You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ariatosca.apache.org by em...@apache.org on 2017/06/16 22:27:44 UTC

[01/10] incubator-ariatosca git commit: ARIA-213 sporadic tests failures over locked database issue [Forced Update!]

Repository: incubator-ariatosca
Updated Branches:
  refs/heads/ARIA-254-multiple-nodes-per-template f5f5852ad -> 76aa0843f (forced update)


ARIA-213 sporadic tests failures over locked database issue

Increased the timeout for acquiring database lock (for sqlite based db).


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/cd830731
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/cd830731
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/cd830731

Branch: refs/heads/ARIA-254-multiple-nodes-per-template
Commit: cd830731bff21e836b5e661623b269aa40f92f52
Parents: 180e0a1
Author: max-orlov <ma...@gigaspaces.com>
Authored: Tue Jun 6 17:05:21 2017 +0300
Committer: max-orlov <ma...@gigaspaces.com>
Committed: Wed Jun 7 17:21:01 2017 +0300

----------------------------------------------------------------------
 aria/storage/sql_mapi.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/cd830731/aria/storage/sql_mapi.py
----------------------------------------------------------------------
diff --git a/aria/storage/sql_mapi.py b/aria/storage/sql_mapi.py
index 4d7e233..bb6223a 100644
--- a/aria/storage/sql_mapi.py
+++ b/aria/storage/sql_mapi.py
@@ -405,7 +405,8 @@ def init_storage(base_dir, filename='db.sqlite'):
 
         path=os.path.join(base_dir, filename))
 
-    engine = create_engine(uri)
+    engine = create_engine(uri, connect_args=dict(timeout=15))
+
     session_factory = orm.sessionmaker(bind=engine)
     session = orm.scoped_session(session_factory=session_factory)
 


[02/10] incubator-ariatosca git commit: ARIA-199 Add "services outputs" CLI command

Posted by em...@apache.org.
ARIA-199 Add "services outputs" CLI command

* Also add an output to hello world example


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/5afa2f7f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/5afa2f7f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/5afa2f7f

Branch: refs/heads/ARIA-254-multiple-nodes-per-template
Commit: 5afa2f7fe11977593009b6da25733fa8dd61a1e9
Parents: cd83073
Author: Tal Liron <ta...@gmail.com>
Authored: Fri Jun 2 14:20:28 2017 -0500
Committer: Tal Liron <ta...@gmail.com>
Committed: Wed Jun 7 14:42:35 2017 -0500

----------------------------------------------------------------------
 aria/cli/commands/services.py                   | 23 ++++++++---------
 aria/modeling/models.py                         |  4 +--
 examples/hello-world/helloworld.yaml            | 16 ++++++++----
 tests/cli/test_services.py                      | 26 ++++++++++++++++++--
 tests/end2end/test_hello_world.py               |  1 +
 tests/mock/models.py                            | 21 ++++++++++------
 .../node-cellar/node-cellar.yaml                | 12 +++++++++
 7 files changed, 76 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/5afa2f7f/aria/cli/commands/services.py
----------------------------------------------------------------------
diff --git a/aria/cli/commands/services.py b/aria/cli/commands/services.py
index 476387c..ae5895a 100644
--- a/aria/cli/commands/services.py
+++ b/aria/cli/commands/services.py
@@ -192,17 +192,16 @@ def outputs(service_name, model_storage, logger):
     """
     logger.info('Showing outputs for service {0}...'.format(service_name))
     service = model_storage.service.get_by_name(service_name)
-    #TODO fix this section..
-    outputs_def = service.outputs
-    response = model_storage.service.outputs.get(service_name)
-    outputs_ = StringIO()
-    for output_name, output in response.outputs.iteritems():
-        outputs_.write(' - "{0}":{1}'.format(output_name, os.linesep))
-        description = outputs_def[output_name].get('description', '')
-        outputs_.write('     Description: {0}{1}'.format(description,
-                                                         os.linesep))
-        outputs_.write('     Value: {0}{1}'.format(output, os.linesep))
-    logger.info(outputs_.getvalue())
+
+    if service.outputs:
+        outputs_string = StringIO()
+        for output_name, output in service.outputs.iteritems():
+            outputs_string.write(' - "{0}":{1}'.format(output_name, os.linesep))
+            outputs_string.write('     Description: {0}{1}'.format(output.description, os.linesep))
+            outputs_string.write('     Value: {0}{1}'.format(output.value, os.linesep))
+        logger.info(outputs_string.getvalue())
+    else:
+        logger.info('\tNo outputs')
 
 
 @services.command(name='inputs',
@@ -218,10 +217,12 @@ def inputs(service_name, model_storage, logger):
     """
     logger.info('Showing inputs for service {0}...'.format(service_name))
     service = model_storage.service.get_by_name(service_name)
+
     if service.inputs:
         inputs_string = StringIO()
         for input_name, input_ in service.inputs.iteritems():
             inputs_string.write(' - "{0}":{1}'.format(input_name, os.linesep))
+            inputs_string.write('     Description: {0}{1}'.format(input_.description, os.linesep))
             inputs_string.write('     Value: {0}{1}'.format(input_.value, os.linesep))
         logger.info(inputs_string.getvalue())
     else:

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/5afa2f7f/aria/modeling/models.py
----------------------------------------------------------------------
diff --git a/aria/modeling/models.py b/aria/modeling/models.py
index 4102090..f30b86f 100644
--- a/aria/modeling/models.py
+++ b/aria/modeling/models.py
@@ -268,7 +268,7 @@ class Argument(aria_declarative_base, orchestration.ArgumentBase):
 
 
 # See also __all__ at the top of this file
-models_to_register = [
+models_to_register = (
     # Service template models
     ServiceTemplate,
     NodeTemplate,
@@ -317,4 +317,4 @@ models_to_register = [
     Task,
     Log,
     Argument
-]
+)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/5afa2f7f/examples/hello-world/helloworld.yaml
----------------------------------------------------------------------
diff --git a/examples/hello-world/helloworld.yaml b/examples/hello-world/helloworld.yaml
index be78401..d3369b7 100644
--- a/examples/hello-world/helloworld.yaml
+++ b/examples/hello-world/helloworld.yaml
@@ -1,13 +1,14 @@
 tosca_definitions_version: tosca_simple_yaml_1_0
 
 node_types:
-  web_server:
+
+  WebServer:
     derived_from: tosca.nodes.Root
     capabilities:
       host:
         type: tosca.capabilities.Container
 
-  web_app:
+  WebApp:
     derived_from: tosca.nodes.WebApplication
     properties:
       port:
@@ -17,10 +18,10 @@ topology_template:
 
   node_templates:
     web_server:
-      type: web_server
+      type: WebServer
 
     web_app:
-      type: web_app
+      type: WebApp
       properties:
         port: 9090
       requirements:
@@ -29,4 +30,9 @@ topology_template:
         Standard:
           configure: scripts/configure.sh
           start: scripts/start.sh
-          stop: scripts/stop.sh
\ No newline at end of file
+          stop: scripts/stop.sh
+
+  outputs:
+    port:
+      type: integer
+      value: { get_property: [ web_app, port ] }

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/5afa2f7f/tests/cli/test_services.py
----------------------------------------------------------------------
diff --git a/tests/cli/test_services.py b/tests/cli/test_services.py
index e5717cc..7dc84bc 100644
--- a/tests/cli/test_services.py
+++ b/tests/cli/test_services.py
@@ -174,7 +174,30 @@ class TestServicesDelete(TestCliBase):
 
 
 class TestServicesOutputs(TestCliBase):
-    pass
+
+    def test_header_string(self, monkeypatch, mock_storage):
+        monkeypatch.setattr(_Environment, 'model_storage', mock_storage)
+        self.invoke('services outputs test_s')
+        assert 'Showing outputs for service test_s...' in self.logger_output_string
+
+    def test_outputs_no_outputs(self, monkeypatch, mock_storage):
+        monkeypatch.setattr(_Environment, 'model_storage', mock_storage)
+        self.invoke('services outputs service_with_no_outputs')
+
+        assert 'No outputs' in self.logger_output_string
+        assert 'output1' not in self.logger_output_string
+        assert 'value1' not in self.logger_output_string
+
+    def test_outputs_one_output(self, monkeypatch, mock_storage):
+        monkeypatch.setattr(_Environment, 'model_storage', mock_storage)
+        s = mock_models.create_service_with_dependencies(include_output=True)
+        monkeypatch.setattr(mock_storage.service, 'get_by_name', mock.MagicMock(return_value=s))
+
+        self.invoke('services outputs test_s')
+
+        assert 'output1' in self.logger_output_string
+        assert 'value1' in self.logger_output_string
+        assert 'No outputs' not in self.logger_output_string
 
 
 class TestServicesInputs(TestCliBase):
@@ -193,7 +216,6 @@ class TestServicesInputs(TestCliBase):
         assert 'value1' not in self.logger_output_string
 
     def test_inputs_one_input(self, monkeypatch, mock_storage):
-
         monkeypatch.setattr(_Environment, 'model_storage', mock_storage)
         s = mock_models.create_service_with_dependencies(include_input=True)
         monkeypatch.setattr(mock_storage.service, 'get_by_name', mock.MagicMock(return_value=s))

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/5afa2f7f/tests/end2end/test_hello_world.py
----------------------------------------------------------------------
diff --git a/tests/end2end/test_hello_world.py b/tests/end2end/test_hello_world.py
index 71792dd..b55b9a8 100644
--- a/tests/end2end/test_hello_world.py
+++ b/tests/end2end/test_hello_world.py
@@ -56,5 +56,6 @@ def _verify_deployed_service_in_storage(service_name, model_storage):
     assert service.name == service_name
     assert len(service.executions) == 1
     assert len(service.nodes) == 2
+    assert service.outputs['port'].value == 9090
     assert all(node.state == node.STARTED for node in service.nodes.values())
     assert len(service.executions[0].logs) > 0

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/5afa2f7f/tests/mock/models.py
----------------------------------------------------------------------
diff --git a/tests/mock/models.py b/tests/mock/models.py
index 56a6e3e..7f6bbea 100644
--- a/tests/mock/models.py
+++ b/tests/mock/models.py
@@ -86,6 +86,7 @@ def create_service(service_template, name=SERVICE_NAME, inputs=None):
 
 def create_service_with_dependencies(include_execution=False,
                                      include_input=False,
+                                     include_output=False,
                                      include_node=False):
     service_template = create_service_template()
     service = create_service(service_template=service_template)
@@ -96,6 +97,9 @@ def create_service_with_dependencies(include_execution=False,
     if include_input:
         input = create_input(name='input1', value='value1')
         service.inputs = {'input1': input}
+    if include_output:
+        output = create_output(name='output1', value='value1')
+        service.outputs = {'output1': output}
     if include_node:
         node_template = create_node_template(service_template=service_template)
         node = create_node(node_template, service, state=models.Node.STARTED)
@@ -290,6 +294,10 @@ def create_input(name, value):
     return _create_parameter(name, value, model_cls=models.Input)
 
 
+def create_output(name, value):
+    return _create_parameter(name, value, model_cls=models.Output)
+
+
 def _dictify(item):
     return dict(((item.name, item),))
 
@@ -300,8 +308,8 @@ def get_standard_interface_template(service_template):
     op_templates = dict(
         (op_name, models.OperationTemplate(
             name=op_name, implementation='{0}.{1}'.format(__file__, mock_operation.__name__)))
-        for op_name in [NORMATIVE_CREATE, NORMATIVE_CONFIGURE, NORMATIVE_START,
-                        NORMATIVE_STOP, NORMATIVE_DELETE]
+        for op_name in (NORMATIVE_CREATE, NORMATIVE_CONFIGURE, NORMATIVE_START,
+                        NORMATIVE_STOP, NORMATIVE_DELETE)
     )
     return models.InterfaceTemplate(name=NORMATIVE_STANDARD_INTERFACE,
                                     operation_templates=op_templates,
@@ -314,8 +322,8 @@ def get_standard_interface(service):
     ops = dict(
         (op_name, models.Operation(
             name=op_name, implementation='{0}.{1}'.format(__file__, mock_operation.__name__)))
-        for op_name in [NORMATIVE_CREATE, NORMATIVE_CONFIGURE, NORMATIVE_START,
-                        NORMATIVE_STOP, NORMATIVE_DELETE]
+        for op_name in (NORMATIVE_CREATE, NORMATIVE_CONFIGURE, NORMATIVE_START,
+                        NORMATIVE_STOP, NORMATIVE_DELETE)
     )
     return {
         NORMATIVE_STANDARD_INTERFACE:
@@ -329,7 +337,7 @@ def get_configure_interfaces(service):
     operations = dict(
         (op_name, models.Operation(
             name=op_name, implementation='{0}.{1}'.format(__file__, mock_operation.__name__)))
-        for op_name in [NORMATIVE_PRE_CONFIGURE_SOURCE,
+        for op_name in (NORMATIVE_PRE_CONFIGURE_SOURCE,
                         NORMATIVE_POST_CONFIGURE_SOURCE,
                         NORMATIVE_ADD_SOURCE,
                         NORMATIVE_REMOVE_SOURCE,
@@ -337,8 +345,7 @@ def get_configure_interfaces(service):
                         NORMATIVE_PRE_CONFIGURE_TARGET,
                         NORMATIVE_POST_CONFIGURE_TARGET,
                         NORMATIVE_ADD_TARGET,
-                        NORMATIVE_REMOVE_TARGET
-                       ]
+                        NORMATIVE_REMOVE_TARGET)
     )
     interface = {
         NORMATIVE_CONFIGURE_INTERFACE: models.Interface(

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/5afa2f7f/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
----------------------------------------------------------------------
diff --git a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
index 4d53f9b..a34301c 100644
--- a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
+++ b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
@@ -144,6 +144,10 @@ topology_template:
       type: nodejs.Server
       requirements:
         - host: application_host
+      capabilities:
+        data_endpoint:
+          properties:
+            url_path: /app
       node_filter: # cannot be validated
         properties:
           #- flavor_name: { valid_values: [ {concat:[m1,.,small]} ] } # won't work because not validated :/
@@ -302,6 +306,14 @@ topology_template:
     capabilities:
       app_endpoint: [ loadbalancer, client ]
 
+  outputs:
+
+    endpoint:
+      description: >-
+        The application endpoint.
+      type: string
+      value: { get_property: [ nodejs, data_endpoint, url_path ] }
+
 policy_types:
 
   MaintenanceWorkflow:


[06/10] incubator-ariatosca git commit: ARIA-54 Prepare for ARIA packaging

Posted by em...@apache.org.
ARIA-54 Prepare for ARIA packaging

Preparations for ARIA packaging:
 - Added CHANGELOG file
 - Added CONTRIBUTING file
 - Added DISCLAIMER file
 - Updated Makefile
 - Converted README from md to rst for PyPI compatiability
 - Removed outdated TODO file
 - Added long_description, download_url to setup.py metadata
 - Modified setup.py url metadata to point at ASF domain
 - Added more badges to README


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/e6cf67ec
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/e6cf67ec
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/e6cf67ec

Branch: refs/heads/ARIA-254-multiple-nodes-per-template
Commit: e6cf67ec1230bf46febc11d65122ee3c0eeebc10
Parents: 2149a5e
Author: Ran Ziv <ra...@gigaspaces.com>
Authored: Mon Jun 5 13:24:49 2017 +0300
Committer: Ran Ziv <ra...@gigaspaces.com>
Committed: Thu Jun 15 12:03:59 2017 +0300

----------------------------------------------------------------------
 CHANGELOG.rst         |   4 ++
 CONTRIBUTING          |   3 +
 DISCLAIMER            |  10 ++++
 MANIFEST.in           |  10 +++-
 Makefile              |  56 ++++++++++++------
 README.md             | 120 --------------------------------------
 README.rst            | 140 +++++++++++++++++++++++++++++++++++++++++++++
 TODO.md               |   8 ---
 docs/conf.py          |   3 +-
 docs/requirements.txt |   4 +-
 setup.py              |   8 ++-
 11 files changed, 214 insertions(+), 152 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e6cf67ec/CHANGELOG.rst
----------------------------------------------------------------------
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
new file mode 100644
index 0000000..6abb1af
--- /dev/null
+++ b/CHANGELOG.rst
@@ -0,0 +1,4 @@
+0.1.0
+-----
+
+ * Initial release.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e6cf67ec/CONTRIBUTING
----------------------------------------------------------------------
diff --git a/CONTRIBUTING b/CONTRIBUTING
new file mode 100644
index 0000000..4124003
--- /dev/null
+++ b/CONTRIBUTING
@@ -0,0 +1,3 @@
+Contribution guide is available on our Confluence:
+
+https://cwiki.apache.org/confluence/display/ARIATOSCA/Contributing+to+ARIA
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e6cf67ec/DISCLAIMER
----------------------------------------------------------------------
diff --git a/DISCLAIMER b/DISCLAIMER
new file mode 100644
index 0000000..358d8e1
--- /dev/null
+++ b/DISCLAIMER
@@ -0,0 +1,10 @@
+Apache AriaTosca is an effort undergoing incubation at the Apache Software
+Foundation (ASF), sponsored by the Apache Incubator.
+
+Incubation is required of all newly accepted projects until a further review
+indicates that the infrastructure, communications, and decision making process
+have stabilized in a manner consistent with other successful ASF projects.
+
+While incubation status is not necessarily a reflection of the completeness
+or stability of the code, it does indicate that the project has yet to be
+fully endorsed by the ASF.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e6cf67ec/MANIFEST.in
----------------------------------------------------------------------
diff --git a/MANIFEST.in b/MANIFEST.in
index 6c79a3a..877a7dd 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,4 +1,10 @@
-include requirements.txt
-include VERSION
+include CONTRIBUTING
 include LICENSE
+include NOTICE
+include VERSION
+include CHANGELOG.rst
+include README.rst
+include requirements.txt
+recursive-include docs/html *
 recursive-include examples *
+prune docs/html/.doctrees

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e6cf67ec/Makefile
----------------------------------------------------------------------
diff --git a/Makefile b/Makefile
index 3bafd3b..a857ca7 100644
--- a/Makefile
+++ b/Makefile
@@ -13,34 +13,54 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-EXTENSIONS=extensions
-DOCS=docs
-HTML=docs/html
+EXTENSIONS = ./extensions
+DIST = ./dist
+DOCS = ./docs
+HTML = ./docs/html
+EASY_INSTALL_PTH = $(VIRTUAL_ENV)/lib/python2.7/site-packages/easy-install.pth
+PYTHON_VERSION = $$(python -V 2>&1 | cut -f2 -d' ' | cut -f1,2 -d'.' --output-delimiter='')
 
-.PHONY: clean aria-requirements docs-requirements docs
-.DEFAULT_GOAL = test
+.DEFAULT_GOAL = install
+.PHONY: clean install install-virtual docs test dist deploy
 
 clean:
-	rm -rf "$(HTML)" .tox .coverage*
+	rm -rf "$(DIST)" "$(HTML)" .tox .coverage*
 	-find . -type f -name '.coverage' -delete
 	-find . -type d -name '.coverage' -exec rm -rf {} \; 2>/dev/null
 	-find . -type d -name '*.egg-info' -exec rm -rf {} \; 2>/dev/null
 
 install:
-	pip install --upgrade .
+	pip install .
 
-requirements:
-	pip install --upgrade --requirement requirements.txt
+install-virtual:
+	pip install --editable .
+	
+	# "pip install --editable" will not add our extensions to the path, so we will patch the virtualenv
+	EXTENSIONS_PATH="$$(head -n 1 "$(EASY_INSTALL_PTH)")/extensions" && \
+	if ! grep -Fxq "$$EXTENSIONS_PATH" "$(EASY_INSTALL_PTH)"; then \
+		echo "$$EXTENSIONS_PATH" >> "$(EASY_INSTALL_PTH)"; \
+	fi
 
-docs-requirements:
-	pip install --upgrade --requirement "$(DOCS)/requirements.txt"
-
-test-requirements:
-	pip install tox==2.5.0
-
-docs: docs-requirements requirements
+docs:
+	pip install --requirement "$(DOCS)/requirements.txt"
 	rm -rf "$(HTML)"
 	sphinx-build -b html "$(DOCS)" "$(HTML)"
 
-test: test-requirements requirements
-	PYTHONPATH="$(EXTENSIONS):$(PYTHONPATH)" tox
+test:
+	pip install --upgrade "tox>=2.7.0"
+	tox -e pylint_code
+	tox -e pylint_tests
+	tox -e py$(PYTHON_VERSION)
+	tox -e py$(PYTHON_VERSION)e2e
+
+dist: docs
+	python ./setup.py sdist bdist_wheel
+
+deploy:
+	pip install --upgrade "twine>=1.9.1"
+	gpg --detach-sign -a "$(DIST)"/*
+	twine upload "$(DIST)"/*
+
+./requirements.txt: ./requirements.in
+	pip install --upgrade "pip-tools>=1.9.0"
+	pip-compile --output-file ./requirements.txt ./requirements.in

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e6cf67ec/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
deleted file mode 100644
index 6aee414..0000000
--- a/README.md
+++ /dev/null
@@ -1,120 +0,0 @@
-ARIA
-====
-
-[![Build Status](https://img.shields.io/travis/apache/incubator-ariatosca/master.svg)](https://travis-ci.org/apache/incubator-ariatosca)
-[![Appveyor Build Status](https://img.shields.io/appveyor/ci/ApacheSoftwareFoundation/incubator-ariatosca/master.svg)](https://ci.appveyor.com/project/ApacheSoftwareFoundation/incubator-ariatosca/history)
-[![License](https://img.shields.io/github/license/apache/incubator-ariatosca.svg)](http://www.apache.org/licenses/LICENSE-2.0)
-[![PyPI release](https://img.shields.io/pypi/v/ariatosca.svg)](https://pypi.python.org/pypi/ariatosca)
-![Python Versions](https://img.shields.io/pypi/pyversions/ariatosca.svg)
-![Wheel](https://img.shields.io/pypi/wheel/ariatosca.svg)
-![Contributors](https://img.shields.io/github/contributors/apache/incubator-ariatosca.svg)
-[![Open Pull Requests](https://img.shields.io/github/issues-pr/apache/incubator-ariatosca.svg)](https://github.com/apache/incubator-ariatosca/pulls)
-[![Closed Pull Requests](https://img.shields.io/github/issues-pr-closed-raw/apache/incubator-ariatosca.svg)](https://github.com/apache/incubator-ariatosca/pulls?q=is%3Apr+is%3Aclosed)
-
-
-What is ARIA?
-----------------
-
-[ARIA](http://ariatosca.incubator.apache.org/) is a an open-source, [TOSCA](https://www.oasis-open.org/committees/tosca/)-based, lightweight library and CLI for orchestration and for consumption by projects building TOSCA-based solutions for resources and services orchestration.
-
-ARIA can be utilized by any organization that wants to implement TOSCA-based orchestration in its solutions, whether a multi-cloud enterprise application, or an NFV or SDN solution for multiple virtual infrastructure managers.
-
-With ARIA, you can utilize TOSCA's cloud portability out-of-the-box, to develop, test and run your applications, from template to deployment.
-
-ARIA is an incubation project under the [Apache Software Foundation](https://www.apache.org/).
-
-
-Installation
-----------------
-
-ARIA is [available on PyPI](https://pypi.python.org/pypi/ariatosca).    
-
-To install ARIA directly from PyPI (using a `wheel`), use:
-
-    pip install aria
-
-
-To install ARIA from source, download the source tarball from [PyPI](https://pypi.python.org/pypi/ariatosca),
-extract it, and then when inside the extracted directory, use:
-
-    pip install .
-
-The source package comes along with relevant examples, documentation,
-`requirements.txt` (for installing specifically the frozen dependencies' versions with which ARIA was tested) and more.
-
-<br>
-Note that for the `pip install` commands mentioned above, you must use a privileged user, or use virtualenv.
-<br><br><br>
-
-ARIA itself is in a `wheel` format compatible with all platforms. 
-Some dependencies, however, might require compilation (based on a given platform), and therefore possibly some system dependencies are required as well.
-
-On Ubuntu or other Debian-based systems:
-
-	sudo apt install python-setuptools python-dev build-essential libssl-dev libffi-dev
-
-On Archlinux:
-
-	sudo pacman -S python-setuptools
-
-
-ARIA requires Python 2.6/2.7. Python 3+ is currently not supported.
-
-
-Getting Started
----------------
-
-This section will describe how to run a simple "Hello World" example.
-
-First, provide ARIA with the ARIA "hello world" service-template and name it (e.g. `my-service-template`):
-
-	aria service-templates store examples/hello-world/helloworld.yaml my-service-template
-	
-Now create a service based on this service-template and name it (e.g. `my-service`):
-	
-	aria services create my-service -t my-service-template
-	
-Finally, start an `install` workflow execution on `my-service` like so:
-
-	aria executions start install -s my-service
-
-<br>
-You should now have a simple web-server running on your local machine.
-You can try visiting http://localhost:9090 to view your deployed application.
-
-To uninstall and clean your environment, follow these steps:
-
-    aria executions start uninstall -s my-service
-    aria services delete my-service
-    aria service-templates delete my-service-template
-
-
-Contribution
-------------
-
-You are welcome and encouraged to participate and contribute to the ARIA project.
-
-Please see our guide to [Contributing to ARIA](https://cwiki.apache.org/confluence/display/ARIATOSCA/Contributing+to+ARIA).
-
-Feel free to also provide feedback on the mailing lists (see [Resources](#user-content-resources) section).
-
-
-Resources
----------
-
-* [ARIA homepage](http://ariatosca.incubator.apache.org/)
-* [ARIA wiki](https://cwiki.apache.org/confluence/display/AriaTosca)
-* [Issue tracker](https://issues.apache.org/jira/browse/ARIA)
-
-* Dev mailing list: dev@ariatosca.incubator.apache.org
-* User mailing list: user@ariatosca.incubator.apache.org
-
-Subscribe by sending a mail to `<group>-subscribe@ariatosca.incubator.apache.org` (e.g. `dev-subscribe@ariatosca.incubator.apache.org`).
-See information on how to subscribe to mailing list [here](https://www.apache.org/foundation/mailinglists.html).
-
-For past correspondence, see the [dev mailing list archive](http://mail-archives.apache.org/mod_mbox/incubator-ariatosca-dev/).
-
-
-License
--------
-ARIA is licensed under the [Apache License 2.0](https://github.com/apache/incubator-ariatosca/blob/master/LICENSE).

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e6cf67ec/README.rst
----------------------------------------------------------------------
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..8af13a5
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,140 @@
+ARIA
+====
+
+|Build Status| |Appveyor Build Status| |License| |PyPI release| |Python Versions| |Wheel|
+|Contributors| |Open Pull Requests| |Closed Pull Requests|
+
+
+What is ARIA?
+-------------
+
+`ARIA <http://ariatosca.incubator.apache.org/>`__ is a an open-source,
+`TOSCA <https://www.oasis-open.org/committees/tosca/>`__-based, lightweight library and CLI for
+orchestration and for consumption by projects building TOSCA-based solutions for resources and
+services orchestration.
+
+ARIA can be utilized by any organization that wants to implement TOSCA-based orchestration in its
+solutions, whether a multi-cloud enterprise application, or an NFV or SDN solution for multiple
+virtual infrastructure managers.
+
+With ARIA, you can utilize TOSCA's cloud portability out-of-the-box, to develop, test and run your
+applications, from template to deployment.
+
+ARIA is an incubation project under the `Apache Software Foundation <https://www.apache.org/>`__.
+
+
+Installation
+------------
+
+ARIA is `available on PyPI <https://pypi.python.org/pypi/ariatosca>`__.
+
+To install ARIA directly from PyPI (using a ``wheel``), use::
+
+    pip install aria
+
+To install ARIA from source, download the source tarball from
+`PyPI <https://pypi.python.org/pypi/ariatosca>`__, extract it, and then when inside the extracted
+directory, use::
+
+    pip install .
+
+The source package comes along with relevant examples, documentation, ``requirements.txt`` (for
+installing specifically the frozen dependencies' versions with which ARIA was tested) and more.
+
+Note that for the ``pip install`` commands mentioned above, you must use a privileged user, or use
+virtualenv.
+
+ARIA itself is in a ``wheel`` format compatible with all platforms. Some dependencies, however,
+might require compilation (based on a given platform), and therefore possibly some system
+dependencies are required as well.
+
+On Ubuntu or other Debian-based systems::
+
+    sudo apt install python-setuptools python-dev build-essential libssl-dev libffi-dev
+
+On Archlinux::
+
+    sudo pacman -S python-setuptools
+
+ARIA requires Python 2.6/2.7. Python 3+ is currently not supported.
+
+
+Getting Started
+---------------
+
+This section will describe how to run a simple "Hello World" example.
+
+First, provide ARIA with the ARIA "hello world" service-template and name it (e.g.
+``my-service-template``)::
+
+    aria service-templates store examples/hello-world/helloworld.yaml my-service-template
+
+Now create a service based on this service-template and name it (e.g. ``my-service``)::
+
+    aria services create my-service -t my-service-template
+
+Finally, start an ``install`` workflow execution on ``my-service`` like so::
+
+    aria executions start install -s my-service
+
+You should now have a simple web-server running on your local machine. You can try visiting
+``http://localhost:9090`` to view your deployed application.
+
+To uninstall and clean your environment, follow these steps::
+
+    aria executions start uninstall -s my-service
+    aria services delete my-service
+    aria service-templates delete my-service-template
+
+
+Contribution
+------------
+
+You are welcome and encouraged to participate and contribute to the ARIA project.
+
+Please see our guide to
+`Contributing to ARIA <https://cwiki.apache.org/confluence/display/ARIATOSCA/Contributing+to+ARIA>`__.
+
+Feel free to also provide feedback on the mailing lists (see `Resources <#user-content-resources>`__
+section).
+
+
+Resources
+---------
+
+-  `ARIA homepage <http://ariatosca.incubator.apache.org/>`__
+-  `ARIA wiki <https://cwiki.apache.org/confluence/display/AriaTosca>`__
+-  `Issue tracker <https://issues.apache.org/jira/browse/ARIA>`__
+
+-  Dev mailing list: dev@ariatosca.incubator.apache.org
+-  User mailing list: user@ariatosca.incubator.apache.org
+
+Subscribe by sending a mail to ``<group>-subscribe@ariatosca.incubator.apache.org`` (e.g.
+``dev-subscribe@ariatosca.incubator.apache.org``). See information on how to subscribe to mailing
+lists `here <https://www.apache.org/foundation/mailinglists.html>`__.
+
+For past correspondence, see the
+`dev mailing list archive <http://mail-archives.apache.org/mod_mbox/incubator-ariatosca-dev/>`__.
+
+
+License
+-------
+
+ARIA is licensed under the
+`Apache License 2.0 <https://github.com/apache/incubator-ariatosca/blob/master/LICENSE>`__.
+
+.. |Build Status| image:: https://img.shields.io/travis/apache/incubator-ariatosca/master.svg
+   :target: https://travis-ci.org/apache/incubator-ariatosca
+.. |Appveyor Build Status| image:: https://img.shields.io/appveyor/ci/ApacheSoftwareFoundation/incubator-ariatosca/master.svg
+   :target: https://ci.appveyor.com/project/ApacheSoftwareFoundation/incubator-ariatosca/history
+.. |License| image:: https://img.shields.io/github/license/apache/incubator-ariatosca.svg
+   :target: http://www.apache.org/licenses/LICENSE-2.0
+.. |PyPI release| image:: https://img.shields.io/pypi/v/ariatosca.svg
+   :target: https://pypi.python.org/pypi/ariatosca
+.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/ariatosca.svg
+.. |Wheel| image:: https://img.shields.io/pypi/wheel/ariatosca.svg
+.. |Contributors| image:: https://img.shields.io/github/contributors/apache/incubator-ariatosca.svg
+.. |Open Pull Requests| image:: https://img.shields.io/github/issues-pr/apache/incubator-ariatosca.svg
+   :target: https://github.com/apache/incubator-ariatosca/pulls
+.. |Closed Pull Requests| image:: https://img.shields.io/github/issues-pr-closed-raw/apache/incubator-ariatosca.svg
+   :target: https://github.com/apache/incubator-ariatosca/pulls?q=is%3Apr+is%3Aclosed

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e6cf67ec/TODO.md
----------------------------------------------------------------------
diff --git a/TODO.md b/TODO.md
deleted file mode 100644
index ab32cf7..0000000
--- a/TODO.md
+++ /dev/null
@@ -1,8 +0,0 @@
-- aria/parser/extension_tools.py:66:    #  todo: maybe add replace action and check in add that we don't replace...
-- aria/parser/framework/elements/policies.py:128:    #  TODO: policies should be implemented according to TOSCA as generic types
-- aria/parser/framework/elements/node_templates.py:42:    #  TODO: Capabilities should be implemented according to TOSCA as generic types
-- aria/parser/framework/functions.py:25:    #  TODO: ugly huck for now..., sort the imports when you have time
-- aria/parser/framework/parser.py:258:    #  TODO: need to clean up
-- tests/parser/test_parser_api.py:430:    #  TODO: assert node-type's default and description values once
-- tests/parser/test_parser_api.py:450:    #  TODO: assert type's default and description values once 'type' is
-- tests/parser/test_parser_api.py:472:    #  TODO: assert type's default and description values once 'type' is

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e6cf67ec/docs/conf.py
----------------------------------------------------------------------
diff --git a/docs/conf.py b/docs/conf.py
index cd25279..e557f02 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -36,7 +36,8 @@ import sys
 sys.path.append(os.path.abspath('../aria'))
 sys.path.append(os.path.abspath('../extensions'))
 
-execfile(os.path.join('../aria', 'VERSION.py'))
+with open('../VERSION') as f:
+    version = f.readline()
 
 # -- General configuration ------------------------------------------------
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e6cf67ec/docs/requirements.txt
----------------------------------------------------------------------
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 72b28f1..976c5b6 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -10,5 +10,5 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-Sphinx==1.5.3
-sphinx_rtd_theme==0.2.4
+Sphinx>=1.6.2, <2.0.0
+sphinx_rtd_theme>=0.2.4, <1.0.0

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/e6cf67ec/setup.py
----------------------------------------------------------------------
diff --git a/setup.py b/setup.py
index d43ce91..8d5f463 100644
--- a/setup.py
+++ b/setup.py
@@ -39,6 +39,9 @@ root_dir = os.path.dirname(__file__)
 with open(os.path.join(root_dir, 'VERSION')) as version_file:
     __version__ = version_file.read().strip()
 
+with open(os.path.join(root_dir, 'README.rst')) as readme:
+    long_description = readme.read()
+
 install_requires = []
 extras_require = {}
 
@@ -106,10 +109,13 @@ setup(
     name=_PACKAGE_NAME,
     version=__version__,
     description='ARIA',
+    long_description=long_description,
     license='Apache License 2.0',
     author='aria',
     author_email='dev@ariatosca.incubator.apache.org',
-    url='http://ariatosca.org',
+    url='http://ariatosca.incubator.apache.org/',
+    download_url=(
+        'https://dist.apache.org/repos/dist/release/incubator/ariatosca/' + __version__),
     classifiers=[
         'Development Status :: 4 - Beta',
         'Environment :: Console',


[08/10] incubator-ariatosca git commit: Finally works

Posted by em...@apache.org.
Finally works


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/76aa0843
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/76aa0843
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/76aa0843

Branch: refs/heads/ARIA-254-multiple-nodes-per-template
Commit: 76aa0843fc872ed759aa3c7282b45c75e576d82b
Parents: 334ea74
Author: Tal Liron <ta...@gmail.com>
Authored: Fri Jun 16 17:27:05 2017 -0500
Committer: Tal Liron <ta...@gmail.com>
Committed: Fri Jun 16 17:27:32 2017 -0500

----------------------------------------------------------------------
 aria/modeling/service_template.py               | 21 +++++----
 aria/parser/presentation/fields.py              |  4 --
 .../profiles/aria-1.0/aria-1.0.yaml             |  2 +
 .../simple_v1_0/modeling/artifacts.py           |  4 +-
 .../simple_v1_0/modeling/capabilities.py        | 47 +++++++++++++-------
 .../simple_v1_0/modeling/interfaces.py          |  8 ++--
 .../simple_v1_0/modeling/parameters.py          |  5 ++-
 tests/end2end/test_nodecellar.py                |  2 +-
 .../node-cellar/node-cellar.yaml                | 38 +++++++++-------
 .../node-cellar/types/nodejs.yaml               |  1 +
 10 files changed, 81 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/76aa0843/aria/modeling/service_template.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py
index c9c7c6c..633b5bc 100644
--- a/aria/modeling/service_template.py
+++ b/aria/modeling/service_template.py
@@ -305,7 +305,6 @@ class ServiceTemplateBase(TemplateModelMixin):
         utils.instantiate_dict(self, service.meta_data, self.meta_data)
 
         for node_template in self.node_templates.itervalues():
-            print 'scaling', node_template.name, node_template.scaling['default_instances'] 
             for _ in range(node_template.scaling['default_instances']):
                 node = node_template.instantiate(container)
                 service.nodes[node.name] = node
@@ -616,12 +615,11 @@ class NodeTemplateBase(TemplateModelMixin):
 
     @property
     def scaling(self):
-        scaling = {
-           'min_instances': 0,
-           'max_instances': 1,
-           'default_instances': 1}
+        scaling = {}
 
         def extract_property(properties, name):
+            if name in scaling:
+                return
             prop = properties.get(name)
             if (prop is not None) and (prop.type_name == 'integer') and (prop.value is not None):
                 scaling[name] = prop.value
@@ -631,21 +629,28 @@ class NodeTemplateBase(TemplateModelMixin):
             extract_property(properties, 'max_instances')
             extract_property(properties, 'default_instances')
 
-        # TODO: currently finds the first matches capability or policy; but we should emit a
-        # validation error if more than one applies to the same node
+        def default_property(name, value):
+            if name not in scaling:
+                scaling[name] = value
 
         # From our scaling capabilities
         for capability_template in self.capability_templates.itervalues():
             if capability_template.type.role == 'scaling':
                 extract_properties(capability_template.properties)
 
-        # From service scaling policies (will override capabilities)
+        # From service scaling policies
         for policy_template in self.service_template.policy_templates.itervalues():
             if policy_template.type.role == 'scaling':
                 if policy_template.is_for_node_template(self.name):
                     extract_properties(policy_template.properties)
 
+        # Defaults
+        default_property('min_instances', 0)
+        default_property('max_instances', 1)
+        default_property('default_instances', 1)
+
         # Validate
+        # pylint: disable=too-many-boolean-expressions
         if (scaling['min_instances'] < 0) or \
             (scaling['max_instances'] < 0) or \
             (scaling['default_instances'] < 0) or \

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/76aa0843/aria/parser/presentation/fields.py
----------------------------------------------------------------------
diff --git a/aria/parser/presentation/fields.py b/aria/parser/presentation/fields.py
index 060c576..7f85723 100644
--- a/aria/parser/presentation/fields.py
+++ b/aria/parser/presentation/fields.py
@@ -680,10 +680,6 @@ class Field(object):
     # object dict
 
     def _get_object_dict(self, presentation, raw, value, context):
-        if self.cls.__name__ == 'CapabilityAssignment':
-            print '>>>>>>>>>>p', presentation._name
-            print '>>>>>>>>>>v', value
-            print '>>>>>>>>>>r', raw
         if not isinstance(value, dict):
             raise InvalidValueError('%s is not a dict: %s' % (self.full_name, safe_repr(value)),
                                     locator=self.get_locator(raw))

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/76aa0843/extensions/aria_extension_tosca/profiles/aria-1.0/aria-1.0.yaml
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/profiles/aria-1.0/aria-1.0.yaml b/extensions/aria_extension_tosca/profiles/aria-1.0/aria-1.0.yaml
index d7b0c61..e421150 100644
--- a/extensions/aria_extension_tosca/profiles/aria-1.0/aria-1.0.yaml
+++ b/extensions/aria_extension_tosca/profiles/aria-1.0/aria-1.0.yaml
@@ -93,3 +93,5 @@ policy_types:
         constraints:
           - greater_or_equal: 0
         required: false
+    targets:
+      - tosca.nodes.Root

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/76aa0843/extensions/aria_extension_tosca/simple_v1_0/modeling/artifacts.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/artifacts.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/artifacts.py
index dd9eeb4..b45615a 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/artifacts.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/artifacts.py
@@ -21,6 +21,8 @@ from aria.utils.collections import OrderedDict
 #
 
 def get_inherited_artifact_definitions(context, presentation, for_presentation=None):
+    if for_presentation is None:
+        for_presentation = presentation
 
     if hasattr(presentation, '_get_type'):
         # In NodeTemplate
@@ -30,7 +32,7 @@ def get_inherited_artifact_definitions(context, presentation, for_presentation=N
         parent = presentation._get_parent(context)
 
     # Get artifact definitions from parent
-    artifacts = get_inherited_artifact_definitions(context, parent, for_presentation=presentation) \
+    artifacts = get_inherited_artifact_definitions(context, parent, for_presentation) \
         if parent is not None else OrderedDict()
 
     # Add/override our artifact definitions

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/76aa0843/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
index e61fc81..bf75f7d 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
@@ -52,12 +52,13 @@ def get_inherited_capability_definitions(context, presentation, for_presentation
     Allows overriding all aspects of parent capability properties except data type.
     """
 
+    if for_presentation is None:
+        for_presentation = presentation
+
     # Get capability definitions from parent
     parent = presentation._get_parent(context)
-    capability_definitions = get_inherited_capability_definitions(context, parent,
-                                                                  for_presentation=presentation) \
-                                                                  if parent is not None \
-                                                                  else OrderedDict()
+    capability_definitions = get_inherited_capability_definitions(
+        context, parent, for_presentation) if parent is not None else OrderedDict()
 
     # Add/merge our capability definitions
     our_capability_definitions = presentation.capabilities
@@ -75,9 +76,8 @@ def get_inherited_capability_definitions(context, presentation, for_presentation
                         .format(type1, type2, presentation._fullname),
                         locator=our_capability_definition._locator, level=Issue.BETWEEN_TYPES)
 
-                # Already cloned?
-                #capability_definition = capability_definition._clone(for_presentation)
-                #capability_definitions[capability_name] = capability_definition
+                merge_capability_definition(context, presentation, capability_definition,
+                                            our_capability_definition)
             else:
                 capability_definition = our_capability_definition._clone(for_presentation)
                 if isinstance(capability_definition._raw, basestring):
@@ -129,20 +129,11 @@ def get_template_capabilities(context, presentation):
             if capability_name in capability_assignments:
                 capability_assignment = capability_assignments[capability_name]
 
-                print
-                print presentation._name
-                print 'raw1', our_capability_assignment._raw
-                print 'raw2', presentation._raw['capabilities'][our_capability_assignment._name]
-
                 # Assign properties
                 values = get_assigned_and_defined_parameter_values(context,
                                                                    our_capability_assignment,
                                                                    'property')
 
-                print 'our', [(k, v.value) for k, v in our_capability_assignment.properties.iteritems()]
-                print 'def', [(k, v.value.value) for k, v in capability_assignment.properties.iteritems()]
-                print 'val', [(k, v.value) for k, v in values.iteritems()]
-                
                 if values:
                     capability_assignment._raw['properties'] = values
                     capability_assignment._reset_method_cache()
@@ -173,6 +164,30 @@ def convert_capability_from_definition_to_assignment(context, presentation, cont
     return CapabilityAssignment(name=presentation._name, raw=raw, container=container)
 
 
+def merge_capability_definition(context, presentation, capability_definition,
+                                from_capability_definition):
+    raw_properties = OrderedDict()
+
+    # Merge properties from type
+    from_property_defintions = from_capability_definition.properties
+    merge_raw_parameter_definitions(context, presentation, raw_properties, from_property_defintions,
+                                    'properties')
+
+    # Merge our properties
+    merge_raw_parameter_definitions(context, presentation, raw_properties,
+                                    capability_definition.properties, 'properties')
+
+    if raw_properties:
+        capability_definition._raw['properties'] = raw_properties
+        capability_definition._reset_method_cache()
+
+    # Merge occurrences
+    occurrences = from_capability_definition._raw.get('occurrences')
+    if (occurrences is not None) and (capability_definition._raw.get('occurrences') is None):
+        capability_definition._raw['occurrences'] = \
+            deepcopy_with_locators(occurrences)
+
+
 def merge_capability_definition_from_type(context, presentation, capability_definition):
     raw_properties = OrderedDict()
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/76aa0843/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
index e04ac4a..d5f447c 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/interfaces.py
@@ -113,9 +113,12 @@ def get_inherited_interface_definitions(context, presentation, type_name, for_pr
     types.
     """
 
+    if for_presentation is None:
+        for_presentation = presentation
+
     # Get interfaces from parent
     parent = presentation._get_parent(context)
-    interfaces = get_inherited_interface_definitions(context, parent, type_name, presentation) \
+    interfaces = get_inherited_interface_definitions(context, parent, type_name, for_presentation) \
         if parent is not None else OrderedDict()
 
     # Add/merge interfaces from their types
@@ -123,8 +126,7 @@ def get_inherited_interface_definitions(context, presentation, type_name, for_pr
 
     # Add/merge our interfaces
     our_interfaces = presentation.interfaces
-    merge_interface_definitions(context, interfaces, our_interfaces, presentation,
-                                for_presentation=for_presentation)
+    merge_interface_definitions(context, interfaces, our_interfaces, presentation, for_presentation)
 
     return interfaces
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/76aa0843/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py
index c910956..87c1a3b 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/parameters.py
@@ -33,11 +33,14 @@ def get_inherited_parameter_definitions(context, presentation, field_name, for_p
     Allows overriding all aspects of parent properties except data type.
     """
 
+    if for_presentation is None:
+        for_presentation = presentation
+
     # Get definitions from parent
     # If we inherit from a primitive, it does not have a parent:
     parent = presentation._get_parent(context) if hasattr(presentation, '_get_parent') else None
     definitions = get_inherited_parameter_definitions(context, parent, field_name,
-                                                      for_presentation=presentation) \
+                                                      for_presentation) \
                                                       if parent is not None else OrderedDict()
 
     # Add/merge our definitions

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/76aa0843/tests/end2end/test_nodecellar.py
----------------------------------------------------------------------
diff --git a/tests/end2end/test_nodecellar.py b/tests/end2end/test_nodecellar.py
index a2b6797..e8cfa84 100644
--- a/tests/end2end/test_nodecellar.py
+++ b/tests/end2end/test_nodecellar.py
@@ -39,4 +39,4 @@ def _verify_deployed_service_in_storage(service_name, model_storage):
     service = service_templates[0].services[service_name]
     assert service.name == service_name
     assert len(service.executions) == 0  # dry executions leave no traces
-    assert len(service.nodes) == 13
+    assert len(service.nodes) == 15

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/76aa0843/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
----------------------------------------------------------------------
diff --git a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
index de57d3c..2d39967 100644
--- a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
+++ b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
@@ -155,7 +155,7 @@ topology_template:
         capabilities:
           - scalable:
               properties:
-                - max_instances: { greater_or_equal: 8 }
+                - max_instances: { greater_or_equal: 5 }
 
     mongodb:
       description: >-
@@ -171,7 +171,7 @@ topology_template:
               capabilities:
                 - scalable:
                     properties:
-                      - max_instances: { greater_or_equal: 8 }
+                      - max_instances: { greater_or_equal: 5 }
             relationship:
               interfaces:
                 Configure:
@@ -201,11 +201,6 @@ topology_template:
         os_users: # map of os.UserInfo
           root:
             password: admin123
-      capabilities:
-        scalable: # will be overriden by policy
-          properties:
-            max_instances: 5
-            default_instances: 3
       interfaces:
         Standard:
           inputs:
@@ -230,7 +225,7 @@ topology_template:
       capabilities:
         scalable:
           properties:
-            max_instances: 10
+            max_instances: 5 # overrides the policy
 
     data_host:
       copy: loadbalancer_host
@@ -251,7 +246,7 @@ topology_template:
       capabilities:
         scalable:
           properties:
-            max_instances: 10
+            max_instances: 6 # overrides the policy
 
     data_volume:
       type: openstack.Volume
@@ -278,14 +273,23 @@ topology_template:
 
   policies:
   
-#    scaling:
-#      type: openstack.Scaling
-#      properties:
-#        bandwidth_threshold: 2 GB
-#        max_instances: 2
-#        default_instances: 2
-#      targets: # node templates or groups
-#        - node_cellar_group
+    app_scaling:
+      type: aria.Scaling
+      properties:
+        max_instances: 10
+        default_instances: 2
+      targets:
+        - node_cellar
+        - nodejs
+  
+    host_scaling:
+      type: openstack.Scaling
+      properties:
+        bandwidth_threshold: 2 GB
+        max_instances: 10
+        default_instances: 2
+      targets: # node templates or groups
+        - node_cellar_group
     
     juju:
       description: >-

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/76aa0843/tests/resources/service-templates/tosca-simple-1.0/node-cellar/types/nodejs.yaml
----------------------------------------------------------------------
diff --git a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/types/nodejs.yaml b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/types/nodejs.yaml
index 4fd4e72..19cc7b9 100644
--- a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/types/nodejs.yaml
+++ b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/types/nodejs.yaml
@@ -51,6 +51,7 @@ node_types:
       host: # @override
         type: tosca.capabilities.Container
         valid_source_types: [ nodejs.Application ]
+        occurrences: [ 0, 1 ]
 
   nodejs.Application:
     derived_from: tosca.nodes.WebApplication


[05/10] incubator-ariatosca git commit: ARIA-276 Support model instrumentation for workflows

Posted by em...@apache.org.
ARIA-276 Support model instrumentation for workflows


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/2149a5ee
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/2149a5ee
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/2149a5ee

Branch: refs/heads/ARIA-254-multiple-nodes-per-template
Commit: 2149a5ee0c4656a253f54db20f279197961588c1
Parents: 1e883c5
Author: max-orlov <ma...@gigaspaces.com>
Authored: Thu Jun 8 09:52:31 2017 +0300
Committer: max-orlov <ma...@gigaspaces.com>
Committed: Tue Jun 13 14:34:41 2017 +0300

----------------------------------------------------------------------
 aria/orchestrator/context/common.py             |   7 +
 aria/orchestrator/context/operation.py          |   7 -
 aria/orchestrator/decorators.py                 |   5 +-
 aria/orchestrator/workflows/api/task.py         |   2 -
 aria/orchestrator/workflows/core/task.py        |  12 +-
 aria/storage/collection_instrumentation.py      |  46 +--
 .../context/test_collection_instrumentation.py  | 325 -------------------
 .../context/test_context_instrumentation.py     | 108 ++++++
 tests/orchestrator/context/test_serialize.py    |  20 +-
 tests/orchestrator/context/test_workflow.py     |  93 ++++--
 .../orchestrator/execution_plugin/test_local.py |  26 +-
 tests/orchestrator/execution_plugin/test_ssh.py |  50 +--
 .../workflows/builtin/test_execute_operation.py |   9 +-
 .../orchestrator/workflows/core/test_engine.py  |  88 +++--
 .../executor/test_process_executor_extension.py |  24 +-
 .../test_process_executor_tracked_changes.py    |  26 +-
 .../storage/test_collection_instrumentation.py  | 257 +++++++++++++++
 17 files changed, 627 insertions(+), 478 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2149a5ee/aria/orchestrator/context/common.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/context/common.py b/aria/orchestrator/context/common.py
index c98e026..f4df317 100644
--- a/aria/orchestrator/context/common.py
+++ b/aria/orchestrator/context/common.py
@@ -36,6 +36,13 @@ class BaseContext(object):
     Base context object for workflow and operation
     """
 
+    INSTRUMENTATION_FIELDS = (
+        modeling.models.Node.attributes,
+        modeling.models.Node.properties,
+        modeling.models.NodeTemplate.attributes,
+        modeling.models.NodeTemplate.properties
+    )
+
     class PrefixedLogger(object):
         def __init__(self, base_logger, task_id=None):
             self._logger = base_logger

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2149a5ee/aria/orchestrator/context/operation.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/context/operation.py b/aria/orchestrator/context/operation.py
index af7220d..efdc04d 100644
--- a/aria/orchestrator/context/operation.py
+++ b/aria/orchestrator/context/operation.py
@@ -29,13 +29,6 @@ class BaseOperationContext(common.BaseContext):
     Context object used during operation creation and execution
     """
 
-    INSTRUMENTATION_FIELDS = (
-        aria.modeling.models.Node.attributes,
-        aria.modeling.models.Node.properties,
-        aria.modeling.models.NodeTemplate.attributes,
-        aria.modeling.models.NodeTemplate.properties
-    )
-
     def __init__(self, task_id, actor_id, **kwargs):
         self._task_id = task_id
         self._actor_id = actor_id

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2149a5ee/aria/orchestrator/decorators.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/decorators.py b/aria/orchestrator/decorators.py
index 80f6962..389bfb8 100644
--- a/aria/orchestrator/decorators.py
+++ b/aria/orchestrator/decorators.py
@@ -49,8 +49,9 @@ def workflow(func=None, suffix_template=''):
         workflow_parameters.setdefault('ctx', ctx)
         workflow_parameters.setdefault('graph', task_graph.TaskGraph(workflow_name))
         validate_function_arguments(func, workflow_parameters)
-        with context.workflow.current.push(ctx):
-            func(**workflow_parameters)
+        with ctx.model.instrument(*ctx.INSTRUMENTATION_FIELDS):
+            with context.workflow.current.push(ctx):
+                func(**workflow_parameters)
         return workflow_parameters['graph']
     return _wrapper
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2149a5ee/aria/orchestrator/workflows/api/task.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/api/task.py b/aria/orchestrator/workflows/api/task.py
index bcba56e..ca125a8 100644
--- a/aria/orchestrator/workflows/api/task.py
+++ b/aria/orchestrator/workflows/api/task.py
@@ -108,8 +108,6 @@ class OperationTask(BaseTask):
                 ``interface_name`` and ``operation_name`` to not refer to an operation on the actor
         """
 
-        assert isinstance(actor, (models.Node, models.Relationship))
-
         # Creating OperationTask directly should raise an error when there is no
         # interface/operation.
         if not has_operation(actor, interface_name, operation_name):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2149a5ee/aria/orchestrator/workflows/core/task.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/core/task.py b/aria/orchestrator/workflows/core/task.py
index 72d83ea..d732f09 100644
--- a/aria/orchestrator/workflows/core/task.py
+++ b/aria/orchestrator/workflows/core/task.py
@@ -124,20 +124,22 @@ class OperationTask(BaseTask):
         self.operation_name = api_task.operation_name
         model_storage = api_task._workflow_context.model
 
+        actor = getattr(api_task.actor, '_wrapped', api_task.actor)
+
         base_task_model = model_storage.task.model_cls
-        if isinstance(api_task.actor, models.Node):
+        if isinstance(actor, models.Node):
             context_cls = operation_context.NodeOperationContext
             create_task_model = base_task_model.for_node
-        elif isinstance(api_task.actor, models.Relationship):
+        elif isinstance(actor, models.Relationship):
             context_cls = operation_context.RelationshipOperationContext
             create_task_model = base_task_model.for_relationship
         else:
             raise RuntimeError('No operation context could be created for {actor.model_cls}'
-                               .format(actor=api_task.actor))
+                               .format(actor=actor))
 
         task_model = create_task_model(
             name=api_task.name,
-            actor=api_task.actor,
+            actor=actor,
             status=base_task_model.PENDING,
             max_attempts=api_task.max_attempts,
             retry_interval=api_task.retry_interval,
@@ -156,7 +158,7 @@ class OperationTask(BaseTask):
                                 resource_storage=self._workflow_context.resource,
                                 service_id=self._workflow_context._service_id,
                                 task_id=task_model.id,
-                                actor_id=api_task.actor.id,
+                                actor_id=actor.id,
                                 execution_id=self._workflow_context._execution_id,
                                 workdir=self._workflow_context._workdir)
         self._task_id = task_model.id

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2149a5ee/aria/storage/collection_instrumentation.py
----------------------------------------------------------------------
diff --git a/aria/storage/collection_instrumentation.py b/aria/storage/collection_instrumentation.py
index 27d8322..454f97a 100644
--- a/aria/storage/collection_instrumentation.py
+++ b/aria/storage/collection_instrumentation.py
@@ -198,23 +198,28 @@ class _InstrumentedList(_InstrumentedCollection, list):
         return list(self)
 
 
-class _InstrumentedModel(object):
+class _WrappedBase(object):
 
-    def __init__(self, original_model, mapi, instrumentation):
+    def __init__(self, wrapped, instrumentation):
+        self._wrapped = wrapped
+        self._instrumentation = instrumentation
+
+
+class _InstrumentedModel(_WrappedBase):
+
+    def __init__(self, mapi, *args, **kwargs):
         """
         The original model
-        :param original_model: the model to be instrumented
+        :param wrapped: the model to be instrumented
         :param mapi: the mapi for that model
         """
-        super(_InstrumentedModel, self).__init__()
-        self._original_model = original_model
+        super(_InstrumentedModel, self).__init__(*args, **kwargs)
         self._mapi = mapi
-        self._instrumentation = instrumentation
         self._apply_instrumentation()
 
     def __getattr__(self, item):
-        return_value = getattr(self._original_model, item)
-        if isinstance(return_value, self._original_model.__class__):
+        return_value = getattr(self._wrapped, item)
+        if isinstance(return_value, self._wrapped.__class__):
             return _create_instrumented_model(return_value, self._mapi, self._instrumentation)
         if isinstance(return_value, (list, dict)):
             return _create_wrapped_model(return_value, self._mapi, self._instrumentation)
@@ -224,7 +229,7 @@ class _InstrumentedModel(object):
         for field in self._instrumentation:
             field_name = field.key
             field_cls = field.mapper.class_
-            field = getattr(self._original_model, field_name)
+            field = getattr(self._wrapped, field_name)
 
             # Preserve the original value. e.g. original attributes would be located under
             # _attributes
@@ -241,20 +246,20 @@ class _InstrumentedModel(object):
                     "ARIA supports instrumentation for dict and list. Field {field} of the "
                     "class {model} is of {type} type.".format(
                         field=field,
-                        model=self._original_model,
+                        model=self._wrapped,
                         type=type(field)))
 
             instrumented_class = instrumentation_cls(seq=field,
-                                                     parent=self._original_model,
+                                                     parent=self._wrapped,
                                                      mapi=self._mapi,
                                                      field_name=field_name,
                                                      field_cls=field_cls)
             setattr(self, field_name, instrumented_class)
 
 
-class _WrappedModel(object):
+class _WrappedModel(_WrappedBase):
 
-    def __init__(self, wrapped, instrumentation, **kwargs):
+    def __init__(self, instrumentation_kwargs, *args, **kwargs):
         """
 
         :param instrumented_cls: The class to be instrumented
@@ -262,9 +267,8 @@ class _WrappedModel(object):
         :param wrapped: the currently wrapped instance
         :param kwargs: and kwargs to the passed to the instrumented class.
         """
-        self._kwargs = kwargs
-        self._instrumentation = instrumentation
-        self._wrapped = wrapped
+        super(_WrappedModel, self).__init__(*args, **kwargs)
+        self._kwargs = instrumentation_kwargs
 
     def _wrap(self, value):
         if value.__class__ in (class_.class_ for class_ in self._instrumentation):
@@ -286,16 +290,18 @@ class _WrappedModel(object):
         return self._wrap(self._wrapped[item])
 
 
-def _create_instrumented_model(original_model, mapi, instrumentation, **kwargs):
+def _create_instrumented_model(original_model, mapi, instrumentation):
     return type('Instrumented{0}'.format(original_model.__class__.__name__),
                 (_InstrumentedModel,),
-                {})(original_model, mapi, instrumentation, **kwargs)
+                {})(wrapped=original_model, instrumentation=instrumentation, mapi=mapi)
 
 
-def _create_wrapped_model(original_model, mapi, instrumentation, **kwargs):
+def _create_wrapped_model(original_model, mapi, instrumentation):
     return type('Wrapped{0}'.format(original_model.__class__.__name__),
                 (_WrappedModel, ),
-                {})(original_model, instrumentation, mapi=mapi, **kwargs)
+                {})(wrapped=original_model,
+                    instrumentation=instrumentation,
+                    instrumentation_kwargs=dict(mapi=mapi))
 
 
 def instrument(instrumentation, original_model, mapi):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2149a5ee/tests/orchestrator/context/test_collection_instrumentation.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/context/test_collection_instrumentation.py b/tests/orchestrator/context/test_collection_instrumentation.py
deleted file mode 100644
index ae3e8ac..0000000
--- a/tests/orchestrator/context/test_collection_instrumentation.py
+++ /dev/null
@@ -1,325 +0,0 @@
-# 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.
-
-import pytest
-
-from aria.modeling import models
-from aria.storage import collection_instrumentation
-from aria.orchestrator.context import operation
-
-from tests import (
-    mock,
-    storage
-)
-
-
-class MockActor(object):
-    def __init__(self):
-        self.dict_ = {}
-        self.list_ = []
-
-
-class MockMAPI(object):
-
-    def __init__(self):
-        pass
-
-    def put(self, *args, **kwargs):
-        pass
-
-    def update(self, *args, **kwargs):
-        pass
-
-
-class CollectionInstrumentation(object):
-
-    @pytest.fixture
-    def actor(self):
-        return MockActor()
-
-    @pytest.fixture
-    def model(self):
-        return MockMAPI()
-
-    @pytest.fixture
-    def dict_(self, actor, model):
-        return collection_instrumentation._InstrumentedDict(model, actor, 'dict_', models.Attribute)
-
-    @pytest.fixture
-    def list_(self, actor, model):
-        return collection_instrumentation._InstrumentedList(model, actor, 'list_', models.Attribute)
-
-
-class TestDict(CollectionInstrumentation):
-
-    def test_keys(self, actor, dict_):
-        dict_.update(
-            {
-                'key1': models.Attribute.wrap('key1', 'value1'),
-                'key2': models.Attribute.wrap('key2', 'value2')
-            }
-        )
-        assert sorted(dict_.keys()) == sorted(['key1', 'key2']) == sorted(actor.dict_.keys())
-
-    def test_values(self, actor, dict_):
-        dict_.update({
-            'key1': models.Attribute.wrap('key1', 'value1'),
-            'key2': models.Attribute.wrap('key1', 'value2')
-        })
-        assert (sorted(dict_.values()) ==
-                sorted(['value1', 'value2']) ==
-                sorted(v.value for v in actor.dict_.values()))
-
-    def test_items(self, dict_):
-        dict_.update({
-            'key1': models.Attribute.wrap('key1', 'value1'),
-            'key2': models.Attribute.wrap('key1', 'value2')
-        })
-        assert sorted(dict_.items()) == sorted([('key1', 'value1'), ('key2', 'value2')])
-
-    def test_iter(self, actor, dict_):
-        dict_.update({
-            'key1': models.Attribute.wrap('key1', 'value1'),
-            'key2': models.Attribute.wrap('key1', 'value2')
-        })
-        assert sorted(list(dict_)) == sorted(['key1', 'key2']) == sorted(actor.dict_.keys())
-
-    def test_bool(self, dict_):
-        assert not dict_
-        dict_.update({
-            'key1': models.Attribute.wrap('key1', 'value1'),
-            'key2': models.Attribute.wrap('key1', 'value2')
-        })
-        assert dict_
-
-    def test_set_item(self, actor, dict_):
-        dict_['key1'] = models.Attribute.wrap('key1', 'value1')
-        assert dict_['key1'] == 'value1' == actor.dict_['key1'].value
-        assert isinstance(actor.dict_['key1'], models.Attribute)
-
-    def test_nested(self, actor, dict_):
-        dict_['key'] = {}
-        assert isinstance(actor.dict_['key'], models.Attribute)
-        assert dict_['key'] == actor.dict_['key'].value == {}
-
-        dict_['key']['inner_key'] = 'value'
-
-        assert len(dict_) == 1
-        assert 'inner_key' in dict_['key']
-        assert dict_['key']['inner_key'] == 'value'
-        assert dict_['key'].keys() == ['inner_key']
-        assert dict_['key'].values() == ['value']
-        assert dict_['key'].items() == [('inner_key', 'value')]
-        assert isinstance(actor.dict_['key'], models.Attribute)
-        assert isinstance(dict_['key'], collection_instrumentation._InstrumentedDict)
-
-        dict_['key'].update({'updated_key': 'updated_value'})
-        assert len(dict_) == 1
-        assert 'updated_key' in dict_['key']
-        assert dict_['key']['updated_key'] == 'updated_value'
-        assert sorted(dict_['key'].keys()) == sorted(['inner_key', 'updated_key'])
-        assert sorted(dict_['key'].values()) == sorted(['value', 'updated_value'])
-        assert sorted(dict_['key'].items()) == sorted([('inner_key', 'value'),
-                                                       ('updated_key', 'updated_value')])
-        assert isinstance(actor.dict_['key'], models.Attribute)
-        assert isinstance(dict_['key'], collection_instrumentation._InstrumentedDict)
-
-        dict_.update({'key': 'override_value'})
-        assert len(dict_) == 1
-        assert 'key' in dict_
-        assert dict_['key'] == 'override_value'
-        assert len(actor.dict_) == 1
-        assert isinstance(actor.dict_['key'], models.Attribute)
-        assert actor.dict_['key'].value == 'override_value'
-
-    def test_get_item(self, actor, dict_):
-        dict_['key1'] = models.Attribute.wrap('key1', 'value1')
-        assert isinstance(actor.dict_['key1'], models.Attribute)
-
-    def test_update(self, actor, dict_):
-        dict_['key1'] = 'value1'
-
-        new_dict = {'key2': 'value2'}
-        dict_.update(new_dict)
-        assert len(dict_) == 2
-        assert dict_['key2'] == 'value2'
-        assert isinstance(actor.dict_['key2'], models.Attribute)
-
-        new_dict = {}
-        new_dict.update(dict_)
-        assert new_dict['key1'] == dict_['key1']
-
-    def test_copy(self, dict_):
-        dict_['key1'] = 'value1'
-
-        new_dict = dict_.copy()
-        assert new_dict is not dict_
-        assert new_dict == dict_
-
-        dict_['key1'] = 'value2'
-        assert new_dict['key1'] == 'value1'
-        assert dict_['key1'] == 'value2'
-
-    def test_clear(self, dict_):
-        dict_['key1'] = 'value1'
-        dict_.clear()
-
-        assert len(dict_) == 0
-
-
-class TestList(CollectionInstrumentation):
-
-    def test_append(self, actor, list_):
-        list_.append(models.Attribute.wrap('name', 'value1'))
-        list_.append('value2')
-        assert len(actor.list_) == 2
-        assert len(list_) == 2
-        assert isinstance(actor.list_[0], models.Attribute)
-        assert list_[0] == 'value1'
-
-        assert isinstance(actor.list_[1], models.Attribute)
-        assert list_[1] == 'value2'
-
-        list_[0] = 'new_value1'
-        list_[1] = 'new_value2'
-        assert isinstance(actor.list_[1], models.Attribute)
-        assert isinstance(actor.list_[1], models.Attribute)
-        assert list_[0] == 'new_value1'
-        assert list_[1] == 'new_value2'
-
-    def test_iter(self, list_):
-        list_.append('value1')
-        list_.append('value2')
-        assert sorted(list_) == sorted(['value1', 'value2'])
-
-    def test_insert(self, actor, list_):
-        list_.append('value1')
-        list_.insert(0, 'value2')
-        list_.insert(2, 'value3')
-        list_.insert(10, 'value4')
-        assert sorted(list_) == sorted(['value1', 'value2', 'value3', 'value4'])
-        assert len(actor.list_) == 4
-
-    def test_set(self, list_):
-        list_.append('value1')
-        list_.append('value2')
-
-        list_[1] = 'value3'
-        assert len(list_) == 2
-        assert sorted(list_) == sorted(['value1', 'value3'])
-
-    def test_insert_into_nested(self, actor, list_):
-        list_.append([])
-
-        list_[0].append('inner_item')
-        assert isinstance(actor.list_[0], models.Attribute)
-        assert len(list_) == 1
-        assert list_[0][0] == 'inner_item'
-
-        list_[0].append('new_item')
-        assert isinstance(actor.list_[0], models.Attribute)
-        assert len(list_) == 1
-        assert list_[0][1] == 'new_item'
-
-        assert list_[0] == ['inner_item', 'new_item']
-        assert ['inner_item', 'new_item'] == list_[0]
-
-
-class TestDictList(CollectionInstrumentation):
-    def test_dict_in_list(self, actor, list_):
-        list_.append({})
-        assert len(list_) == 1
-        assert isinstance(actor.list_[0], models.Attribute)
-        assert actor.list_[0].value == {}
-
-        list_[0]['key'] = 'value'
-        assert list_[0]['key'] == 'value'
-        assert len(actor.list_) == 1
-        assert isinstance(actor.list_[0], models.Attribute)
-        assert actor.list_[0].value['key'] == 'value'
-
-    def test_list_in_dict(self, actor, dict_):
-        dict_['key'] = []
-        assert len(dict_) == 1
-        assert isinstance(actor.dict_['key'], models.Attribute)
-        assert actor.dict_['key'].value == []
-
-        dict_['key'].append('value')
-        assert dict_['key'][0] == 'value'
-        assert len(actor.dict_) == 1
-        assert isinstance(actor.dict_['key'], models.Attribute)
-        assert actor.dict_['key'].value[0] == 'value'
-
-
-class TestModelInstrumentation(object):
-
-    @pytest.fixture
-    def workflow_ctx(self, tmpdir):
-        context = mock.context.simple(str(tmpdir), inmemory=True)
-        yield context
-        storage.release_sqlite_storage(context.model)
-
-    def test_attributes_access(self, workflow_ctx):
-        node = workflow_ctx.model.node.list()[0]
-        task = models.Task(node=node)
-        workflow_ctx.model.task.put(task)
-
-        ctx = operation.NodeOperationContext(
-            task.id, node.id, name='', service_id=workflow_ctx.model.service.list()[0].id,
-            model_storage=workflow_ctx.model, resource_storage=workflow_ctx.resource,
-            execution_id=1)
-
-        def _run_assertions(is_under_ctx):
-            def ctx_assert(expr):
-                if is_under_ctx:
-                    assert expr
-                else:
-                    assert not expr
-
-            ctx_assert(isinstance(ctx.node.attributes,
-                                  collection_instrumentation._InstrumentedDict))
-            assert not isinstance(ctx.node.properties,
-                                  collection_instrumentation._InstrumentedCollection)
-
-            for rel in ctx.node.inbound_relationships:
-                ctx_assert(isinstance(rel, collection_instrumentation._WrappedModel))
-                ctx_assert(isinstance(rel.source_node.attributes,
-                                      collection_instrumentation._InstrumentedDict))
-                ctx_assert(isinstance(rel.target_node.attributes,
-                                      collection_instrumentation._InstrumentedDict))
-
-            for node in ctx.model.node:
-                ctx_assert(isinstance(node.attributes,
-                                      collection_instrumentation._InstrumentedDict))
-                assert not isinstance(node.properties,
-                                      collection_instrumentation._InstrumentedCollection)
-
-            for rel in ctx.model.relationship:
-                ctx_assert(isinstance(rel, collection_instrumentation._WrappedModel))
-
-                ctx_assert(isinstance(rel.source_node.attributes,
-                                      collection_instrumentation._InstrumentedDict))
-                ctx_assert(isinstance(rel.target_node.attributes,
-                                      collection_instrumentation._InstrumentedDict))
-
-                assert not isinstance(rel.source_node.properties,
-                                      collection_instrumentation._InstrumentedCollection)
-                assert not isinstance(rel.target_node.properties,
-                                      collection_instrumentation._InstrumentedCollection)
-
-        with ctx.model.instrument(models.Node.attributes):
-            _run_assertions(True)
-
-        _run_assertions(False)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2149a5ee/tests/orchestrator/context/test_context_instrumentation.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/context/test_context_instrumentation.py b/tests/orchestrator/context/test_context_instrumentation.py
new file mode 100644
index 0000000..6cc8096
--- /dev/null
+++ b/tests/orchestrator/context/test_context_instrumentation.py
@@ -0,0 +1,108 @@
+# 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.
+
+import pytest
+
+from aria.modeling import models
+from aria.storage import collection_instrumentation
+from aria.orchestrator.context import operation
+
+from tests import (
+    mock,
+    storage
+)
+
+
+class TestContextInstrumentation(object):
+
+    @pytest.fixture
+    def workflow_ctx(self, tmpdir):
+        context = mock.context.simple(str(tmpdir), inmemory=True)
+        yield context
+        storage.release_sqlite_storage(context.model)
+
+    def test_workflow_context_instrumentation(self, workflow_ctx):
+        with workflow_ctx.model.instrument(models.Node.attributes):
+            self._run_common_assertions(workflow_ctx, True)
+        self._run_common_assertions(workflow_ctx, False)
+
+    def test_operation_context_instrumentation(self, workflow_ctx):
+        node = workflow_ctx.model.node.list()[0]
+        task = models.Task(node=node)
+        workflow_ctx.model.task.put(task)
+
+        ctx = operation.NodeOperationContext(
+            task.id, node.id, name='', service_id=workflow_ctx.model.service.list()[0].id,
+            model_storage=workflow_ctx.model, resource_storage=workflow_ctx.resource,
+            execution_id=1)
+
+        with ctx.model.instrument(models.Node.attributes):
+            self._run_op_assertions(ctx, True)
+            self._run_common_assertions(ctx, True)
+
+        self._run_op_assertions(ctx, False)
+        self._run_common_assertions(ctx, False)
+
+    @staticmethod
+    def ctx_assert(expr, is_under_ctx):
+        if is_under_ctx:
+            assert expr
+        else:
+            assert not expr
+
+    def _run_op_assertions(self, ctx, is_under_ctx):
+        self.ctx_assert(isinstance(ctx.node.attributes,
+                                   collection_instrumentation._InstrumentedDict), is_under_ctx)
+        assert not isinstance(ctx.node.properties,
+                              collection_instrumentation._InstrumentedCollection)
+
+        for rel in ctx.node.inbound_relationships:
+            self.ctx_assert(
+                isinstance(rel, collection_instrumentation._WrappedModel), is_under_ctx)
+            self.ctx_assert(
+                isinstance(rel.source_node.attributes,
+                           collection_instrumentation._InstrumentedDict),
+                is_under_ctx)
+            self.ctx_assert(
+                isinstance(rel.target_node.attributes,
+                           collection_instrumentation._InstrumentedDict),
+                is_under_ctx)
+
+    def _run_common_assertions(self, ctx, is_under_ctx):
+
+        for node in ctx.model.node:
+            self.ctx_assert(
+                isinstance(node.attributes, collection_instrumentation._InstrumentedDict),
+                is_under_ctx)
+            assert not isinstance(node.properties,
+                                  collection_instrumentation._InstrumentedCollection)
+
+        for rel in ctx.model.relationship:
+            self.ctx_assert(
+                isinstance(rel, collection_instrumentation._WrappedModel), is_under_ctx)
+
+            self.ctx_assert(
+                isinstance(rel.source_node.attributes,
+                           collection_instrumentation._InstrumentedDict),
+                is_under_ctx)
+            self.ctx_assert(
+                isinstance(rel.target_node.attributes,
+                           collection_instrumentation._InstrumentedDict),
+                is_under_ctx)
+
+            assert not isinstance(rel.source_node.properties,
+                                  collection_instrumentation._InstrumentedCollection)
+            assert not isinstance(rel.target_node.properties,
+                                  collection_instrumentation._InstrumentedCollection)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2149a5ee/tests/orchestrator/context/test_serialize.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/context/test_serialize.py b/tests/orchestrator/context/test_serialize.py
index 4db7bf4..0919e81 100644
--- a/tests/orchestrator/context/test_serialize.py
+++ b/tests/orchestrator/context/test_serialize.py
@@ -33,16 +33,10 @@ def test_serialize_operation_context(context, executor, tmpdir):
     test_file.write(TEST_FILE_CONTENT)
     resource = context.resource
     resource.service_template.upload(TEST_FILE_ENTRY_ID, str(test_file))
-    graph = _mock_workflow(ctx=context)  # pylint: disable=no-value-for-parameter
-    eng = engine.Engine(executor=executor, workflow_context=context, tasks_graph=graph)
-    eng.execute()
-
 
-@workflow
-def _mock_workflow(ctx, graph):
-    node = ctx.model.node.get_by_name(mock.models.DEPENDENCY_NODE_NAME)
+    node = context.model.node.get_by_name(mock.models.DEPENDENCY_NODE_NAME)
     plugin = mock.models.create_plugin()
-    ctx.model.plugin.put(plugin)
+    context.model.plugin.put(plugin)
     interface = mock.models.create_interface(
         node.service,
         'test',
@@ -51,6 +45,16 @@ def _mock_workflow(ctx, graph):
                               plugin=plugin)
     )
     node.interfaces[interface.name] = interface
+    context.model.node.update(node)
+
+    graph = _mock_workflow(ctx=context)  # pylint: disable=no-value-for-parameter
+    eng = engine.Engine(executor=executor, workflow_context=context, tasks_graph=graph)
+    eng.execute()
+
+
+@workflow
+def _mock_workflow(ctx, graph):
+    node = ctx.model.node.get_by_name(mock.models.DEPENDENCY_NODE_NAME)
     task = api.task.OperationTask(node, interface_name='test', operation_name='op')
     graph.add_tasks(task)
     return graph

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2149a5ee/tests/orchestrator/context/test_workflow.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/context/test_workflow.py b/tests/orchestrator/context/test_workflow.py
index 3c35435..6d53c2a 100644
--- a/tests/orchestrator/context/test_workflow.py
+++ b/tests/orchestrator/context/test_workflow.py
@@ -17,11 +17,14 @@ from datetime import datetime
 
 import pytest
 
-from aria import application_model_storage
+from aria import application_model_storage, workflow
 from aria.orchestrator import context
 from aria.storage import sql_mapi
-from tests import storage as test_storage
-from tests.mock import models
+from aria.orchestrator.workflows.executor import thread, process
+
+from tests import storage as test_storage, ROOT_DIR
+from ... import mock
+from . import execute
 
 
 class TestWorkflowContext(object):
@@ -30,10 +33,10 @@ class TestWorkflowContext(object):
         ctx = self._create_ctx(storage)
         execution = storage.execution.get(ctx.execution.id)             # pylint: disable=no-member
         assert execution.service == storage.service.get_by_name(
-            models.SERVICE_NAME)
-        assert execution.workflow_name == models.WORKFLOW_NAME
+            mock.models.SERVICE_NAME)
+        assert execution.workflow_name == mock.models.WORKFLOW_NAME
         assert execution.service_template == storage.service_template.get_by_name(
-            models.SERVICE_TEMPLATE_NAME)
+            mock.models.SERVICE_TEMPLATE_NAME)
         assert execution.status == storage.execution.model_cls.PENDING
         assert execution.inputs == {}
         assert execution.created_at <= datetime.utcnow()
@@ -49,27 +52,75 @@ class TestWorkflowContext(object):
         :param storage:
         :return WorkflowContext:
         """
-        service = storage.service.get_by_name(models.SERVICE_NAME)
+        service = storage.service.get_by_name(mock.models.SERVICE_NAME)
         return context.workflow.WorkflowContext(
             name='simple_context',
             model_storage=storage,
             resource_storage=None,
             service_id=service,
             execution_id=storage.execution.list(filters=dict(service=service))[0].id,
-            workflow_name=models.WORKFLOW_NAME,
-            task_max_attempts=models.TASK_MAX_ATTEMPTS,
-            task_retry_interval=models.TASK_RETRY_INTERVAL
+            workflow_name=mock.models.WORKFLOW_NAME,
+            task_max_attempts=mock.models.TASK_MAX_ATTEMPTS,
+            task_retry_interval=mock.models.TASK_RETRY_INTERVAL
         )
 
+    @pytest.fixture
+    def storage(self):
+        workflow_storage = application_model_storage(
+            sql_mapi.SQLAlchemyModelAPI, initiator=test_storage.init_inmemory_model_storage)
+        workflow_storage.service_template.put(mock.models.create_service_template())
+        service_template = workflow_storage.service_template.get_by_name(
+            mock.models.SERVICE_TEMPLATE_NAME)
+        service = mock.models.create_service(service_template)
+        workflow_storage.service.put(service)
+        workflow_storage.execution.put(mock.models.create_execution(service))
+        yield workflow_storage
+        test_storage.release_sqlite_storage(workflow_storage)
+
+
+@pytest.fixture
+def ctx(tmpdir):
+    context = mock.context.simple(
+        str(tmpdir),
+        context_kwargs=dict(workdir=str(tmpdir.join('workdir')))
+    )
+    yield context
+    test_storage.release_sqlite_storage(context.model)
+
+
+@pytest.fixture(params=[
+    (thread.ThreadExecutor, {}),
+    (process.ProcessExecutor, {'python_path': [ROOT_DIR]}),
+])
+def executor(request):
+    executor_cls, executor_kwargs = request.param
+    result = executor_cls(**executor_kwargs)
+    try:
+        yield result
+    finally:
+        result.close()
+
+
+def test_attribute_consumption(ctx, executor):
+
+    node = ctx.model.node.get_by_name(mock.models.DEPENDENT_NODE_NAME)
+    node.attributes['key'] = ctx.model.attribute.model_cls.wrap('key', 'value')
+    node.attributes['key2'] = ctx.model.attribute.model_cls.wrap('key2', 'value_to_change')
+    ctx.model.node.update(node)
+
+    assert node.attributes['key'].value == 'value'
+    assert node.attributes['key2'].value == 'value_to_change'
+
+    @workflow
+    def basic_workflow(ctx, **_):
+        node = ctx.model.node.get_by_name(mock.models.DEPENDENT_NODE_NAME)
+        node.attributes['new_key'] = 'new_value'
+        node.attributes['key2'] = 'changed_value'
+
+    execute(workflow_func=basic_workflow, workflow_context=ctx, executor=executor)
+    node = ctx.model.node.get_by_name(mock.models.DEPENDENT_NODE_NAME)
 
-@pytest.fixture(scope='function')
-def storage():
-    workflow_storage = application_model_storage(
-        sql_mapi.SQLAlchemyModelAPI, initiator=test_storage.init_inmemory_model_storage)
-    workflow_storage.service_template.put(models.create_service_template())
-    service_template = workflow_storage.service_template.get_by_name(models.SERVICE_TEMPLATE_NAME)
-    service = models.create_service(service_template)
-    workflow_storage.service.put(service)
-    workflow_storage.execution.put(models.create_execution(service))
-    yield workflow_storage
-    test_storage.release_sqlite_storage(workflow_storage)
+    assert len(node.attributes) == 3
+    assert node.attributes['key'].value == 'value'
+    assert node.attributes['new_key'].value == 'new_value'
+    assert node.attributes['key2'].value == 'changed_value'

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2149a5ee/tests/orchestrator/execution_plugin/test_local.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/execution_plugin/test_local.py b/tests/orchestrator/execution_plugin/test_local.py
index d792a57..f667460 100644
--- a/tests/orchestrator/execution_plugin/test_local.py
+++ b/tests/orchestrator/execution_plugin/test_local.py
@@ -477,20 +477,22 @@ if __name__ == '__main__':
             'input_as_env_var': env_var
         })
 
+        node = workflow_context.model.node.get_by_name(mock.models.DEPENDENCY_NODE_NAME)
+        interface = mock.models.create_interface(
+            node.service,
+            'test',
+            'op',
+            operation_kwargs=dict(
+                function='{0}.{1}'.format(
+                    operations.__name__,
+                    operations.run_script_locally.__name__),
+                arguments=arguments)
+        )
+        node.interfaces[interface.name] = interface
+        workflow_context.model.node.update(node)
+
         @workflow
         def mock_workflow(ctx, graph):
-            node = ctx.model.node.get_by_name(mock.models.DEPENDENCY_NODE_NAME)
-            interface = mock.models.create_interface(
-                node.service,
-                'test',
-                'op',
-                operation_kwargs=dict(
-                    function='{0}.{1}'.format(
-                        operations.__name__,
-                        operations.run_script_locally.__name__),
-                    arguments=arguments)
-            )
-            node.interfaces[interface.name] = interface
             graph.add_tasks(api.task.OperationTask(
                 node,
                 interface_name='test',

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2149a5ee/tests/orchestrator/execution_plugin/test_ssh.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/execution_plugin/test_ssh.py b/tests/orchestrator/execution_plugin/test_ssh.py
index 8b326e7..8c4dd2d 100644
--- a/tests/orchestrator/execution_plugin/test_ssh.py
+++ b/tests/orchestrator/execution_plugin/test_ssh.py
@@ -214,33 +214,33 @@ class TestWithActualSSHServer(object):
         else:
             operation = operations.run_script_with_ssh
 
+        node = self._workflow_context.model.node.get_by_name(mock.models.DEPENDENCY_NODE_NAME)
+        arguments = {
+            'script_path': script_path,
+            'fabric_env': _FABRIC_ENV,
+            'process': process,
+            'use_sudo': use_sudo,
+            'custom_env_var': custom_input,
+            'test_operation': '',
+        }
+        if hide_output:
+            arguments['hide_output'] = hide_output
+        if commands:
+            arguments['commands'] = commands
+        interface = mock.models.create_interface(
+            node.service,
+            'test',
+            'op',
+            operation_kwargs=dict(
+                function='{0}.{1}'.format(
+                    operations.__name__,
+                    operation.__name__),
+                arguments=arguments)
+        )
+        node.interfaces[interface.name] = interface
+
         @workflow
         def mock_workflow(ctx, graph):
-            node = ctx.model.node.get_by_name(mock.models.DEPENDENCY_NODE_NAME)
-            arguments = {
-                'script_path': script_path,
-                'fabric_env': _FABRIC_ENV,
-                'process': process,
-                'use_sudo': use_sudo,
-                'custom_env_var': custom_input,
-                'test_operation': '',
-            }
-            if hide_output:
-                arguments['hide_output'] = hide_output
-            if commands:
-                arguments['commands'] = commands
-            interface = mock.models.create_interface(
-                node.service,
-                'test',
-                'op',
-                operation_kwargs=dict(
-                    function='{0}.{1}'.format(
-                        operations.__name__,
-                        operation.__name__),
-                    arguments=arguments)
-            )
-            node.interfaces[interface.name] = interface
-
             ops = []
             for test_operation in test_operations:
                 op_arguments = arguments.copy()

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2149a5ee/tests/orchestrator/workflows/builtin/test_execute_operation.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/workflows/builtin/test_execute_operation.py b/tests/orchestrator/workflows/builtin/test_execute_operation.py
index 88818ca..8713e3c 100644
--- a/tests/orchestrator/workflows/builtin/test_execute_operation.py
+++ b/tests/orchestrator/workflows/builtin/test_execute_operation.py
@@ -56,12 +56,9 @@ def test_execute_operation(ctx):
     )
 
     assert len(execute_tasks) == 1
-    assert execute_tasks[0].name == task.OperationTask.NAME_FORMAT.format(
-        type='node',
-        name=node.name,
-        interface=interface_name,
-        operation=operation_name
-    )
+    assert getattr(execute_tasks[0].actor, '_wrapped', execute_tasks[0].actor) == node
+    assert execute_tasks[0].operation_name == operation_name
+    assert execute_tasks[0].interface_name == interface_name
 
 
 # TODO: add more scenarios

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2149a5ee/tests/orchestrator/workflows/core/test_engine.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/workflows/core/test_engine.py b/tests/orchestrator/workflows/core/test_engine.py
index 6d2836c..0438544 100644
--- a/tests/orchestrator/workflows/core/test_engine.py
+++ b/tests/orchestrator/workflows/core/test_engine.py
@@ -55,12 +55,7 @@ class BaseTest(object):
                              tasks_graph=graph)
 
     @staticmethod
-    def _op(ctx,
-            func,
-            arguments=None,
-            max_attempts=None,
-            retry_interval=None,
-            ignore_failure=None):
+    def _create_interface(ctx, func, arguments=None):
         node = ctx.model.node.get_by_name(mock.models.DEPENDENCY_NODE_NAME)
         interface_name = 'aria.interfaces.lifecycle'
         operation_kwargs = dict(function='{name}.{func.__name__}'.format(
@@ -72,6 +67,17 @@ class BaseTest(object):
         interface = mock.models.create_interface(node.service, interface_name, operation_name,
                                                  operation_kwargs=operation_kwargs)
         node.interfaces[interface.name] = interface
+        ctx.model.node.update(node)
+
+        return node, interface_name, operation_name
+
+    @staticmethod
+    def _op(node,
+            operation_name,
+            arguments=None,
+            max_attempts=None,
+            retry_interval=None,
+            ignore_failure=None):
 
         return api.task.OperationTask(
             node,
@@ -158,9 +164,11 @@ class TestEngine(BaseTest):
         assert execution.status == models.Execution.SUCCEEDED
 
     def test_single_task_successful_execution(self, workflow_context, executor):
+        node, _, operation_name = self._create_interface(workflow_context, mock_success_task)
+
         @workflow
         def mock_workflow(ctx, graph):
-            graph.add_tasks(self._op(ctx, func=mock_success_task))
+            graph.add_tasks(self._op(node, operation_name))
         self._execute(
             workflow_func=mock_workflow,
             workflow_context=workflow_context,
@@ -170,9 +178,11 @@ class TestEngine(BaseTest):
         assert global_test_holder.get('sent_task_signal_calls') == 1
 
     def test_single_task_failed_execution(self, workflow_context, executor):
+        node, _, operation_name = self._create_interface(workflow_context, mock_failed_task)
+
         @workflow
         def mock_workflow(ctx, graph):
-            graph.add_tasks(self._op(ctx, func=mock_failed_task))
+            graph.add_tasks(self._op(node, operation_name))
         with pytest.raises(exceptions.ExecutorException):
             self._execute(
                 workflow_func=mock_workflow,
@@ -187,10 +197,13 @@ class TestEngine(BaseTest):
         assert execution.status == models.Execution.FAILED
 
     def test_two_tasks_execution_order(self, workflow_context, executor):
+        node, _, operation_name = self._create_interface(
+            workflow_context, mock_ordered_task, {'counter': 1})
+
         @workflow
         def mock_workflow(ctx, graph):
-            op1 = self._op(ctx, func=mock_ordered_task, arguments={'counter': 1})
-            op2 = self._op(ctx, func=mock_ordered_task, arguments={'counter': 2})
+            op1 = self._op(node, operation_name, arguments={'counter': 1})
+            op2 = self._op(node, operation_name, arguments={'counter': 2})
             graph.sequence(op1, op2)
         self._execute(
             workflow_func=mock_workflow,
@@ -202,11 +215,14 @@ class TestEngine(BaseTest):
         assert global_test_holder.get('sent_task_signal_calls') == 2
 
     def test_stub_and_subworkflow_execution(self, workflow_context, executor):
+        node, _, operation_name = self._create_interface(
+            workflow_context, mock_ordered_task, {'counter': 1})
+
         @workflow
         def sub_workflow(ctx, graph):
-            op1 = self._op(ctx, func=mock_ordered_task, arguments={'counter': 1})
+            op1 = self._op(node, operation_name, arguments={'counter': 1})
             op2 = api.task.StubTask()
-            op3 = self._op(ctx, func=mock_ordered_task, arguments={'counter': 2})
+            op3 = self._op(node, operation_name, arguments={'counter': 2})
             graph.sequence(op1, op2, op3)
 
         @workflow
@@ -225,11 +241,13 @@ class TestCancel(BaseTest):
 
     def test_cancel_started_execution(self, workflow_context, executor):
         number_of_tasks = 100
+        node, _, operation_name = self._create_interface(
+            workflow_context, mock_sleep_task, {'seconds': 0.1})
 
         @workflow
         def mock_workflow(ctx, graph):
             operations = (
-                self._op(ctx, func=mock_sleep_task, arguments=dict(seconds=0.1))
+                self._op(node, operation_name, arguments=dict(seconds=0.1))
                 for _ in range(number_of_tasks)
             )
             return graph.sequence(*operations)
@@ -267,9 +285,12 @@ class TestCancel(BaseTest):
 class TestRetries(BaseTest):
 
     def test_two_max_attempts_and_success_on_retry(self, workflow_context, executor):
+        node, _, operation_name = self._create_interface(
+            workflow_context, mock_conditional_failure_task, {'failure_count': 1})
+
         @workflow
         def mock_workflow(ctx, graph):
-            op = self._op(ctx, func=mock_conditional_failure_task,
+            op = self._op(node, operation_name,
                           arguments={'failure_count': 1},
                           max_attempts=2)
             graph.add_tasks(op)
@@ -283,9 +304,12 @@ class TestRetries(BaseTest):
         assert global_test_holder.get('sent_task_signal_calls') == 2
 
     def test_two_max_attempts_and_failure_on_retry(self, workflow_context, executor):
+        node, _, operation_name = self._create_interface(
+            workflow_context, mock_conditional_failure_task, {'failure_count': 1})
+
         @workflow
         def mock_workflow(ctx, graph):
-            op = self._op(ctx, func=mock_conditional_failure_task,
+            op = self._op(node, operation_name,
                           arguments={'failure_count': 2},
                           max_attempts=2)
             graph.add_tasks(op)
@@ -300,9 +324,11 @@ class TestRetries(BaseTest):
         assert global_test_holder.get('sent_task_signal_calls') == 2
 
     def test_three_max_attempts_and_success_on_first_retry(self, workflow_context, executor):
+        node, _, operation_name = self._create_interface(
+            workflow_context, mock_conditional_failure_task, {'failure_count': 1})
         @workflow
         def mock_workflow(ctx, graph):
-            op = self._op(ctx, func=mock_conditional_failure_task,
+            op = self._op(node, operation_name,
                           arguments={'failure_count': 1},
                           max_attempts=3)
             graph.add_tasks(op)
@@ -316,9 +342,12 @@ class TestRetries(BaseTest):
         assert global_test_holder.get('sent_task_signal_calls') == 2
 
     def test_three_max_attempts_and_success_on_second_retry(self, workflow_context, executor):
+        node, _, operation_name = self._create_interface(
+            workflow_context, mock_conditional_failure_task, {'failure_count': 1})
+
         @workflow
         def mock_workflow(ctx, graph):
-            op = self._op(ctx, func=mock_conditional_failure_task,
+            op = self._op(node, operation_name,
                           arguments={'failure_count': 2},
                           max_attempts=3)
             graph.add_tasks(op)
@@ -332,9 +361,11 @@ class TestRetries(BaseTest):
         assert global_test_holder.get('sent_task_signal_calls') == 3
 
     def test_infinite_retries(self, workflow_context, executor):
+        node, _, operation_name = self._create_interface(
+            workflow_context, mock_conditional_failure_task, {'failure_count': 1})
         @workflow
         def mock_workflow(ctx, graph):
-            op = self._op(ctx, func=mock_conditional_failure_task,
+            op = self._op(node, operation_name,
                           arguments={'failure_count': 1},
                           max_attempts=-1)
             graph.add_tasks(op)
@@ -358,9 +389,11 @@ class TestRetries(BaseTest):
                                   executor=executor)
 
     def _test_retry_interval(self, retry_interval, workflow_context, executor):
+        node, _, operation_name = self._create_interface(
+            workflow_context, mock_conditional_failure_task, {'failure_count': 1})
         @workflow
         def mock_workflow(ctx, graph):
-            op = self._op(ctx, func=mock_conditional_failure_task,
+            op = self._op(node, operation_name,
                           arguments={'failure_count': 1},
                           max_attempts=2,
                           retry_interval=retry_interval)
@@ -378,9 +411,11 @@ class TestRetries(BaseTest):
         assert global_test_holder.get('sent_task_signal_calls') == 2
 
     def test_ignore_failure(self, workflow_context, executor):
+        node, _, operation_name = self._create_interface(
+            workflow_context, mock_conditional_failure_task, {'failure_count': 1})
         @workflow
         def mock_workflow(ctx, graph):
-            op = self._op(ctx, func=mock_conditional_failure_task,
+            op = self._op(node, operation_name,
                           ignore_failure=True,
                           arguments={'failure_count': 100},
                           max_attempts=100)
@@ -401,10 +436,12 @@ class TestTaskRetryAndAbort(BaseTest):
 
     def test_task_retry_default_interval(self, workflow_context, executor):
         default_retry_interval = 0.1
+        node, _, operation_name = self._create_interface(
+            workflow_context, mock_task_retry, {'message': self.message})
 
         @workflow
         def mock_workflow(ctx, graph):
-            op = self._op(ctx, func=mock_task_retry,
+            op = self._op(node, operation_name,
                           arguments={'message': self.message},
                           retry_interval=default_retry_interval,
                           max_attempts=2)
@@ -425,10 +462,13 @@ class TestTaskRetryAndAbort(BaseTest):
     def test_task_retry_custom_interval(self, workflow_context, executor):
         default_retry_interval = 100
         custom_retry_interval = 0.1
+        node, _, operation_name = self._create_interface(
+            workflow_context, mock_task_retry, {'message': self.message,
+                                                'retry_interval': custom_retry_interval})
 
         @workflow
         def mock_workflow(ctx, graph):
-            op = self._op(ctx, func=mock_task_retry,
+            op = self._op(node, operation_name,
                           arguments={'message': self.message,
                                      'retry_interval': custom_retry_interval},
                           retry_interval=default_retry_interval,
@@ -449,9 +489,11 @@ class TestTaskRetryAndAbort(BaseTest):
         assert global_test_holder.get('sent_task_signal_calls') == 2
 
     def test_task_abort(self, workflow_context, executor):
+        node, _, operation_name = self._create_interface(
+            workflow_context, mock_task_abort, {'message': self.message})
         @workflow
         def mock_workflow(ctx, graph):
-            op = self._op(ctx, func=mock_task_abort,
+            op = self._op(node, operation_name,
                           arguments={'message': self.message},
                           retry_interval=100,
                           max_attempts=100)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2149a5ee/tests/orchestrator/workflows/executor/test_process_executor_extension.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/workflows/executor/test_process_executor_extension.py b/tests/orchestrator/workflows/executor/test_process_executor_extension.py
index 7969457..5f0b75f 100644
--- a/tests/orchestrator/workflows/executor/test_process_executor_extension.py
+++ b/tests/orchestrator/workflows/executor/test_process_executor_extension.py
@@ -32,19 +32,23 @@ def test_decorate_extension(context, executor):
     def get_node(ctx):
         return ctx.model.node.get_by_name(mock.models.DEPENDENCY_NODE_NAME)
 
+    node = get_node(context)
+    interface_name = 'test_interface'
+    operation_name = 'operation'
+    interface = mock.models.create_interface(
+        context.service,
+        interface_name,
+        operation_name,
+        operation_kwargs=dict(function='{0}.{1}'.format(__name__, _mock_operation.__name__),
+                              arguments=arguments)
+    )
+    node.interfaces[interface.name] = interface
+    context.model.node.update(node)
+
+
     @workflow
     def mock_workflow(ctx, graph):
         node = get_node(ctx)
-        interface_name = 'test_interface'
-        operation_name = 'operation'
-        interface = mock.models.create_interface(
-            ctx.service,
-            interface_name,
-            operation_name,
-            operation_kwargs=dict(function='{0}.{1}'.format(__name__, _mock_operation.__name__),
-                                  arguments=arguments)
-        )
-        node.interfaces[interface.name] = interface
         task = api.task.OperationTask(
             node,
             interface_name=interface_name,

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2149a5ee/tests/orchestrator/workflows/executor/test_process_executor_tracked_changes.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/workflows/executor/test_process_executor_tracked_changes.py b/tests/orchestrator/workflows/executor/test_process_executor_tracked_changes.py
index 2d80a3b..7dbcc5a 100644
--- a/tests/orchestrator/workflows/executor/test_process_executor_tracked_changes.py
+++ b/tests/orchestrator/workflows/executor/test_process_executor_tracked_changes.py
@@ -83,20 +83,22 @@ def test_apply_tracked_changes_during_an_operation(context, executor):
 
 
 def _run_workflow(context, executor, op_func, arguments=None):
+    node = context.model.node.get_by_name(mock.models.DEPENDENCY_NODE_NAME)
+    interface_name = 'test_interface'
+    operation_name = 'operation'
+    wf_arguments = arguments or {}
+    interface = mock.models.create_interface(
+        context.service,
+        interface_name,
+        operation_name,
+        operation_kwargs=dict(function=_operation_mapping(op_func),
+                              arguments=wf_arguments)
+    )
+    node.interfaces[interface.name] = interface
+    context.model.node.update(node)
+
     @workflow
     def mock_workflow(ctx, graph):
-        node = ctx.model.node.get_by_name(mock.models.DEPENDENCY_NODE_NAME)
-        interface_name = 'test_interface'
-        operation_name = 'operation'
-        wf_arguments = arguments or {}
-        interface = mock.models.create_interface(
-            ctx.service,
-            interface_name,
-            operation_name,
-            operation_kwargs=dict(function=_operation_mapping(op_func),
-                                  arguments=wf_arguments)
-        )
-        node.interfaces[interface.name] = interface
         task = api.task.OperationTask(
             node,
             interface_name=interface_name,

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/2149a5ee/tests/storage/test_collection_instrumentation.py
----------------------------------------------------------------------
diff --git a/tests/storage/test_collection_instrumentation.py b/tests/storage/test_collection_instrumentation.py
new file mode 100644
index 0000000..e915421
--- /dev/null
+++ b/tests/storage/test_collection_instrumentation.py
@@ -0,0 +1,257 @@
+# 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.
+
+import pytest
+
+from aria.modeling import models
+from aria.storage import collection_instrumentation
+
+
+class MockActor(object):
+    def __init__(self):
+        self.dict_ = {}
+        self.list_ = []
+
+
+class MockMAPI(object):
+
+    def __init__(self):
+        pass
+
+    def put(self, *args, **kwargs):
+        pass
+
+    def update(self, *args, **kwargs):
+        pass
+
+
+class CollectionInstrumentation(object):
+
+    @pytest.fixture
+    def actor(self):
+        return MockActor()
+
+    @pytest.fixture
+    def model(self):
+        return MockMAPI()
+
+    @pytest.fixture
+    def dict_(self, actor, model):
+        return collection_instrumentation._InstrumentedDict(model, actor, 'dict_', models.Attribute)
+
+    @pytest.fixture
+    def list_(self, actor, model):
+        return collection_instrumentation._InstrumentedList(model, actor, 'list_', models.Attribute)
+
+
+class TestDict(CollectionInstrumentation):
+
+    def test_keys(self, actor, dict_):
+        dict_.update(
+            {
+                'key1': models.Attribute.wrap('key1', 'value1'),
+                'key2': models.Attribute.wrap('key2', 'value2')
+            }
+        )
+        assert sorted(dict_.keys()) == sorted(['key1', 'key2']) == sorted(actor.dict_.keys())
+
+    def test_values(self, actor, dict_):
+        dict_.update({
+            'key1': models.Attribute.wrap('key1', 'value1'),
+            'key2': models.Attribute.wrap('key1', 'value2')
+        })
+        assert (sorted(dict_.values()) ==
+                sorted(['value1', 'value2']) ==
+                sorted(v.value for v in actor.dict_.values()))
+
+    def test_items(self, dict_):
+        dict_.update({
+            'key1': models.Attribute.wrap('key1', 'value1'),
+            'key2': models.Attribute.wrap('key1', 'value2')
+        })
+        assert sorted(dict_.items()) == sorted([('key1', 'value1'), ('key2', 'value2')])
+
+    def test_iter(self, actor, dict_):
+        dict_.update({
+            'key1': models.Attribute.wrap('key1', 'value1'),
+            'key2': models.Attribute.wrap('key1', 'value2')
+        })
+        assert sorted(list(dict_)) == sorted(['key1', 'key2']) == sorted(actor.dict_.keys())
+
+    def test_bool(self, dict_):
+        assert not dict_
+        dict_.update({
+            'key1': models.Attribute.wrap('key1', 'value1'),
+            'key2': models.Attribute.wrap('key1', 'value2')
+        })
+        assert dict_
+
+    def test_set_item(self, actor, dict_):
+        dict_['key1'] = models.Attribute.wrap('key1', 'value1')
+        assert dict_['key1'] == 'value1' == actor.dict_['key1'].value
+        assert isinstance(actor.dict_['key1'], models.Attribute)
+
+    def test_nested(self, actor, dict_):
+        dict_['key'] = {}
+        assert isinstance(actor.dict_['key'], models.Attribute)
+        assert dict_['key'] == actor.dict_['key'].value == {}
+
+        dict_['key']['inner_key'] = 'value'
+
+        assert len(dict_) == 1
+        assert 'inner_key' in dict_['key']
+        assert dict_['key']['inner_key'] == 'value'
+        assert dict_['key'].keys() == ['inner_key']
+        assert dict_['key'].values() == ['value']
+        assert dict_['key'].items() == [('inner_key', 'value')]
+        assert isinstance(actor.dict_['key'], models.Attribute)
+        assert isinstance(dict_['key'], collection_instrumentation._InstrumentedDict)
+
+        dict_['key'].update({'updated_key': 'updated_value'})
+        assert len(dict_) == 1
+        assert 'updated_key' in dict_['key']
+        assert dict_['key']['updated_key'] == 'updated_value'
+        assert sorted(dict_['key'].keys()) == sorted(['inner_key', 'updated_key'])
+        assert sorted(dict_['key'].values()) == sorted(['value', 'updated_value'])
+        assert sorted(dict_['key'].items()) == sorted([('inner_key', 'value'),
+                                                       ('updated_key', 'updated_value')])
+        assert isinstance(actor.dict_['key'], models.Attribute)
+        assert isinstance(dict_['key'], collection_instrumentation._InstrumentedDict)
+
+        dict_.update({'key': 'override_value'})
+        assert len(dict_) == 1
+        assert 'key' in dict_
+        assert dict_['key'] == 'override_value'
+        assert len(actor.dict_) == 1
+        assert isinstance(actor.dict_['key'], models.Attribute)
+        assert actor.dict_['key'].value == 'override_value'
+
+    def test_get_item(self, actor, dict_):
+        dict_['key1'] = models.Attribute.wrap('key1', 'value1')
+        assert isinstance(actor.dict_['key1'], models.Attribute)
+
+    def test_update(self, actor, dict_):
+        dict_['key1'] = 'value1'
+
+        new_dict = {'key2': 'value2'}
+        dict_.update(new_dict)
+        assert len(dict_) == 2
+        assert dict_['key2'] == 'value2'
+        assert isinstance(actor.dict_['key2'], models.Attribute)
+
+        new_dict = {}
+        new_dict.update(dict_)
+        assert new_dict['key1'] == dict_['key1']
+
+    def test_copy(self, dict_):
+        dict_['key1'] = 'value1'
+
+        new_dict = dict_.copy()
+        assert new_dict is not dict_
+        assert new_dict == dict_
+
+        dict_['key1'] = 'value2'
+        assert new_dict['key1'] == 'value1'
+        assert dict_['key1'] == 'value2'
+
+    def test_clear(self, dict_):
+        dict_['key1'] = 'value1'
+        dict_.clear()
+
+        assert len(dict_) == 0
+
+
+class TestList(CollectionInstrumentation):
+
+    def test_append(self, actor, list_):
+        list_.append(models.Attribute.wrap('name', 'value1'))
+        list_.append('value2')
+        assert len(actor.list_) == 2
+        assert len(list_) == 2
+        assert isinstance(actor.list_[0], models.Attribute)
+        assert list_[0] == 'value1'
+
+        assert isinstance(actor.list_[1], models.Attribute)
+        assert list_[1] == 'value2'
+
+        list_[0] = 'new_value1'
+        list_[1] = 'new_value2'
+        assert isinstance(actor.list_[1], models.Attribute)
+        assert isinstance(actor.list_[1], models.Attribute)
+        assert list_[0] == 'new_value1'
+        assert list_[1] == 'new_value2'
+
+    def test_iter(self, list_):
+        list_.append('value1')
+        list_.append('value2')
+        assert sorted(list_) == sorted(['value1', 'value2'])
+
+    def test_insert(self, actor, list_):
+        list_.append('value1')
+        list_.insert(0, 'value2')
+        list_.insert(2, 'value3')
+        list_.insert(10, 'value4')
+        assert sorted(list_) == sorted(['value1', 'value2', 'value3', 'value4'])
+        assert len(actor.list_) == 4
+
+    def test_set(self, list_):
+        list_.append('value1')
+        list_.append('value2')
+
+        list_[1] = 'value3'
+        assert len(list_) == 2
+        assert sorted(list_) == sorted(['value1', 'value3'])
+
+    def test_insert_into_nested(self, actor, list_):
+        list_.append([])
+
+        list_[0].append('inner_item')
+        assert isinstance(actor.list_[0], models.Attribute)
+        assert len(list_) == 1
+        assert list_[0][0] == 'inner_item'
+
+        list_[0].append('new_item')
+        assert isinstance(actor.list_[0], models.Attribute)
+        assert len(list_) == 1
+        assert list_[0][1] == 'new_item'
+
+        assert list_[0] == ['inner_item', 'new_item']
+        assert ['inner_item', 'new_item'] == list_[0]
+
+
+class TestDictList(CollectionInstrumentation):
+    def test_dict_in_list(self, actor, list_):
+        list_.append({})
+        assert len(list_) == 1
+        assert isinstance(actor.list_[0], models.Attribute)
+        assert actor.list_[0].value == {}
+
+        list_[0]['key'] = 'value'
+        assert list_[0]['key'] == 'value'
+        assert len(actor.list_) == 1
+        assert isinstance(actor.list_[0], models.Attribute)
+        assert actor.list_[0].value['key'] == 'value'
+
+    def test_list_in_dict(self, actor, dict_):
+        dict_['key'] = []
+        assert len(dict_) == 1
+        assert isinstance(actor.dict_['key'], models.Attribute)
+        assert actor.dict_['key'].value == []
+
+        dict_['key'].append('value')
+        assert dict_['key'][0] == 'value'
+        assert len(actor.dict_) == 1
+        assert isinstance(actor.dict_['key'], models.Attribute)
+        assert actor.dict_['key'].value[0] == 'value'


[10/10] incubator-ariatosca git commit: ARIA-254 Create of multiple nodes per template

Posted by em...@apache.org.
ARIA-254 Create of multiple nodes per template

* New aria.Scaling policy (and "scaling" role)
* NodeTemplate model no longer stores scaling values (default_instances,
etc.) but instead fetches them from applicable scaling policies
* Some code cleanup


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/b7ec71e6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/b7ec71e6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/b7ec71e6

Branch: refs/heads/ARIA-254-multiple-nodes-per-template
Commit: b7ec71e62b588385dc95e7c284011c7949de57b6
Parents: e6cf67e
Author: Tal Liron <ta...@gmail.com>
Authored: Thu Jun 1 14:17:17 2017 -0500
Committer: Tal Liron <ta...@gmail.com>
Committed: Fri Jun 16 17:27:32 2017 -0500

----------------------------------------------------------------------
 aria/cli/commands/workflows.py                  |   4 +-
 aria/cli/execution_logging.py                   |   4 +-
 aria/core.py                                    |   2 +-
 aria/modeling/orchestration.py                  |  12 +-
 aria/modeling/relationship.py                   |   2 +-
 aria/modeling/service_changes.py                |   8 +-
 aria/modeling/service_common.py                 |   2 +-
 aria/modeling/service_instance.py               |  59 +++----
 aria/modeling/service_template.py               | 153 +++++++++++++------
 aria/modeling/types.py                          |   4 +-
 aria/orchestrator/workflow_runner.py            |   2 +-
 aria/orchestrator/workflows/executor/celery.py  |   2 +-
 aria/orchestrator/workflows/executor/process.py |   2 +-
 aria/orchestrator/workflows/executor/thread.py  |   2 +-
 aria/storage/core.py                            |   2 +-
 .../profiles/aria-1.0/aria-1.0.yaml             |  25 ++-
 .../simple_v1_0/assignments.py                  |   8 +
 .../simple_v1_0/data_types.py                   |  22 ++-
 .../simple_v1_0/definitions.py                  |   8 +
 .../aria_extension_tosca/simple_v1_0/filters.py |   2 +
 .../aria_extension_tosca/simple_v1_0/misc.py    |  10 ++
 .../simple_v1_0/modeling/__init__.py            |   3 -
 .../simple_v1_0/presentation/extensible.py      |   1 +
 .../presentation/field_validators.py            |  20 +++
 .../simple_v1_0/presentation/types.py           |   2 +
 .../simple_v1_0/presenter.py                    |   3 +-
 .../simple_v1_0/templates.py                    |   8 +-
 .../aria_extension_tosca/simple_v1_0/types.py   |  10 +-
 tests/end2end/test_hello_world.py               |   2 +-
 tests/end2end/test_nodecellar.py                |   2 +-
 tests/mock/models.py                            |   8 +-
 tests/modeling/test_mixins.py                   |   3 -
 tests/modeling/test_models.py                   |  20 +--
 tests/orchestrator/context/test_operation.py    |   2 +-
 .../node-cellar/node-cellar.yaml                |   1 +
 .../node-cellar/types/openstack.yaml            |   3 +-
 36 files changed, 286 insertions(+), 137 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/aria/cli/commands/workflows.py
----------------------------------------------------------------------
diff --git a/aria/cli/commands/workflows.py b/aria/cli/commands/workflows.py
index 221dbc4..baab973 100644
--- a/aria/cli/commands/workflows.py
+++ b/aria/cli/commands/workflows.py
@@ -42,7 +42,7 @@ def show(workflow_name, service_name, model_storage, logger):
     logger.info('Retrieving workflow {0} for service {1}'.format(
         workflow_name, service_name))
     service = model_storage.service.get_by_name(service_name)
-    workflow = next((wf for wf in service.workflows.values() if
+    workflow = next((wf for wf in service.workflows.itervalues() if
                      wf.name == workflow_name), None)
     if not workflow:
         raise AriaCliError(
@@ -91,7 +91,7 @@ def list(service_name, model_storage, logger):
     """
     logger.info('Listing workflows for service {0}...'.format(service_name))
     service = model_storage.service.get_by_name(service_name)
-    workflows_list = sorted(service.workflows.values(), key=lambda w: w.name)
+    workflows_list = sorted(service.workflows.itervalues(), key=lambda w: w.name)
 
     defaults = {
         'service_template_name': service.service_template_name,

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/aria/cli/execution_logging.py
----------------------------------------------------------------------
diff --git a/aria/cli/execution_logging.py b/aria/cli/execution_logging.py
index 248ff7c..467123c 100644
--- a/aria/cli/execution_logging.py
+++ b/aria/cli/execution_logging.py
@@ -106,11 +106,11 @@ def stylize_log(item, mark_pattern):
     if item.task:
         # operation task
         implementation = item.task.function
-        inputs = dict(arg.unwrapped for arg in item.task.arguments.values())
+        inputs = dict(arg.unwrapped for arg in item.task.arguments.itervalues())
     else:
         # execution task
         implementation = item.execution.workflow_name
-        inputs = dict(inp.unwrapped for inp in item.execution.inputs.values())
+        inputs = dict(inp.unwrapped for inp in item.execution.inputs.itervalues())
 
     stylized_str = color.StringStylizer(_get_format())
     _populate_level(stylized_str, item)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/aria/core.py
----------------------------------------------------------------------
diff --git a/aria/core.py b/aria/core.py
index f660167..f286e66 100644
--- a/aria/core.py
+++ b/aria/core.py
@@ -106,7 +106,7 @@ class Core(object):
                 'Active execution ID: {1}'.format(service.name, active_executions[0].id))
 
         if not force:
-            available_nodes = [str(n.id) for n in service.nodes.values() if n.is_available()]
+            available_nodes = [str(n.id) for n in service.nodes.itervalues() if n.is_available()]
             if available_nodes:
                 raise exceptions.DependentAvailableNodesError(
                     'Can\'t delete service `{0}` - there are available nodes for this service. '

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/aria/modeling/orchestration.py
----------------------------------------------------------------------
diff --git a/aria/modeling/orchestration.py b/aria/modeling/orchestration.py
index 995c8c2..9186c55 100644
--- a/aria/modeling/orchestration.py
+++ b/aria/modeling/orchestration.py
@@ -53,8 +53,8 @@ class ExecutionBase(ModelMixin):
 
     __tablename__ = 'execution'
 
-    __private_fields__ = ['service_fk',
-                          'service_template']
+    __private_fields__ = ('service_fk',
+                          'service_template')
 
     SUCCEEDED = 'succeeded'
     FAILED = 'failed'
@@ -257,10 +257,10 @@ class TaskBase(ModelMixin):
 
     __tablename__ = 'task'
 
-    __private_fields__ = ['node_fk',
+    __private_fields__ = ('node_fk',
                           'relationship_fk',
                           'plugin_fk',
-                          'execution_fk']
+                          'execution_fk')
 
     PENDING = 'pending'
     RETRYING = 'retrying'
@@ -397,8 +397,8 @@ class LogBase(ModelMixin):
 
     __tablename__ = 'log'
 
-    __private_fields__ = ['execution_fk',
-                          'task_fk']
+    __private_fields__ = ('execution_fk',
+                          'task_fk')
 
     @declared_attr
     def execution(cls):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/aria/modeling/relationship.py
----------------------------------------------------------------------
diff --git a/aria/modeling/relationship.py b/aria/modeling/relationship.py
index 40be5b2..f2c3986 100644
--- a/aria/modeling/relationship.py
+++ b/aria/modeling/relationship.py
@@ -352,7 +352,7 @@ def _get_class_for_table(model_class, tablename):
     if tablename in (model_class.__name__, model_class.__tablename__):
         return model_class
 
-    for table_cls in model_class._decl_class_registry.values():
+    for table_cls in model_class._decl_class_registry.itervalues():
         if tablename == getattr(table_cls, '__tablename__', None):
             return table_cls
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/aria/modeling/service_changes.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_changes.py b/aria/modeling/service_changes.py
index f632fef..39b5f10 100644
--- a/aria/modeling/service_changes.py
+++ b/aria/modeling/service_changes.py
@@ -44,8 +44,8 @@ class ServiceUpdateBase(ModelMixin):
     """
     __tablename__ = 'service_update'
 
-    __private_fields__ = ['service_fk',
-                          'execution_fk']
+    __private_fields__ = ('service_fk',
+                          'execution_fk')
 
     created_at = Column(DateTime, nullable=False, index=True)
     service_plan = Column(Dict, nullable=False)
@@ -119,7 +119,7 @@ class ServiceUpdateStepBase(ModelMixin):
 
     __tablename__ = 'service_update_step'
 
-    __private_fields__ = ['service_update_fk']
+    __private_fields__ = ('service_update_fk',)
 
     _action_types = namedtuple('ACTION_TYPES', 'ADD, REMOVE, MODIFY')
     ACTION_TYPES = _action_types(ADD='add', REMOVE='remove', MODIFY='modify')
@@ -211,7 +211,7 @@ class ServiceModificationBase(ModelMixin):
 
     __tablename__ = 'service_modification'
 
-    __private_fields__ = ['service_fk']
+    __private_fields__ = ('service_fk',)
 
     STARTED = 'started'
     FINISHED = 'finished'

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/aria/modeling/service_common.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_common.py b/aria/modeling/service_common.py
index 272dfd7..c56238c 100644
--- a/aria/modeling/service_common.py
+++ b/aria/modeling/service_common.py
@@ -308,7 +308,7 @@ class TypeBase(InstanceModelMixin):
 
     __tablename__ = 'type'
 
-    __private_fields__ = ['parent_type_fk']
+    __private_fields__ = ('parent_type_fk',)
 
     variant = Column(Text, nullable=False)
     description = Column(Text)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/aria/modeling/service_instance.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_instance.py b/aria/modeling/service_instance.py
index 2bf9872..d94ef57 100644
--- a/aria/modeling/service_instance.py
+++ b/aria/modeling/service_instance.py
@@ -88,8 +88,8 @@ class ServiceBase(InstanceModelMixin):
 
     __tablename__ = 'service'
 
-    __private_fields__ = ['substitution_fk',
-                          'service_template_fk']
+    __private_fields__ = ('substitution_fk',
+                          'service_template_fk')
 
     # region foreign keys
 
@@ -357,10 +357,10 @@ class NodeBase(InstanceModelMixin):
 
     __tablename__ = 'node'
 
-    __private_fields__ = ['type_fk',
+    __private_fields__ = ('type_fk',
                           'host_fk',
                           'service_fk',
-                          'node_template_fk']
+                          'node_template_fk')
 
     INITIAL = 'initial'
     CREATING = 'creating'
@@ -371,16 +371,17 @@ class NodeBase(InstanceModelMixin):
     STARTED = 'started'
     STOPPING = 'stopping'
     DELETING = 'deleting'
-    # 'deleted' isn't actually part of the tosca spec, since according the description of the
-    # 'deleting' state: "Node is transitioning from its current state to one where it is deleted and
-    #  its state is no longer tracked by the instance model."
-    # However, we prefer to be able to retrieve information about deleted nodes, so we chose to add
-    # this 'deleted' state to enable us to do so.
     DELETED = 'deleted'
     ERROR = 'error'
 
-    STATES = [INITIAL, CREATING, CREATED, CONFIGURING, CONFIGURED, STARTING, STARTED, STOPPING,
-              DELETING, DELETED, ERROR]
+    # Note: 'deleted' isn't actually part of the TOSCA spec, since according the description of the
+    # 'deleting' state: "Node is transitioning from its current state to one where it is deleted and
+    # its state is no longer tracked by the instance model." However, we prefer to be able to
+    # retrieve information about deleted nodes, so we chose to add this 'deleted' state to enable us
+    # to do so.
+
+    STATES = (INITIAL, CREATING, CREATED, CONFIGURING, CONFIGURED, STARTING, STARTED, STOPPING,
+              DELETING, DELETED, ERROR)
 
     _op_to_state = {'create': {'transitional': CREATING, 'finished': CREATED},
                     'configure': {'transitional': CONFIGURING, 'finished': CONFIGURED},
@@ -722,7 +723,9 @@ class GroupBase(InstanceModelMixin):
 
     __tablename__ = 'group'
 
-    __private_fields__ = ['type_fk', 'service_fk', 'group_template_fk']
+    __private_fields__ = ('type_fk',
+                          'service_fk',
+                          'group_template_fk')
 
     # region foreign_keys
 
@@ -846,7 +849,9 @@ class PolicyBase(InstanceModelMixin):
 
     __tablename__ = 'policy'
 
-    __private_fields__ = ['type_fk', 'service_fk', 'policy_template_fk']
+    __private_fields__ = ('type_fk',
+                          'service_fk',
+                          'policy_template_fk')
 
     # region foreign_keys
 
@@ -962,8 +967,8 @@ class SubstitutionBase(InstanceModelMixin):
 
     __tablename__ = 'substitution'
 
-    __private_fields__ = ['node_type_fk',
-                          'substitution_template_fk']
+    __private_fields__ = ('node_type_fk',
+                          'substitution_template_fk')
 
     # region foreign_keys
 
@@ -1053,10 +1058,10 @@ class SubstitutionMappingBase(InstanceModelMixin):
 
     __tablename__ = 'substitution_mapping'
 
-    __private_fields__ = ['substitution_fk',
+    __private_fields__ = ('substitution_fk',
                           'node_fk',
                           'capability_fk',
-                          'requirement_template_fk']
+                          'requirement_template_fk')
 
     # region foreign keys
 
@@ -1176,14 +1181,14 @@ class RelationshipBase(InstanceModelMixin):
 
     __tablename__ = 'relationship'
 
-    __private_fields__ = ['type_fk',
+    __private_fields__ = ('type_fk',
                           'source_node_fk',
                           'target_node_fk',
                           'target_capability_fk',
                           'requirement_template_fk',
                           'relationship_template_fk',
                           'target_position',
-                          'source_position']
+                          'source_position')
 
     # region foreign keys
 
@@ -1360,9 +1365,9 @@ class CapabilityBase(InstanceModelMixin):
 
     __tablename__ = 'capability'
 
-    __private_fields__ = ['capability_fk',
+    __private_fields__ = ('capability_fk',
                           'node_fk',
-                          'capability_template_fk']
+                          'capability_template_fk')
 
     # region foreign_keys
 
@@ -1487,11 +1492,11 @@ class InterfaceBase(InstanceModelMixin):
 
     __tablename__ = 'interface'
 
-    __private_fields__ = ['type_fk',
+    __private_fields__ = ('type_fk',
                           'node_fk',
                           'group_fk',
                           'relationship_fk',
-                          'interface_template_fk']
+                          'interface_template_fk')
 
     # region foreign_keys
 
@@ -1644,10 +1649,10 @@ class OperationBase(InstanceModelMixin):
 
     __tablename__ = 'operation'
 
-    __private_fields__ = ['service_fk',
+    __private_fields__ = ('service_fk',
                           'interface_fk',
                           'plugin_fk',
-                          'operation_template_fk']
+                          'operation_template_fk')
 
     # region foreign_keys
 
@@ -1849,9 +1854,9 @@ class ArtifactBase(InstanceModelMixin):
 
     __tablename__ = 'artifact'
 
-    __private_fields__ = ['type_fk',
+    __private_fields__ = ('type_fk',
                           'node_fk',
-                          'artifact_template_fk']
+                          'artifact_template_fk')
 
     # region foreign_keys
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/aria/modeling/service_template.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py
index 4d1e837..dfef8d6 100644
--- a/aria/modeling/service_template.py
+++ b/aria/modeling/service_template.py
@@ -98,14 +98,14 @@ class ServiceTemplateBase(TemplateModelMixin):
 
     __tablename__ = 'service_template'
 
-    __private_fields__ = ['substitution_template_fk',
+    __private_fields__ = ('substitution_template_fk',
                           'node_type_fk',
                           'group_type_fk',
                           'policy_type_fk',
                           'relationship_type_fk',
                           'capability_type_fk',
                           'interface_type_fk',
-                          'artifact_type_fk']
+                          'artifact_type_fk')
 
     description = Column(Text)
     main_file_name = Column(Text)
@@ -279,12 +279,14 @@ class ServiceTemplateBase(TemplateModelMixin):
 
     def instantiate(self, container, model_storage, inputs=None):  # pylint: disable=arguments-differ
         from . import models
-        context = ConsumptionContext.get_thread_local()
         now = datetime.now()
         service = models.Service(created_at=now,
                                  updated_at=now,
                                  description=deepcopy_with_locators(self.description),
                                  service_template=self)
+
+        # TODO: we want to remove this use of the context
+        context = ConsumptionContext.get_thread_local()
         context.modeling.instance = service
 
         service.inputs = utils.merge_parameter_values(inputs, self.inputs, model_cls=models.Input)
@@ -438,8 +440,8 @@ class NodeTemplateBase(TemplateModelMixin):
 
     __tablename__ = 'node_template'
 
-    __private_fields__ = ['type_fk',
-                          'service_template_fk']
+    __private_fields__ = ('type_fk',
+                          'service_template_fk')
 
     # region foreign_keys
 
@@ -518,27 +520,14 @@ class NodeTemplateBase(TemplateModelMixin):
     # endregion
 
     description = Column(Text)
-    default_instances = Column(Integer, default=1)
-    min_instances = Column(Integer, default=0)
-    max_instances = Column(Integer, default=None)
     target_node_template_constraints = Column(PickleType)
 
-    def is_target_node_template_valid(self, target_node_template):
-        if self.target_node_template_constraints:
-            for node_template_constraint in self.target_node_template_constraints:
-                if not node_template_constraint.matches(self, target_node_template):
-                    return False
-        return True
-
     @property
     def as_raw(self):
         return collections.OrderedDict((
             ('name', self.name),
             ('description', self.description),
             ('type_name', self.type.name),
-            ('default_instances', self.default_instances),
-            ('min_instances', self.min_instances),
-            ('max_instances', self.max_instances),
             ('properties', formatting.as_raw_dict(self.properties)),
             ('attributes', formatting.as_raw_dict(self.properties)),
             ('interface_templates', formatting.as_raw_list(self.interface_templates)),
@@ -548,13 +537,7 @@ class NodeTemplateBase(TemplateModelMixin):
 
     def instantiate(self, container):
         from . import models
-        if self.nodes:
-            highest_name_suffix = max(int(n.name.rsplit('_', 1)[-1]) for n in self.nodes)
-            suffix = highest_name_suffix + 1
-        else:
-            suffix = 1
-        name = '{name}_{index}'.format(name=self.name, index=suffix)
-        node = models.Node(name=name,
+        node = models.Node(name=self.next_name,
                            type=self.type,
                            description=deepcopy_with_locators(self.description),
                            state=models.Node.INITIAL,
@@ -566,10 +549,12 @@ class NodeTemplateBase(TemplateModelMixin):
         utils.instantiate_dict(node, node.capabilities, self.capability_templates)
 
         # Default attributes
-        if 'tosca_name' in node.attributes:
+        if ('tosca_name' in node.attributes) \
+            and (node.attributes['tosca_name'].type_name == 'string'):
             node.attributes['tosca_name'].value = self.name
-        if 'tosca_id' in node.attributes:
-            node.attributes['tosca_id'].value = name
+        if 'tosca_id' in node.attributes \
+            and (node.attributes['tosca_id'].type_name == 'string'):
+            node.attributes['tosca_id'].value = node.name
 
         return node
 
@@ -609,6 +594,56 @@ class NodeTemplateBase(TemplateModelMixin):
             utils.dump_dict_values(self.capability_templates, 'Capability templates')
             utils.dump_list_values(self.requirement_templates, 'Requirement templates')
 
+    @property
+    def next_index(self):
+        """
+        Next available node index.
+
+        :returns: node index
+        :rtype: int
+        """
+
+        max_index = 0
+        if self.nodes:
+            max_index = max(int(n.name.rsplit('_', 1)[-1]) for n in self.nodes)
+        return max_index + 1
+
+    @property
+    def next_name(self):
+        """
+        Next available node name.
+
+        :returns: node name
+        :rtype: basestring
+        """
+
+        return '{name}_{index}'.format(name=self.name, index=self.next_index)
+
+    @property
+    def default_instances(self):
+        # TODO: currently finds the first matching policy; but we should emit a validation error
+        # if more than one policy applies to the same node
+        for policy_template in self.service_template.policy_templates.itervalues():
+            if policy_template.type.role == 'scaling':
+                if policy_template.is_for_node_template(self.name):
+                    default_instances = policy_template.properties.get('default_instances')
+                    if (default_instances is not None) \
+                        and (default_instances.type_name == 'integer'):
+                        return default_instances.value
+                    break
+        return 1
+
+    def is_target_node_template_valid(self, target_node_template):
+        """
+        Checks if ``target_node_template`` matches all our ``target_node_template_constraints``.
+        """
+
+        if self.target_node_template_constraints:
+            for node_template_constraint in self.target_node_template_constraints:
+                if not node_template_constraint.matches(self, target_node_template):
+                    return False
+        return True
+
 
 class GroupTemplateBase(TemplateModelMixin):
     """
@@ -638,8 +673,8 @@ class GroupTemplateBase(TemplateModelMixin):
 
     __tablename__ = 'group_template'
 
-    __private_fields__ = ['type_fk',
-                          'service_template_fk']
+    __private_fields__ = ('type_fk',
+                          'service_template_fk')
 
     # region foreign keys
 
@@ -744,6 +779,12 @@ class GroupTemplateBase(TemplateModelMixin):
                 console.puts('Member node templates: {0}'.format(', '.join(
                     (str(context.style.node(v.name)) for v in self.node_templates))))
 
+    def contains_node_template(self, name):
+        for node_template in self.node_templates:
+            if node_template.name == name:
+                return True
+        return False
+
 
 class PolicyTemplateBase(TemplateModelMixin):
     """
@@ -770,7 +811,8 @@ class PolicyTemplateBase(TemplateModelMixin):
 
     __tablename__ = 'policy_template'
 
-    __private_fields__ = ['type_fk', 'service_template_fk']
+    __private_fields__ = ('type_fk',
+                          'service_template_fk')
 
     # region foreign keys
 
@@ -876,6 +918,21 @@ class PolicyTemplateBase(TemplateModelMixin):
                 console.puts('Target group templates: {0}'.format(', '.join(
                     (str(context.style.node(v.name)) for v in self.group_templates))))
 
+    def is_for_node_template(self, name):
+        for node_template in self.node_templates:
+            if node_template.name == name:
+                return True
+        for group_template in self.group_templates:
+            if group_template.contains_node_template(name):
+                return True
+        return False
+
+    def is_for_group_template(self, name):
+        for group_template in self.group_templates:
+            if group_template.name == name:
+                return True
+        return False
+
 
 class SubstitutionTemplateBase(TemplateModelMixin):
     """
@@ -893,7 +950,7 @@ class SubstitutionTemplateBase(TemplateModelMixin):
 
     __tablename__ = 'substitution_template'
 
-    __private_fields__ = ['node_type_fk']
+    __private_fields__ = ('node_type_fk',)
 
     # region foreign keys
 
@@ -979,10 +1036,10 @@ class SubstitutionTemplateMappingBase(TemplateModelMixin):
 
     __tablename__ = 'substitution_template_mapping'
 
-    __private_fields__ = ['substitution_template_fk',
+    __private_fields__ = ('substitution_template_fk',
                           'node_template_fk',
                           'capability_template_fk',
-                          'requirement_template_fk']
+                          'requirement_template_fk')
 
     # region foreign keys
 
@@ -1125,11 +1182,11 @@ class RequirementTemplateBase(TemplateModelMixin):
 
     __tablename__ = 'requirement_template'
 
-    __private_fields__ = ['target_node_type_fk',
+    __private_fields__ = ('target_node_type_fk',
                           'target_node_template_fk',
                           'target_capability_type_fk'
                           'node_template_fk',
-                          'relationship_template_fk']
+                          'relationship_template_fk')
 
     # region foreign keys
 
@@ -1236,7 +1293,7 @@ class RequirementTemplateBase(TemplateModelMixin):
         # Find first node that matches the type
         elif self.target_node_type is not None:
             for target_node_template in \
-                    self.node_template.service_template.node_templates.values():
+                    self.node_template.service_template.node_templates.itervalues():
                 if self.target_node_type.get_descendant(target_node_template.type.name) is None:
                     continue
 
@@ -1338,7 +1395,7 @@ class RelationshipTemplateBase(TemplateModelMixin):
 
     __tablename__ = 'relationship_template'
 
-    __private_fields__ = ['type_fk']
+    __private_fields__ = ('type_fk',)
 
     # region foreign keys
 
@@ -1453,8 +1510,8 @@ class CapabilityTemplateBase(TemplateModelMixin):
 
     __tablename__ = 'capability_template'
 
-    __private_fields__ = ['type_fk',
-                          'node_template_fk']
+    __private_fields__ = ('type_fk',
+                          'node_template_fk')
 
     # region foreign keys
 
@@ -1612,10 +1669,10 @@ class InterfaceTemplateBase(TemplateModelMixin):
 
     __tablename__ = 'interface_template'
 
-    __private_fields__ = ['type_fk',
+    __private_fields__ = ('type_fk',
                           'node_template_fk',
                           'group_template_fk',
-                          'relationship_template_fk']
+                          'relationship_template_fk')
 
     # region foreign keys
 
@@ -1768,9 +1825,9 @@ class OperationTemplateBase(TemplateModelMixin):
 
     __tablename__ = 'operation_template'
 
-    __private_fields__ = ['service_template_fk',
+    __private_fields__ = ('service_template_fk',
                           'interface_template_fk',
-                          'plugin_fk']
+                          'plugin_fk')
 
     # region foreign keys
 
@@ -1943,8 +2000,8 @@ class ArtifactTemplateBase(TemplateModelMixin):
 
     __tablename__ = 'artifact_template'
 
-    __private_fields__ = ['type_fk',
-                          'node_template_fk']
+    __private_fields__ = ('type_fk',
+                          'node_template_fk')
 
     # region foreign keys
 
@@ -2064,8 +2121,8 @@ class PluginSpecificationBase(TemplateModelMixin):
 
     __tablename__ = 'plugin_specification'
 
-    __private_fields__ = ['service_template_fk',
-                          'plugin_fk']
+    __private_fields__ = ('service_template_fk',
+                          'plugin_fk')
 
     version = Column(Text)
     enabled = Column(Boolean, nullable=False, default=True)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/aria/modeling/types.py
----------------------------------------------------------------------
diff --git a/aria/modeling/types.py b/aria/modeling/types.py
index 920a0c2..fe57617 100644
--- a/aria/modeling/types.py
+++ b/aria/modeling/types.py
@@ -258,10 +258,10 @@ StrictList = _StrictList()
 
 def _mutable_association_listener(mapper, cls):
     strict_dict_type_to_listener = \
-        dict((v.type_cls, v.listener_cls) for v in _StrictDict._strict_map.values())
+        dict((v.type_cls, v.listener_cls) for v in _StrictDict._strict_map.itervalues())
 
     strict_list_type_to_listener = \
-        dict((v.type_cls, v.listener_cls) for v in _StrictList._strict_map.values())
+        dict((v.type_cls, v.listener_cls) for v in _StrictList._strict_map.itervalues())
 
     for prop in mapper.column_attrs:
         column_type = prop.columns[0].type

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/aria/orchestrator/workflow_runner.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflow_runner.py b/aria/orchestrator/workflow_runner.py
index 848c59b..0577991 100644
--- a/aria/orchestrator/workflow_runner.py
+++ b/aria/orchestrator/workflow_runner.py
@@ -81,7 +81,7 @@ class WorkflowRunner(object):
             task_retry_interval=task_retry_interval)
 
         # transforming the execution inputs to dict, to pass them to the workflow function
-        execution_inputs_dict = dict(inp.unwrapped for inp in self.execution.inputs.values())
+        execution_inputs_dict = dict(inp.unwrapped for inp in self.execution.inputs.itervalues())
         self._tasks_graph = workflow_fn(ctx=workflow_context, **execution_inputs_dict)
 
         executor = executor or ProcessExecutor(plugin_manager=plugin_manager)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/aria/orchestrator/workflows/executor/celery.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/executor/celery.py b/aria/orchestrator/workflows/executor/celery.py
index 9d66d26..749b091 100644
--- a/aria/orchestrator/workflows/executor/celery.py
+++ b/aria/orchestrator/workflows/executor/celery.py
@@ -44,7 +44,7 @@ class CeleryExecutor(BaseExecutor):
 
     def _execute(self, task):
         self._tasks[task.id] = task
-        arguments = dict(arg.unwrapped for arg in task.arguments.values())
+        arguments = dict(arg.unwrapped for arg in task.arguments.itervalues())
         arguments['ctx'] = task.context
         self._results[task.id] = self._app.send_task(
             task.operation_mapping,

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/aria/orchestrator/workflows/executor/process.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/executor/process.py b/aria/orchestrator/workflows/executor/process.py
index 634f1f2..ec1be44 100644
--- a/aria/orchestrator/workflows/executor/process.py
+++ b/aria/orchestrator/workflows/executor/process.py
@@ -141,7 +141,7 @@ class ProcessExecutor(base.BaseExecutor):
         return {
             'task_id': task.id,
             'function': task.function,
-            'operation_arguments': dict(arg.unwrapped for arg in task.arguments.values()),
+            'operation_arguments': dict(arg.unwrapped for arg in task.arguments.itervalues()),
             'port': self._server_port,
             'context': task.context.serialization_dict,
         }

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/aria/orchestrator/workflows/executor/thread.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/executor/thread.py b/aria/orchestrator/workflows/executor/thread.py
index 56a56a5..7d01c90 100644
--- a/aria/orchestrator/workflows/executor/thread.py
+++ b/aria/orchestrator/workflows/executor/thread.py
@@ -61,7 +61,7 @@ class ThreadExecutor(BaseExecutor):
                 self._task_started(task)
                 try:
                     task_func = imports.load_attribute(task.function)
-                    arguments = dict(arg.unwrapped for arg in task.arguments.values())
+                    arguments = dict(arg.unwrapped for arg in task.arguments.itervalues())
                     task_func(ctx=task.context, **arguments)
                     self._task_succeeded(task)
                 except BaseException as e:

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/aria/storage/core.py
----------------------------------------------------------------------
diff --git a/aria/storage/core.py b/aria/storage/core.py
index 06c29e8..25ad252 100644
--- a/aria/storage/core.py
+++ b/aria/storage/core.py
@@ -165,7 +165,7 @@ class ModelStorage(Storage):
         Drop all the tables from the model.
         :return:
         """
-        for mapi in self.registered.values():
+        for mapi in self.registered.itervalues():
             mapi.drop()
 
     @contextmanager

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/extensions/aria_extension_tosca/profiles/aria-1.0/aria-1.0.yaml
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/profiles/aria-1.0/aria-1.0.yaml b/extensions/aria_extension_tosca/profiles/aria-1.0/aria-1.0.yaml
index c1dc11d..71d6e8e 100644
--- a/extensions/aria_extension_tosca/profiles/aria-1.0/aria-1.0.yaml
+++ b/extensions/aria_extension_tosca/profiles/aria-1.0/aria-1.0.yaml
@@ -58,4 +58,27 @@ policy_types:
           the full path to a Python @workflow function that generates a task graph based on the
           service topology.
         type: string
-        required: true
+
+  aria.Scaling:
+    _extensions:
+      type_qualified_name: aria:Scaling
+      role: scaling
+    description: >-
+      Scaling.
+    derived_from: tosca.policies.Scaling
+    properties:
+      default_instances:
+        type: integer
+        default: 1
+        constraints:
+          - greater_or_equal: 0
+      min_instances:
+        type: integer
+        default: 0
+        constraints:
+          - greater_or_equal: 0
+      max_instances:
+        type: integer
+        default: -1
+        constraints:
+          - greater_or_equal: -1

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/extensions/aria_extension_tosca/simple_v1_0/assignments.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/assignments.py b/extensions/aria_extension_tosca/simple_v1_0/assignments.py
index 79f6377..f7160b2 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/assignments.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/assignments.py
@@ -32,6 +32,7 @@ from .presentation.field_validators import (node_template_or_type_validator,
 from .presentation.types import (convert_shorthand_to_full_type_name,
                                  get_type_by_full_or_shorthand_name)
 
+
 @implements_specification('3.5.9', 'tosca-simple-1.0')
 class PropertyAssignment(AsIsPresentation):
     """
@@ -43,6 +44,7 @@ class PropertyAssignment(AsIsPresentation):
     #DEFN_ELEMENT_PROPERTY_VALUE_ASSIGNMENT>`__
     """
 
+
 @short_form_field('implementation')
 @has_fields
 @implements_specification('3.5.13-2', 'tosca-simple-1.0')
@@ -103,6 +105,7 @@ class OperationAssignment(ExtensiblePresentation):
             extensions.update(self._extensions)
         return extensions
 
+
 @allow_unknown_fields
 @has_fields
 @implements_specification('3.5.14-2', 'tosca-simple-1.0')
@@ -154,6 +157,7 @@ class InterfaceAssignment(ExtensiblePresentation):
             for operation in self.operations.itervalues(): # pylint: disable=no-member
                 operation._validate(context)
 
+
 @short_form_field('type')
 @has_fields
 class RelationshipAssignment(ExtensiblePresentation):
@@ -198,6 +202,7 @@ class RelationshipAssignment(ExtensiblePresentation):
                 return the_type, 'relationship_type'
         return None, None
 
+
 @short_form_field('node')
 @has_fields
 @implements_specification('3.7.2', 'tosca-simple-1.0')
@@ -297,6 +302,7 @@ class RequirementAssignment(ExtensiblePresentation):
 
         return None, None
 
+
 @implements_specification('3.5.11', 'tosca-simple-1.0')
 class AttributeAssignment(AsIsPresentation):
     """
@@ -308,6 +314,7 @@ class AttributeAssignment(AsIsPresentation):
     #DEFN_ELEMENT_ATTRIBUTE_VALUE_ASSIGNMENT>`__
     """
 
+
 @has_fields
 @implements_specification('3.7.1', 'tosca-simple-1.0')
 class CapabilityAssignment(ExtensiblePresentation):
@@ -350,6 +357,7 @@ class CapabilityAssignment(ExtensiblePresentation):
         return capability_definition._get_type(context) \
             if capability_definition is not None else None
 
+
 @has_fields
 @implements_specification('3.5.6', 'tosca-simple-1.0')
 class ArtifactAssignment(ExtensiblePresentation):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/extensions/aria_extension_tosca/simple_v1_0/data_types.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/data_types.py b/extensions/aria_extension_tosca/simple_v1_0/data_types.py
index c385f78..513b517 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/data_types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/data_types.py
@@ -14,14 +14,14 @@
 # limitations under the License.
 
 import re
-from datetime import datetime, tzinfo, timedelta
+from datetime import (datetime, tzinfo, timedelta)
 try:
     from functools import total_ordering
 except ImportError:
     from total_ordering import total_ordering
 
 from aria.parser import implements_specification
-from aria.utils.collections import StrictDict, OrderedDict
+from aria.utils.collections import (StrictDict, OrderedDict)
 from aria.utils.formatting import safe_repr
 
 from .modeling.data_types import (coerce_to_data_type_class, report_issue_for_bad_format,
@@ -48,8 +48,10 @@ class Timezone(tzinfo):
 
     _ZERO = timedelta(0)
 
+
 UTC = Timezone()
 
+
 @total_ordering
 @implements_specification('timestamp', 'yaml-1.1')
 class Timestamp(object):
@@ -145,6 +147,7 @@ class Timestamp(object):
     def _fraction_as_str(the_datetime):
         return '{0:g}'.format(the_datetime.microsecond / 1000000.0).lstrip('0')
 
+
 @total_ordering
 @implements_specification('3.2.2', 'tosca-simple-1.0')
 class Version(object):
@@ -229,6 +232,7 @@ class Version(object):
                             return True
         return False
 
+
 @implements_specification('3.2.3', 'tosca-simple-1.0')
 class Range(object):
     """
@@ -276,6 +280,7 @@ class Range(object):
     def as_raw(self):
         return list(self.value)
 
+
 @implements_specification('3.2.4', 'tosca-simple-1.0')
 class List(list):
     """
@@ -309,6 +314,7 @@ class List(list):
     def as_raw(self):
         return list(self)
 
+
 @implements_specification('3.2.5', 'tosca-simple-1.0')
 class Map(StrictDict):
     """
@@ -348,6 +354,7 @@ class Map(StrictDict):
     def as_raw(self):
         return OrderedDict(self)
 
+
 @total_ordering
 @implements_specification('3.2.6', 'tosca-simple-1.0')
 class Scalar(object):
@@ -416,6 +423,7 @@ class Scalar(object):
             value = self.TYPE(scalar) # pylint: disable=no-member
         return self.value < value
 
+
 @implements_specification('3.2.6.4', 'tosca-simple-1.0')
 class ScalarSize(Scalar):
     """
@@ -444,6 +452,7 @@ class ScalarSize(Scalar):
     TYPE = int
     UNIT = 'bytes'
 
+
 @implements_specification('3.2.6.5', 'tosca-simple-1.0')
 class ScalarTime(Scalar):
     """
@@ -469,6 +478,7 @@ class ScalarTime(Scalar):
     TYPE = float
     UNIT = 'seconds'
 
+
 @implements_specification('3.2.6.6', 'tosca-simple-1.0')
 class ScalarFrequency(Scalar):
     """
@@ -491,6 +501,7 @@ class ScalarFrequency(Scalar):
     TYPE = float
     UNIT = 'Hz'
 
+
 #
 # The following are hooked in the YAML as 'coerce_value' extensions
 #
@@ -499,10 +510,12 @@ def coerce_timestamp(context, presentation, the_type, entry_schema, constraints,
     return coerce_to_data_type_class(context, presentation, Timestamp, entry_schema, constraints,
                                      value, aspect)
 
+
 def coerce_version(context, presentation, the_type, entry_schema, constraints, value, aspect): # pylint: disable=unused-argument
     return coerce_to_data_type_class(context, presentation, Version, entry_schema, constraints,
                                      value, aspect)
 
+
 def coerce_range(context, presentation, the_type, entry_schema, constraints, value, aspect):
     if aspect == 'in_range':
         # When we're in a "in_range" constraint, the values are *not* themselves ranges, but numbers
@@ -516,24 +529,29 @@ def coerce_range(context, presentation, the_type, entry_schema, constraints, val
         return coerce_to_data_type_class(context, presentation, Range, entry_schema, constraints,
                                          value, aspect)
 
+
 def coerce_list(context, presentation, the_type, entry_schema, constraints, value, aspect): # pylint: disable=unused-argument
     return coerce_to_data_type_class(context, presentation, List, entry_schema, constraints,
                                      value, aspect)
 
+
 def coerce_map_value(context, presentation, the_type, entry_schema, constraints, value, aspect): # pylint: disable=unused-argument
     return coerce_to_data_type_class(context, presentation, Map, entry_schema, constraints, value,
                                      aspect)
 
+
 def coerce_scalar_unit_size(context, presentation, the_type, entry_schema, constraints, value, # pylint: disable=unused-argument
                             aspect):
     return coerce_to_data_type_class(context, presentation, ScalarSize, entry_schema, constraints,
                                      value, aspect)
 
+
 def coerce_scalar_unit_time(context, presentation, the_type, entry_schema, constraints, value, # pylint: disable=unused-argument
                             aspect):
     return coerce_to_data_type_class(context, presentation, ScalarTime, entry_schema, constraints,
                                      value, aspect)
 
+
 def coerce_scalar_unit_frequency(context, presentation, the_type, entry_schema, constraints, value, # pylint: disable=unused-argument
                                  aspect):
     return coerce_to_data_type_class(context, presentation, ScalarFrequency, entry_schema,

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/extensions/aria_extension_tosca/simple_v1_0/definitions.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/definitions.py b/extensions/aria_extension_tosca/simple_v1_0/definitions.py
index 8564249..9519586 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/definitions.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/definitions.py
@@ -34,6 +34,7 @@ from .modeling.data_types import get_data_type, get_property_constraints
 from .modeling.interfaces import (get_and_override_input_definitions_from_type,
                                   get_and_override_operation_definitions_from_type)
 
+
 @has_fields
 @implements_specification('3.5.8', 'tosca-simple-1.0')
 class PropertyDefinition(ExtensiblePresentation):
@@ -120,6 +121,7 @@ class PropertyDefinition(ExtensiblePresentation):
     def _get_constraints(self, context):
         return get_property_constraints(context, self)
 
+
 @has_fields
 @implements_specification('3.5.10', 'tosca-simple-1.0')
 class AttributeDefinition(ExtensiblePresentation):
@@ -189,6 +191,7 @@ class AttributeDefinition(ExtensiblePresentation):
     def _get_type(self, context):
         return get_data_type(context, self, 'type')
 
+
 @has_fields
 @implements_specification('3.5.12', 'tosca-simple-1.0')
 class ParameterDefinition(PropertyDefinition):
@@ -223,6 +226,7 @@ class ParameterDefinition(PropertyDefinition):
         as the result from the evaluation of an expression or a function.
         """
 
+
 @short_form_field('implementation')
 @has_fields
 @implements_specification('3.5.13-1', 'tosca-simple-1.0')
@@ -264,6 +268,7 @@ class OperationDefinition(ExtensiblePresentation):
         :rtype: dict of str, :class:`PropertyDefinition`
         """
 
+
 @allow_unknown_fields
 @has_fields
 @implements_specification('3.5.14-1', 'tosca-simple-1.0')
@@ -322,6 +327,7 @@ class InterfaceDefinition(ExtensiblePresentation):
             for operation in self.operations.itervalues(): # pylint: disable=no-member
                 operation._validate(context)
 
+
 @short_form_field('type')
 @has_fields
 class RelationshipDefinition(ExtensiblePresentation):
@@ -350,6 +356,7 @@ class RelationshipDefinition(ExtensiblePresentation):
     def _get_type(self, context):
         return get_type_by_full_or_shorthand_name(context, self.type, 'relationship_types')
 
+
 @short_form_field('capability')
 @has_fields
 @implements_specification('3.6.2', 'tosca-simple-1.0')
@@ -416,6 +423,7 @@ class RequirementDefinition(ExtensiblePresentation):
     def _get_node_type(self, context):
         return context.presentation.get_from_dict('service_template', 'node_types', self.node)
 
+
 @short_form_field('type')
 @has_fields
 @implements_specification('3.6.1', 'tosca-simple-1.0')

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/extensions/aria_extension_tosca/simple_v1_0/filters.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/filters.py b/extensions/aria_extension_tosca/simple_v1_0/filters.py
index 838b505..889acdf 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/filters.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/filters.py
@@ -22,6 +22,7 @@ from .presentation.extensible import ExtensiblePresentation
 from .presentation.field_validators import (node_filter_properties_validator,
                                             node_filter_capabilities_validator)
 
+
 @has_fields
 class CapabilityFilter(ExtensiblePresentation):
     @object_sequenced_list_field(ConstraintClause)
@@ -44,6 +45,7 @@ class CapabilityFilter(ExtensiblePresentation):
 
         return None
 
+
 @has_fields
 @implements_specification('3.5.4', 'tosca-simple-1.0')
 class NodeFilter(ExtensiblePresentation):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/extensions/aria_extension_tosca/simple_v1_0/misc.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/misc.py b/extensions/aria_extension_tosca/simple_v1_0/misc.py
index 74eba18..d276813 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/misc.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/misc.py
@@ -36,6 +36,7 @@ from .presentation.field_validators import (constraint_clause_field_validator,
 from .presentation.types import (convert_shorthand_to_full_type_name,
                                  get_type_by_full_or_shorthand_name)
 
+
 @implements_specification('3.5.1', 'tosca-simple-1.0')
 class Description(AsIsPresentation):
     """
@@ -51,6 +52,7 @@ class Description(AsIsPresentation):
         value = as_raw(self.value)
         puts(context.style.meta(value))
 
+
 @allow_unknown_fields
 @has_fields
 @implements_specification('3.9.3.2', 'tosca-simple-1.0')
@@ -85,6 +87,7 @@ class MetaData(ExtensiblePresentation):
         :rtype: dict
         """
 
+
 @short_form_field('url')
 @has_fields
 @implements_specification('3.5.5', 'tosca-simple-1.0')
@@ -126,6 +129,7 @@ class Repository(ExtensiblePresentation):
     def _get_credential(self, context):
         return get_data_type_value(context, self, 'credential', 'tosca.datatypes.Credential')
 
+
 @short_form_field('file')
 @has_fields
 @implements_specification('3.5.7', 'tosca-simple-1.0')
@@ -176,6 +180,7 @@ class Import(ExtensiblePresentation):
         :rtype: str
         """
 
+
 @has_fields
 @implements_specification('3.5.2-1', 'tosca-simple-1.0')
 class ConstraintClause(ExtensiblePresentation):
@@ -288,6 +293,7 @@ class ConstraintClause(ExtensiblePresentation):
     def _apply_to_value(self, context, presentation, value):
         return apply_constraint_to_value(context, presentation, self, value)
 
+
 @short_form_field('type')
 @has_fields
 class EntrySchema(ExtensiblePresentation):
@@ -323,6 +329,7 @@ class EntrySchema(ExtensiblePresentation):
     def _get_constraints(self, context):
         return get_property_constraints(context, self)
 
+
 @short_form_field('primary')
 @has_fields
 class OperationImplementation(ExtensiblePresentation):
@@ -345,6 +352,7 @@ class OperationImplementation(ExtensiblePresentation):
         :rtype: list of str
         """
 
+
 class SubstitutionMappingsRequirement(AsIsPresentation):
     @property
     @cachedmethod
@@ -360,6 +368,7 @@ class SubstitutionMappingsRequirement(AsIsPresentation):
         super(SubstitutionMappingsRequirement, self)._validate(context)
         validate_subtitution_mappings_requirement(context, self)
 
+
 class SubstitutionMappingsCapability(AsIsPresentation):
     @property
     @cachedmethod
@@ -375,6 +384,7 @@ class SubstitutionMappingsCapability(AsIsPresentation):
         super(SubstitutionMappingsCapability, self)._validate(context)
         validate_subtitution_mappings_capability(context, self)
 
+
 @has_fields
 @implements_specification('2.10', 'tosca-simple-1.0')
 class SubstitutionMappings(ExtensiblePresentation):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
index 5813ccf..bff508c 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
@@ -168,9 +168,6 @@ def create_node_template_model(context, service_template, node_template):
     model = NodeTemplate(name=node_template._name,
                          type=node_type)
 
-    model.default_instances = 1
-    model.min_instances = 0
-
     if node_template.description:
         model.description = node_template.description.value
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py b/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py
index a2fd6ee..3c03213 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py
@@ -16,6 +16,7 @@
 from aria.utils.caching import cachedmethod
 from aria.parser.presentation import (Presentation, has_fields, primitive_dict_field)
 
+
 @has_fields
 class ExtensiblePresentation(Presentation):
     """

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py b/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py
index d7b03ae..e5ecfa7 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py
@@ -24,6 +24,7 @@ from ..modeling.data_types import (get_primitive_data_type, get_data_type_name,
                                    get_container_data_type)
 from .types import get_type_by_full_or_shorthand_name, convert_shorthand_to_full_type_name
 
+
 #
 # NodeTemplate, RelationshipTemplate
 #
@@ -56,6 +57,7 @@ def copy_validator(template_type_name, templates_dict_name):
 
     return validator_fn
 
+
 #
 # PropertyDefinition, AttributeDefinition, ParameterDefinition, EntrySchema
 #
@@ -97,6 +99,7 @@ def data_type_validator(type_name='data type'):
 
     return validator
 
+
 #
 # PropertyDefinition, AttributeDefinition
 #
@@ -141,6 +144,7 @@ def entry_schema_validator(field, presentation, context):
                 % (get_data_type_name(the_type), presentation._container._fullname),
                 locator=presentation._locator, level=Issue.BETWEEN_TYPES)
 
+
 def data_value_validator(field, presentation, context):
     """
     Makes sure that the field contains a valid value according to data type and constraints.
@@ -160,6 +164,7 @@ def data_value_validator(field, presentation, context):
             if hasattr(presentation, '_get_constraints') else None
         coerce_value(context, presentation, the_type, entry_schema, constraints, value, field.name)
 
+
 #
 # DataType
 #
@@ -168,6 +173,7 @@ _data_type_validator = data_type_validator()
 _data_type_derived_from_validator = derived_from_validator(convert_shorthand_to_full_type_name,
                                                            'data_types')
 
+
 def data_type_derived_from_validator(field, presentation, context):
     """
     Makes sure that the field refers to a valid parent data type (complex or primitive).
@@ -181,6 +187,7 @@ def data_type_derived_from_validator(field, presentation, context):
         # hierarchy)
         _data_type_derived_from_validator(field, presentation, context)
 
+
 def data_type_constraints_validator(field, presentation, context):
     """
     Makes sure that we do not have constraints if we are a complex type (with no primitive
@@ -197,6 +204,7 @@ def data_type_constraints_validator(field, presentation, context):
                 % presentation._fullname,
                 locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_TYPES)
 
+
 def data_type_properties_validator(field, presentation, context):
     """
     Makes sure that we do not have properties if we have a primitive ancestor.
@@ -215,6 +223,7 @@ def data_type_properties_validator(field, presentation, context):
                 % presentation._fullname,
                 locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_TYPES)
 
+
 #
 # ConstraintClause
 #
@@ -235,6 +244,7 @@ def constraint_clause_field_validator(field, presentation, context):
             if hasattr(the_type, '_get_constraints') else None
         coerce_value(context, presentation, the_type, None, constraints, value, field.name)
 
+
 def constraint_clause_in_range_validator(field, presentation, context):
     """
     Makes sure that the value is a list with exactly two elements, that both lower bound contains a
@@ -274,6 +284,7 @@ def constraint_clause_in_range_validator(field, presentation, context):
                 % (field.name, presentation._fullname),
                 locator=presentation._get_child_locator(field.name), level=Issue.FIELD)
 
+
 def constraint_clause_valid_values_validator(field, presentation, context):
     """
     Makes sure that the value is a list of valid values for the container type.
@@ -290,6 +301,7 @@ def constraint_clause_valid_values_validator(field, presentation, context):
         for value in values:
             coerce_value(context, presentation, the_type, None, None, value, field.name)
 
+
 def constraint_clause_pattern_validator(field, presentation, context):
     """
     Makes sure that the value is a valid regular expression.
@@ -316,6 +328,7 @@ def constraint_clause_pattern_validator(field, presentation, context):
                 % (field.name, presentation._fullname),
                 locator=presentation._get_child_locator(field.name), level=Issue.FIELD, exception=e)
 
+
 #
 # RequirementAssignment
 #
@@ -340,6 +353,7 @@ def node_template_or_type_validator(field, presentation, context):
             report_issue_for_unknown_type(context, presentation, 'node template or node type',
                                           field.name)
 
+
 def capability_definition_or_type_validator(field, presentation, context):
     """
     Makes sure refers to either a capability assignment name in the node template referred to by the
@@ -381,6 +395,7 @@ def capability_definition_or_type_validator(field, presentation, context):
                 % (presentation._name, presentation._container._fullname, safe_repr(value)),
                 locator=presentation._get_child_locator(field.name), level=Issue.BETWEEN_TYPES)
 
+
 def node_filter_validator(field, presentation, context):
     """
     Makes sure that the field has a value only if "node" refers to a node type.
@@ -401,6 +416,7 @@ def node_filter_validator(field, presentation, context):
                 % (presentation._fullname, presentation._container._fullname),
                 locator=presentation._locator, level=Issue.BETWEEN_FIELDS)
 
+
 #
 # RelationshipAssignment
 #
@@ -426,6 +442,7 @@ def relationship_template_or_type_validator(field, presentation, context):
             report_issue_for_unknown_type(context, presentation,
                                           'relationship template or relationship type', field.name)
 
+
 #
 # PolicyType
 #
@@ -449,6 +466,7 @@ def list_node_type_or_group_type_validator(field, presentation, context):
                 report_issue_for_unknown_type(context, presentation, 'node type or group type',
                                               field.name, value)
 
+
 #
 # PolicyTemplate
 #
@@ -506,6 +524,7 @@ def policy_targets_validator(field, presentation, context):
                     % (presentation._name, safe_repr(value)),
                     locator=presentation._locator, level=Issue.BETWEEN_TYPES)
 
+
 #
 # NodeFilter
 #
@@ -532,6 +551,7 @@ def node_filter_properties_validator(field, presentation, context):
                         % (node_type._name, name),
                         locator=presentation._locator, level=Issue.BETWEEN_TYPES)
 
+
 def node_filter_capabilities_validator(field, presentation, context):
     """
     Makes sure that the field's elements refer to defined capabilities and properties in the target

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py b/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
index 088a246..e34405d 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
@@ -13,6 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+
 def convert_shorthand_to_full_type_name(context, name, types_dict): # pylint: disable=unused-argument
     """
     Converts a shorthand type name to its full type name, or else returns it unchanged.
@@ -31,6 +32,7 @@ def convert_shorthand_to_full_type_name(context, name, types_dict): # pylint: di
                 return full_name
     return name
 
+
 def get_type_by_full_or_shorthand_name(context, name, *types_dict_names):
     """
     Gets a type either by its full name or its shorthand name.

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/extensions/aria_extension_tosca/simple_v1_0/presenter.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/presenter.py b/extensions/aria_extension_tosca/simple_v1_0/presenter.py
index f64078f..92e37d9 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/presenter.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/presenter.py
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from aria.utils.collections import FrozenList, EMPTY_READ_ONLY_LIST
+from aria.utils.collections import (FrozenList, EMPTY_READ_ONLY_LIST)
 from aria.utils.caching import cachedmethod
 from aria.parser.presentation import Presenter
 
@@ -22,6 +22,7 @@ from .modeling.functions import (Concat, Token, GetInput, GetProperty, GetAttrib
                                  GetOperationOutput, GetNodesOfType, GetArtifact)
 from .templates import ServiceTemplate
 
+
 class ToscaSimplePresenter1_0(Presenter): # pylint: disable=invalid-name,abstract-method
     """
     ARIA presenter for the `TOSCA Simple Profile v1.0 cos01 <http://docs.oasis-open.org/tosca

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/extensions/aria_extension_tosca/simple_v1_0/templates.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/templates.py b/extensions/aria_extension_tosca/simple_v1_0/templates.py
index 123a00e..6f61a39 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/templates.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/templates.py
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from aria.utils.collections import FrozenDict, FrozenList
+from aria.utils.collections import (FrozenDict, FrozenList)
 from aria.utils.caching import cachedmethod
 from aria.parser import implements_specification
 from aria.parser.presentation import (has_fields, primitive_field, primitive_list_field,
@@ -40,6 +40,7 @@ from .presentation.types import (convert_shorthand_to_full_type_name,
 from .types import (ArtifactType, DataType, CapabilityType, InterfaceType, RelationshipType,
                     NodeType, GroupType, PolicyType)
 
+
 @has_fields
 @implements_specification('3.7.3', 'tosca-simple-1.0')
 class NodeTemplate(ExtensiblePresentation):
@@ -201,6 +202,7 @@ class NodeTemplate(ExtensiblePresentation):
             'node_filter',
             'copy'))
 
+
 @has_fields
 @implements_specification('3.7.4', 'tosca-simple-1.0')
 class RelationshipTemplate(ExtensiblePresentation):
@@ -300,6 +302,7 @@ class RelationshipTemplate(ExtensiblePresentation):
             'interfaces',
             'copy'))
 
+
 @has_fields
 @implements_specification('3.7.5', 'tosca-simple-1.0')
 class GroupTemplate(ExtensiblePresentation):
@@ -373,6 +376,7 @@ class GroupTemplate(ExtensiblePresentation):
         self._get_property_values(context)
         self._get_interfaces(context)
 
+
 @has_fields
 @implements_specification('3.7.6', 'tosca-simple-1.0')
 class PolicyTemplate(ExtensiblePresentation):
@@ -437,6 +441,7 @@ class PolicyTemplate(ExtensiblePresentation):
         super(PolicyTemplate, self)._validate(context)
         self._get_property_values(context)
 
+
 @has_fields
 @implements_specification('3.8', 'tosca-simple-1.0')
 class TopologyTemplate(ExtensiblePresentation):
@@ -547,6 +552,7 @@ class TopologyTemplate(ExtensiblePresentation):
             'outputs',
             'substitution_mappings'))
 
+
 @has_fields
 @implements_specification('3.9', 'tosca-simple-1.0')
 class ServiceTemplate(ExtensiblePresentation):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/extensions/aria_extension_tosca/simple_v1_0/types.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/types.py b/extensions/aria_extension_tosca/simple_v1_0/types.py
index d97b89c..7c1008f 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/types.py
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from aria.utils.collections import FrozenDict, FrozenList
+from aria.utils.collections import (FrozenDict, FrozenList)
 from aria.utils.caching import cachedmethod
 from aria.parser import implements_specification
 from aria.parser.presentation import (has_fields, allow_unknown_fields, primitive_field,
@@ -45,6 +45,7 @@ from .presentation.field_validators import (data_type_derived_from_validator,
                                             list_node_type_or_group_type_validator)
 from .presentation.types import convert_shorthand_to_full_type_name
 
+
 @has_fields
 @implements_specification('3.6.3', 'tosca-simple-1.0')
 class ArtifactType(ExtensiblePresentation):
@@ -130,6 +131,7 @@ class ArtifactType(ExtensiblePresentation):
             'file_ext',
             'properties'))
 
+
 @has_fields
 @implements_specification('3.6.5', 'tosca-simple-1.0')
 class DataType(ExtensiblePresentation):
@@ -224,6 +226,7 @@ class DataType(ExtensiblePresentation):
             'constraints',
             'properties'))
 
+
 @has_fields
 @implements_specification('3.6.6', 'tosca-simple-1.0')
 class CapabilityType(ExtensiblePresentation):
@@ -326,6 +329,7 @@ class CapabilityType(ExtensiblePresentation):
             'properties',
             'attributes'))
 
+
 @allow_unknown_fields
 @has_fields
 @implements_specification('3.6.4', 'tosca-simple-1.0')
@@ -405,6 +409,7 @@ class InterfaceType(ExtensiblePresentation):
             'inputs',
             'operations'))
 
+
 @has_fields
 @implements_specification('3.6.9', 'tosca-simple-1.0')
 class RelationshipType(ExtensiblePresentation):
@@ -519,6 +524,7 @@ class RelationshipType(ExtensiblePresentation):
             'attributes',
             'interfaces'))
 
+
 @has_fields
 @implements_specification('3.6.8', 'tosca-simple-1.0')
 class NodeType(ExtensiblePresentation):
@@ -667,6 +673,7 @@ class NodeType(ExtensiblePresentation):
             'requirements',
             'capabilities'))
 
+
 @has_fields
 @implements_specification('3.6.10', 'tosca-simple-1.0')
 class GroupType(ExtensiblePresentation):
@@ -780,6 +787,7 @@ class GroupType(ExtensiblePresentation):
             'properties',
             'interfaces'))
 
+
 @has_fields
 @implements_specification('3.6.11', 'tosca-simple-1.0')
 class PolicyType(ExtensiblePresentation):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/tests/end2end/test_hello_world.py
----------------------------------------------------------------------
diff --git a/tests/end2end/test_hello_world.py b/tests/end2end/test_hello_world.py
index b55b9a8..5e4d7fd 100644
--- a/tests/end2end/test_hello_world.py
+++ b/tests/end2end/test_hello_world.py
@@ -57,5 +57,5 @@ def _verify_deployed_service_in_storage(service_name, model_storage):
     assert len(service.executions) == 1
     assert len(service.nodes) == 2
     assert service.outputs['port'].value == 9090
-    assert all(node.state == node.STARTED for node in service.nodes.values())
+    assert all(node.state == node.STARTED for node in service.nodes.itervalues())
     assert len(service.executions[0].logs) > 0

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/tests/end2end/test_nodecellar.py
----------------------------------------------------------------------
diff --git a/tests/end2end/test_nodecellar.py b/tests/end2end/test_nodecellar.py
index f02441f..a2b6797 100644
--- a/tests/end2end/test_nodecellar.py
+++ b/tests/end2end/test_nodecellar.py
@@ -39,4 +39,4 @@ def _verify_deployed_service_in_storage(service_name, model_storage):
     service = service_templates[0].services[service_name]
     assert service.name == service_name
     assert len(service.executions) == 0  # dry executions leave no traces
-    assert len(service.nodes) == 10
+    assert len(service.nodes) == 13

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/tests/mock/models.py
----------------------------------------------------------------------
diff --git a/tests/mock/models.py b/tests/mock/models.py
index 7f6bbea..5ff567a 100644
--- a/tests/mock/models.py
+++ b/tests/mock/models.py
@@ -133,10 +133,7 @@ def create_node_template(service_template,
                          type=models.Type(variant='node', name='test_node_type'),
                          capability_templates=None,
                          requirement_templates=None,
-                         interface_templates=None,
-                         default_instances=1,
-                         min_instances=1,
-                         max_instances=1):
+                         interface_templates=None):
     capability_templates = capability_templates or {}
     requirement_templates = requirement_templates or []
     interface_templates = interface_templates or {}
@@ -146,9 +143,6 @@ def create_node_template(service_template,
         capability_templates=capability_templates,
         requirement_templates=requirement_templates,
         interface_templates=interface_templates,
-        default_instances=default_instances,
-        min_instances=min_instances,
-        max_instances=max_instances,
         service_template=service_template)
 
     service_template.node_templates[node_template.name] = node_template

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/tests/modeling/test_mixins.py
----------------------------------------------------------------------
diff --git a/tests/modeling/test_mixins.py b/tests/modeling/test_mixins.py
index 2c91a4b..2d94d7c 100644
--- a/tests/modeling/test_mixins.py
+++ b/tests/modeling/test_mixins.py
@@ -112,9 +112,6 @@ def test_relationship_model_ordering(context):
     new_node_template = modeling.models.NodeTemplate(
         name='new_node_template',
         type=source_node.type,
-        default_instances=1,
-        min_instances=1,
-        max_instances=1,
         service_template=service.service_template
     )
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/tests/modeling/test_models.py
----------------------------------------------------------------------
diff --git a/tests/modeling/test_models.py b/tests/modeling/test_models.py
index 464f432..0ebed97 100644
--- a/tests/modeling/test_models.py
+++ b/tests/modeling/test_models.py
@@ -510,19 +510,15 @@ class TestServiceModification(object):
 
 class TestNodeTemplate(object):
     @pytest.mark.parametrize(
-        'is_valid, name, default_instances, max_instances, min_instances, properties',
+        'is_valid, name, properties',
         [
-            (False, m_cls, 1, 1, 1, {}),
-            (False, 'name', m_cls, 1, 1, {}),
-            (False, 'name', 1, m_cls, 1, {}),
-            (False, 'name', 1, 1, m_cls, {}),
-            (False, 'name', 1, 1, 1, m_cls),
+            (False, m_cls, {}),
+            (False, 'name', m_cls),
 
-            (True, 'name', 1, 1, 1, {}),
+            (True, 'name', {}),
         ]
     )
-    def test_node_template_model_creation(self, service_storage, is_valid, name, default_instances,
-                                          max_instances, min_instances, properties):
+    def test_node_template_model_creation(self, service_storage, is_valid, name, properties):
         node_template = _test_model(
             is_valid=is_valid,
             storage=service_storage,
@@ -530,9 +526,6 @@ class TestNodeTemplate(object):
             model_kwargs=dict(
                 name=name,
                 type=service_storage.type.list()[0],
-                default_instances=default_instances,
-                max_instances=max_instances,
-                min_instances=min_instances,
                 properties=properties,
                 service_template=service_storage.service_template.list()[0]
             ))
@@ -621,9 +614,6 @@ class TestNodeHostAddress(object):
         kwargs = dict(
             name='node_template',
             type=storage.type.list()[0],
-            default_instances=1,
-            max_instances=1,
-            min_instances=1,
             service_template=storage.service_template.list()[0]
         )
         if host_address:

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/tests/orchestrator/context/test_operation.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/context/test_operation.py b/tests/orchestrator/context/test_operation.py
index 3dcfaa2..91ac6bb 100644
--- a/tests/orchestrator/context/test_operation.py
+++ b/tests/orchestrator/context/test_operation.py
@@ -476,7 +476,7 @@ def operation_common(ctx, holder):
     holder['actor_name'] = ctx.task.actor.name
     holder['task_name'] = ctx.task.name
     holder['function'] = ctx.task.function
-    holder['arguments'] = dict(i.unwrapped for i in ctx.task.arguments.values())
+    holder['arguments'] = dict(i.unwrapped for i in ctx.task.arguments.itervalues())
 
 
 @operation

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
----------------------------------------------------------------------
diff --git a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
index a34301c..e130b13 100644
--- a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
+++ b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
@@ -277,6 +277,7 @@ topology_template:
       type: openstack.Scaling
       properties:
         bandwidth_threshold: 2 GB
+        default_instances: 2
       targets: # node templates or groups
         - node_cellar_group
     

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b7ec71e6/tests/resources/service-templates/tosca-simple-1.0/node-cellar/types/openstack.yaml
----------------------------------------------------------------------
diff --git a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/types/openstack.yaml b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/types/openstack.yaml
index de5fb47..99ee902 100644
--- a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/types/openstack.yaml
+++ b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/types/openstack.yaml
@@ -15,6 +15,7 @@
 
 imports:
   - os.yaml
+  - aria-1.0
 
 dsl_definitions:
 
@@ -169,7 +170,7 @@ policy_types:
   openstack.Scaling:
     description: >-
       OpenStack scaling policy.
-    derived_from: tosca.policies.Scaling
+    derived_from: aria.Scaling
     properties:
       bandwidth_threshold:
         type: scalar-unit.size


[07/10] incubator-ariatosca git commit: wip

Posted by em...@apache.org.
wip


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/ba4460e2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/ba4460e2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/ba4460e2

Branch: refs/heads/ARIA-254-multiple-nodes-per-template
Commit: ba4460e2cefce13536114b0b5ad6072da5281dc5
Parents: b7ec71e
Author: Tal Liron <ta...@gmail.com>
Authored: Tue Jun 13 14:50:17 2017 -0500
Committer: Tal Liron <ta...@gmail.com>
Committed: Fri Jun 16 17:27:32 2017 -0500

----------------------------------------------------------------------
 aria/modeling/service_template.py               | 62 +++++++++++++++-----
 aria/parser/presentation/presentation.py        | 12 +++-
 .../profiles/aria-1.0/aria-1.0.yaml             | 23 ++++++--
 .../profiles/tosca-simple-1.0/capabilities.yaml |  1 +
 .../simple_v1_0/modeling/capabilities.py        | 15 +++--
 .../node-cellar/node-cellar.yaml                | 20 ++++---
 6 files changed, 99 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/ba4460e2/aria/modeling/service_template.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py
index dfef8d6..c9c7c6c 100644
--- a/aria/modeling/service_template.py
+++ b/aria/modeling/service_template.py
@@ -305,7 +305,8 @@ class ServiceTemplateBase(TemplateModelMixin):
         utils.instantiate_dict(self, service.meta_data, self.meta_data)
 
         for node_template in self.node_templates.itervalues():
-            for _ in range(node_template.default_instances):
+            print 'scaling', node_template.name, node_template.scaling['default_instances'] 
+            for _ in range(node_template.scaling['default_instances']):
                 node = node_template.instantiate(container)
                 service.nodes[node.name] = node
 
@@ -581,12 +582,6 @@ class NodeTemplateBase(TemplateModelMixin):
             console.puts(context.style.meta(self.description))
         with context.style.indent:
             console.puts('Type: {0}'.format(context.style.type(self.type.name)))
-            console.puts('Instances: {0:d} ({1:d}{2})'.format(
-                self.default_instances,
-                self.min_instances,
-                ' to {0:d}'.format(self.max_instances)
-                if self.max_instances is not None
-                else ' or more'))
             utils.dump_dict_values(self.properties, 'Properties')
             utils.dump_dict_values(self.attributes, 'Attributes')
             utils.dump_interfaces(self.interface_templates)
@@ -620,18 +615,53 @@ class NodeTemplateBase(TemplateModelMixin):
         return '{name}_{index}'.format(name=self.name, index=self.next_index)
 
     @property
-    def default_instances(self):
-        # TODO: currently finds the first matching policy; but we should emit a validation error
-        # if more than one policy applies to the same node
+    def scaling(self):
+        scaling = {
+           'min_instances': 0,
+           'max_instances': 1,
+           'default_instances': 1}
+
+        def extract_property(properties, name):
+            prop = properties.get(name)
+            if (prop is not None) and (prop.type_name == 'integer') and (prop.value is not None):
+                scaling[name] = prop.value
+
+        def extract_properties(properties):
+            extract_property(properties, 'min_instances')
+            extract_property(properties, 'max_instances')
+            extract_property(properties, 'default_instances')
+
+        # TODO: currently finds the first matches capability or policy; but we should emit a
+        # validation error if more than one applies to the same node
+
+        # From our scaling capabilities
+        for capability_template in self.capability_templates.itervalues():
+            if capability_template.type.role == 'scaling':
+                extract_properties(capability_template.properties)
+
+        # From service scaling policies (will override capabilities)
         for policy_template in self.service_template.policy_templates.itervalues():
             if policy_template.type.role == 'scaling':
                 if policy_template.is_for_node_template(self.name):
-                    default_instances = policy_template.properties.get('default_instances')
-                    if (default_instances is not None) \
-                        and (default_instances.type_name == 'integer'):
-                        return default_instances.value
-                    break
-        return 1
+                    extract_properties(policy_template.properties)
+
+        # Validate
+        if (scaling['min_instances'] < 0) or \
+            (scaling['max_instances'] < 0) or \
+            (scaling['default_instances'] < 0) or \
+            (scaling['max_instances'] < scaling['min_instances']) or \
+            (scaling['default_instances'] < scaling['min_instances']) or \
+            (scaling['default_instances'] > scaling['max_instances']):
+            context = ConsumptionContext.get_thread_local()
+            context.validation.report('invalid scaling parameters for node template "{0}": '
+                                      'min={1}, max={2}, default={3}'.format(
+                                          self.name,
+                                          scaling['min_instances'],
+                                          scaling['max_instances'],
+                                          scaling['default_instances']),
+                                      level=validation.Issue.BETWEEN_TYPES)
+
+        return scaling
 
     def is_target_node_template_valid(self, target_node_template):
         """

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/ba4460e2/aria/parser/presentation/presentation.py
----------------------------------------------------------------------
diff --git a/aria/parser/presentation/presentation.py b/aria/parser/presentation/presentation.py
index 644d880..495c42c 100644
--- a/aria/parser/presentation/presentation.py
+++ b/aria/parser/presentation/presentation.py
@@ -34,6 +34,14 @@ class Value(object):
         self.value = deepcopy_with_locators(value)
         self.description = deepcopy_with_locators(description)
 
+    def _dump(self, context):
+        if self.type is not None:
+            puts(context.style.type(self.type))
+        if self.value is not None:
+            puts(context.style.literal(self.value))
+        if self.description is not None:
+            puts(context.style.meta(self.description))
+
 
 class PresentationBase(HasCachedMethods):
     """
@@ -234,6 +242,8 @@ class AsIsPresentation(PresentationBase):
 
     def _dump(self, context):
         if hasattr(self._raw, '_dump'):
-            self._raw._dump(context)
+            puts(context.style.node(self._name))
+            with context.style.indent:
+                self._raw._dump(context)
         else:
             super(AsIsPresentation, self)._dump(context)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/ba4460e2/extensions/aria_extension_tosca/profiles/aria-1.0/aria-1.0.yaml
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/profiles/aria-1.0/aria-1.0.yaml b/extensions/aria_extension_tosca/profiles/aria-1.0/aria-1.0.yaml
index 71d6e8e..d7b0c61 100644
--- a/extensions/aria_extension_tosca/profiles/aria-1.0/aria-1.0.yaml
+++ b/extensions/aria_extension_tosca/profiles/aria-1.0/aria-1.0.yaml
@@ -67,18 +67,29 @@ policy_types:
       Scaling.
     derived_from: tosca.policies.Scaling
     properties:
-      default_instances:
+      min_instances:
+        description: >-
+          This property is used to indicate the minimum number of instances that should be created
+          for the associated TOSCA Node Template by a TOSCA orchestrator.
         type: integer
         default: 1
         constraints:
           - greater_or_equal: 0
-      min_instances:
+      max_instances:
+        description: >-
+          This property is used to indicate the maximum number of instances that should be created
+          for the associated TOSCA Node Template by a TOSCA orchestrator.
         type: integer
-        default: 0
+        default: 1
         constraints:
           - greater_or_equal: 0
-      max_instances:
+      default_instances:
+        description: >-
+          An optional property that indicates the requested default number of instances that should
+          be the starting number of instances a TOSCA orchestrator should attempt to allocate. Note:
+          The value for this property MUST be in the range between the values set for
+          "min_instances" and "max_instances" properties.
         type: integer
-        default: -1
         constraints:
-          - greater_or_equal: -1
+          - greater_or_equal: 0
+        required: false

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/ba4460e2/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/capabilities.yaml
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/capabilities.yaml b/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/capabilities.yaml
index 30abe10..b705d47 100644
--- a/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/capabilities.yaml
+++ b/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/capabilities.yaml
@@ -132,6 +132,7 @@ capability_types:
       specification: tosca-simple-1.0
       specification_section: 5.4.10
       specification_url: 'http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#DEFN_TYPE_CAPABILITIES_SCALABLE'
+      role: scaling
     description: >-
       This is the default TOSCA type that should be used to express a scalability capability for a node.
     derived_from: tosca.capabilities.Root

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/ba4460e2/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
index a90a9fc..18a4541 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
@@ -71,8 +71,8 @@ def get_inherited_capability_definitions(context, presentation, for_presentation
                 type2 = our_capability_definition.type
                 if type1 != type2:
                     context.validation.report(
-                        'capability definition changes type from "%s" to "%s" in "%s"'
-                        % (type1, type2, presentation._fullname),
+                        'capability definition changes type from "{0}" to "{1}" in "{2}"'
+                        .format(type1, type2, presentation._fullname),
                         locator=our_capability_definition._locator, level=Issue.BETWEEN_TYPES)
 
                 # Already cloned?
@@ -133,12 +133,19 @@ def get_template_capabilities(context, presentation):
                 values = get_assigned_and_defined_parameter_values(context,
                                                                    our_capability_assignment,
                                                                    'property')
+
+                print presentation._name
+                print 'our', [(k, v.value) for k, v in our_capability_assignment.properties.iteritems()]
+                print 'ass', [(k, v.value.value) for k, v in capability_assignment.properties.iteritems()]
+                print 'val', [(k, v.value) for k, v in values.iteritems()]
+                
                 if values:
                     capability_assignment._raw['properties'] = values
+                    capability_assignment._reset_method_cache()
             else:
                 context.validation.report(
-                    'capability "%s" not declared at node type "%s" in "%s"'
-                    % (capability_name, presentation.type, presentation._fullname),
+                    'capability "{0}" not declared at node type "{1}" in "{2}"'
+                    .format(capability_name, presentation.type, presentation._fullname),
                     locator=our_capability_assignment._locator, level=Issue.BETWEEN_TYPES)
 
     return capability_assignments

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/ba4460e2/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
----------------------------------------------------------------------
diff --git a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
index e130b13..de57d3c 100644
--- a/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
+++ b/tests/resources/service-templates/tosca-simple-1.0/node-cellar/node-cellar.yaml
@@ -201,6 +201,11 @@ topology_template:
         os_users: # map of os.UserInfo
           root:
             password: admin123
+      capabilities:
+        scalable: # will be overriden by policy
+          properties:
+            max_instances: 5
+            default_instances: 3
       interfaces:
         Standard:
           inputs:
@@ -273,13 +278,14 @@ topology_template:
 
   policies:
   
-    scaling:
-      type: openstack.Scaling
-      properties:
-        bandwidth_threshold: 2 GB
-        default_instances: 2
-      targets: # node templates or groups
-        - node_cellar_group
+#    scaling:
+#      type: openstack.Scaling
+#      properties:
+#        bandwidth_threshold: 2 GB
+#        max_instances: 2
+#        default_instances: 2
+#      targets: # node templates or groups
+#        - node_cellar_group
     
     juju:
       description: >-


[09/10] incubator-ariatosca git commit: Temp

Posted by em...@apache.org.
Temp


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/334ea74e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/334ea74e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/334ea74e

Branch: refs/heads/ARIA-254-multiple-nodes-per-template
Commit: 334ea74e9829e5174103aab20145737879e2e09f
Parents: ba4460e
Author: Tal Liron <ta...@gmail.com>
Authored: Wed Jun 14 11:50:01 2017 -0500
Committer: Tal Liron <ta...@gmail.com>
Committed: Fri Jun 16 17:27:32 2017 -0500

----------------------------------------------------------------------
 aria/parser/presentation/fields.py                           | 4 ++++
 .../simple_v1_0/modeling/capabilities.py                     | 8 ++++++--
 2 files changed, 10 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/334ea74e/aria/parser/presentation/fields.py
----------------------------------------------------------------------
diff --git a/aria/parser/presentation/fields.py b/aria/parser/presentation/fields.py
index 7f85723..060c576 100644
--- a/aria/parser/presentation/fields.py
+++ b/aria/parser/presentation/fields.py
@@ -680,6 +680,10 @@ class Field(object):
     # object dict
 
     def _get_object_dict(self, presentation, raw, value, context):
+        if self.cls.__name__ == 'CapabilityAssignment':
+            print '>>>>>>>>>>p', presentation._name
+            print '>>>>>>>>>>v', value
+            print '>>>>>>>>>>r', raw
         if not isinstance(value, dict):
             raise InvalidValueError('%s is not a dict: %s' % (self.full_name, safe_repr(value)),
                                     locator=self.get_locator(raw))

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/334ea74e/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
index 18a4541..e61fc81 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
@@ -129,14 +129,18 @@ def get_template_capabilities(context, presentation):
             if capability_name in capability_assignments:
                 capability_assignment = capability_assignments[capability_name]
 
+                print
+                print presentation._name
+                print 'raw1', our_capability_assignment._raw
+                print 'raw2', presentation._raw['capabilities'][our_capability_assignment._name]
+
                 # Assign properties
                 values = get_assigned_and_defined_parameter_values(context,
                                                                    our_capability_assignment,
                                                                    'property')
 
-                print presentation._name
                 print 'our', [(k, v.value) for k, v in our_capability_assignment.properties.iteritems()]
-                print 'ass', [(k, v.value.value) for k, v in capability_assignment.properties.iteritems()]
+                print 'def', [(k, v.value.value) for k, v in capability_assignment.properties.iteritems()]
                 print 'val', [(k, v.value) for k, v in values.iteritems()]
                 
                 if values:


[03/10] incubator-ariatosca git commit: ARIA-166 Update README file

Posted by em...@apache.org.
ARIA-166 Update README file


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/22f6e9ef
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/22f6e9ef
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/22f6e9ef

Branch: refs/heads/ARIA-254-multiple-nodes-per-template
Commit: 22f6e9efd5300f33bee51a1c1622c22b1531bbf5
Parents: 5afa2f7
Author: Ran Ziv <ra...@gigaspaces.com>
Authored: Thu Jun 8 18:26:29 2017 +0300
Committer: Ran Ziv <ra...@gigaspaces.com>
Committed: Mon Jun 12 19:08:44 2017 +0300

----------------------------------------------------------------------
 README.md | 231 +++++++++++++++++++--------------------------------------
 1 file changed, 75 insertions(+), 156 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/22f6e9ef/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index e534645..6aee414 100644
--- a/README.md
+++ b/README.md
@@ -1,201 +1,120 @@
 ARIA
 ====
 
-[![Build Status](https://travis-ci.org/apache/incubator-ariatosca.svg?branch=master)](https://travis-ci.org/apache/incubator-ariatosca)
-[![Appveyor Build Status](https://ci.appveyor.com/api/projects/status/ltv89jk63ahiu306?svg=true)](https://ci.appveyor.com/project/ApacheSoftwareFoundation/incubator-ariatosca/history)
-[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
+[![Build Status](https://img.shields.io/travis/apache/incubator-ariatosca/master.svg)](https://travis-ci.org/apache/incubator-ariatosca)
+[![Appveyor Build Status](https://img.shields.io/appveyor/ci/ApacheSoftwareFoundation/incubator-ariatosca/master.svg)](https://ci.appveyor.com/project/ApacheSoftwareFoundation/incubator-ariatosca/history)
+[![License](https://img.shields.io/github/license/apache/incubator-ariatosca.svg)](http://www.apache.org/licenses/LICENSE-2.0)
+[![PyPI release](https://img.shields.io/pypi/v/ariatosca.svg)](https://pypi.python.org/pypi/ariatosca)
+![Python Versions](https://img.shields.io/pypi/pyversions/ariatosca.svg)
+![Wheel](https://img.shields.io/pypi/wheel/ariatosca.svg)
+![Contributors](https://img.shields.io/github/contributors/apache/incubator-ariatosca.svg)
+[![Open Pull Requests](https://img.shields.io/github/issues-pr/apache/incubator-ariatosca.svg)](https://github.com/apache/incubator-ariatosca/pulls)
+[![Closed Pull Requests](https://img.shields.io/github/issues-pr-closed-raw/apache/incubator-ariatosca.svg)](https://github.com/apache/incubator-ariatosca/pulls?q=is%3Apr+is%3Aclosed)
 
 
-[ARIA](http://ariatosca.org/) is a minimal TOSCA orchestrator, as well as a platform for building
-TOSCA-based products. Its features can be accessed via a well-documented Python API.
+What is ARIA?
+----------------
 
-On its own, ARIA provides built-in tools for blueprint validation and for creating ready-to-run
-service instances. 
+[ARIA](http://ariatosca.incubator.apache.org/) is a an open-source, [TOSCA](https://www.oasis-open.org/committees/tosca/)-based, lightweight library and CLI for orchestration and for consumption by projects building TOSCA-based solutions for resources and services orchestration.
 
-ARIA adheres strictly and meticulously to the
-[TOSCA Simple Profile v1.0 cos01 specification](http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html),
-providing state-of-the-art validation at seven different levels:
+ARIA can be utilized by any organization that wants to implement TOSCA-based orchestration in its solutions, whether a multi-cloud enterprise application, or an NFV or SDN solution for multiple virtual infrastructure managers.
 
-<ol start="0">
-<li>Platform errors. E.g. network, hardware, or even an internal bug in ARIA (let us know,
-	please!).</li>
-<li>Syntax and format errors. E.g. non-compliant YAML, XML, JSON.</li>
-<li>Field validation. E.g. assigning a string where an integer is expected, using a list instead of
-	a dict.</li>
-<li>Relationships between fields within a type. This is "grammar" as it applies to rules for
-    setting the values of fields in relation to each other.</li>
-<li>Relationships between types. E.g. referring to an unknown type, causing a type inheritance
-    loop.</li>
-<li>Topology. These errors happen if requirements and capabilities cannot be matched in order to
-	assemble a valid topology.</li>
-<li>External dependencies. These errors happen if requirement/capability matching fails due to
-    external resources missing, e.g. the lack of a valid virtual machine, API credentials, etc.
-    </li> 
-</ol>
+With ARIA, you can utilize TOSCA's cloud portability out-of-the-box, to develop, test and run your applications, from template to deployment.
 
-Validation errors include a plain English message and when relevant the exact location (file, row,
-column) of the data the caused the error.
+ARIA is an incubation project under the [Apache Software Foundation](https://www.apache.org/).
 
-The ARIA API documentation always links to the relevant section of the specification, and likewise
-we provide an annotated version of the specification that links back to the API documentation.
 
+Installation
+----------------
 
-Quick Start
------------
+ARIA is [available on PyPI](https://pypi.python.org/pypi/ariatosca).    
 
-You need Python 2.6 or 2.7. Python 3+ is not currently supported.
+To install ARIA directly from PyPI (using a `wheel`), use:
 
-To install, we recommend using [pip](https://pip.pypa.io/) and a
-[virtualenv](https://virtualenv.pypa.io/en/stable/).
+    pip install aria
 
-In Debian-based systems:
 
-	sudo apt install python-setuptools
-	sudo -H easy_install pip
-	sudo -H pip install virtualenv
-	virtualenv env
+To install ARIA from source, download the source tarball from [PyPI](https://pypi.python.org/pypi/ariatosca),
+extract it, and then when inside the extracted directory, use:
 
-Or in Archlinux-based systems:
+    pip install .
 
-	pacman -S python2 python-setuptools python-pip
-	pip install virtualenv
-	virtualenv env -p $(type -p python2)
+The source package comes along with relevant examples, documentation,
+`requirements.txt` (for installing specifically the frozen dependencies' versions with which ARIA was tested) and more.
 
-To install the latest development snapshot of ARIA:
+<br>
+Note that for the `pip install` commands mentioned above, you must use a privileged user, or use virtualenv.
+<br><br><br>
 
-	. env/bin/activate
-	pip install git+http://git-wip-us.apache.org/repos/asf/incubator-ariatosca.git
+ARIA itself is in a `wheel` format compatible with all platforms. 
+Some dependencies, however, might require compilation (based on a given platform), and therefore possibly some system dependencies are required as well.
 
-To test it, let's create a service instance from a TOSCA blueprint:
+On Ubuntu or other Debian-based systems:
 
-	aria parse blueprints/tosca/node-cellar/node-cellar.yaml
-	
-You can also get it in JSON or YAML formats:
+	sudo apt install python-setuptools python-dev build-essential libssl-dev libffi-dev
 
-	aria parse blueprints/tosca/node-cellar/node-cellar.yaml --json
+On Archlinux:
 
-Or get an overview of the relationship graph:
+	sudo pacman -S python-setuptools
 
-	aria parse blueprints/tosca/node-cellar/node-cellar.yaml --graph
 
-You can provide inputs as JSON, overriding default values provided in the blueprint
+ARIA requires Python 2.6/2.7. Python 3+ is currently not supported.
 
-	aria parse blueprints/tosca/node-cellar/node-cellar.yaml --inputs='{"openstack_credential": {"user": "username"}}'
 
-Instead of providing them explicitly, you can also provide them in a file or URL, in either JSON or
-YAML. If you do so, the value must end in ".json" or ".yaml":
+Getting Started
+---------------
 
-	aria parse blueprints/tosca/node-cellar/node-cellar.yaml --inputs=blueprints/tosca/node-cellar/inputs.yaml
+This section will describe how to run a simple "Hello World" example.
 
+First, provide ARIA with the ARIA "hello world" service-template and name it (e.g. `my-service-template`):
 
-CLI
----
+	aria service-templates store examples/hello-world/helloworld.yaml my-service-template
+	
+Now create a service based on this service-template and name it (e.g. `my-service`):
+	
+	aria services create my-service -t my-service-template
+	
+Finally, start an `install` workflow execution on `my-service` like so:
 
-Though ARIA is fully exposed as an API, it also comes with a CLI tool to allow you to work from the
-shell:
+	aria executions start install -s my-service
 
-	aria parse blueprints/tosca/node-cellar/node-cellar.yaml instance
+<br>
+You should now have a simple web-server running on your local machine.
+You can try visiting http://localhost:9090 to view your deployed application.
 
-The `parse` command supports the following directives to create variations of the default consumer
-chain:
+To uninstall and clean your environment, follow these steps:
 
-* `presentation`: emits a colorized textual representation of the Python presentation classes
-   wrapping the blueprint.
-* `model`: emits a colorized textual representation of the complete service model derived from the
-   validated blueprint. This includes all the node templates, with their requirements satisfied at
-   the level of relating to other node templates.
-* `types`: emits a colorized textual representation of the type hierarchies.
-* `instance`: **this is the default command**; emits a colorized textual representation of a
-   service instance instantiated from the service model. Here the node templates are each used to
-   create one or more nodes, with the appropriate relationships between them. Note that every time
-   you run this consumer, you will get a different set of node IDs. Use `--graph` to see just the
-   node relationship graph.
-   
-For all these commands, you can also use `--json` or `--yaml` flags to emit in those formats.
+    aria executions start uninstall -s my-service
+    aria services delete my-service
+    aria service-templates delete my-service-template
 
-Additionally, The CLI tool lets you specify the complete classname of your own custom consumer to
-chain at the end of the default consumer chain, after `instance`.
 
-Your custom consumer can be an entry point into a powerful TOSCA-based tool or application, such as
-an orchestrator, a graphical modeling tool, etc.
+Contribution
+------------
 
+You are welcome and encouraged to participate and contribute to the ARIA project.
 
-Development
------------
+Please see our guide to [Contributing to ARIA](https://cwiki.apache.org/confluence/display/ARIATOSCA/Contributing+to+ARIA).
 
-Instead of installing with `pip`, it would be easier to work directly with the source files:
+Feel free to also provide feedback on the mailing lists (see [Resources](#user-content-resources) section).
 
-	pip install virtualenv
-	virtualenv env
-	. env/bin/activate
-	git clone http://git-wip-us.apache.org/repos/asf/incubator-ariatosca.git ariatosca
-	cd ariatosca
-	pip install -e .
 
-To run tests:
+Resources
+---------
 
-	pip install tox
-	tox
+* [ARIA homepage](http://ariatosca.incubator.apache.org/)
+* [ARIA wiki](https://cwiki.apache.org/confluence/display/AriaTosca)
+* [Issue tracker](https://issues.apache.org/jira/browse/ARIA)
 
-Here's a quick example of using the API to parse YAML text into a service instance:
+* Dev mailing list: dev@ariatosca.incubator.apache.org
+* User mailing list: user@ariatosca.incubator.apache.org
 
-	from aria import install_aria_extensions
-	from aria.parser.consumption import ConsumptionContext, ConsumerChain, Read, Validate, Model, Instance
-	from aria.parser.loading import LiteralLocation
-	
-	def parse_text(payload, file_search_paths=[]):
-	    context = ConsumptionContext()
-	    context.presentation.location = LiteralLocation(payload)
-	    context.loading.file_search_paths += file_search_paths
-	    ConsumerChain(context, (Read, Validate, Model, Instance)).consume()
-	    if not context.validation.dump_issues():
-	        return context.modeling.instance
-	    return None
-	
-	install_aria_extensions()
-
-	print parse_text("""
-	tosca_definitions_version: tosca_simple_yaml_1_0
-	topology_template:
-	  node_templates:
-	    MyNode:
-	      type: tosca.nodes.Compute 
-	""")
-
-
-Parser API Architecture
------------------------
-
-ARIA's parsing engine comprises individual "consumers" (in the `aria.parser.consumption` package)
-that do things with blueprints. When chained together, each performs a different task, adds its own
-validations, and can provide its own output.
-
-Parsing happens in five phases, represented in five packages:
-
-* `aria.parser.loading`: Loaders are used to read the TOSCA data, usually as text. For example
-  UriTextLoader will load text from URIs (including files).
-* `aria.parser.reading`: Readers convert data from the loaders into agnostic raw data. For
-  example, `YamlReader` converts YAML text into Python dicts, lists, and primitives.
-* `aria.parser.presentation`: Presenters wrap the agnostic raw data in a nice
-  Python facade (a "presentation") that makes it much easier to work with the data, including
-  utilities for validation, querying, etc. Note that presenters are _wrappers_: the agnostic raw
-  data is always maintained intact, and can always be accessed directly or written back to files.
-* `aria.parser.modeling.model`: Here the topology is normalized into a coherent structure of
-  node templates, requirements, and capabilities. Types are inherited and properties are assigned.
-  The service model is a _new_ structure, which is not mapped to the YAML. In fact, it is possible
-  to generate the model programmatically, or from a DSL parser other than TOSCA.
-* `aria.parser.modeling.instance`: The service instance is an instantiated service model. Node
-  templates turn into node instances (with unique IDs), and requirements are satisfied by matching
-  them to capabilities. This is where level 5 validation errors are detected (see above).
-
-The phases do not have to be used in order. Indeed, consumers do not have to be used at all: ARIA
-can be used to _produce_ blueprints. For example, it is possible to fill in the
-`aria.parser.presentation` classes programmatically, in Python, and then write the presentation
-to a YAML file as compliant TOSCA. The same technique can be used to convert from one DSL (consume
-it) to another (write it).
-
-The term "agnostic raw data" (ARD?) appears often in the documentation. It denotes data structures
-comprising _only_ Python dicts, lists, and primitives, such that they can always be converted to and
-from language-agnostic formats such as YAML, JSON, and XML. A considerable effort has been made to
-conserve the agnostic raw data at all times. Thus, though ARIA makes good use of the dynamic power
-of Python, you will _always_ be able to use ARIA with other systems.
+Subscribe by sending a mail to `<group>-subscribe@ariatosca.incubator.apache.org` (e.g. `dev-subscribe@ariatosca.incubator.apache.org`).
+See information on how to subscribe to mailing list [here](https://www.apache.org/foundation/mailinglists.html).
+
+For past correspondence, see the [dev mailing list archive](http://mail-archives.apache.org/mod_mbox/incubator-ariatosca-dev/).
+
+
+License
+-------
+ARIA is licensed under the [Apache License 2.0](https://github.com/apache/incubator-ariatosca/blob/master/LICENSE).


[04/10] incubator-ariatosca git commit: ARIA-275 Update NFV profile to csd04

Posted by em...@apache.org.
ARIA-275 Update NFV profile to csd04

This update was done according to:
http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html

We resolved some inconsistencies of csd04 with the TOSCA spec, and within csd04 itself. Wherever we resolved such inconsistencies, we added a detailed
comment describing our reasoning.


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/1e883c57
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/1e883c57
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/1e883c57

Branch: refs/heads/ARIA-254-multiple-nodes-per-template
Commit: 1e883c57abb733b10e13f0b7005cf564886d3fb1
Parents: 22f6e9e
Author: Avia Efrat <av...@gigaspaces.com>
Authored: Sun Jun 4 22:11:10 2017 +0300
Committer: Avia Efrat <av...@gigaspaces.com>
Committed: Mon Jun 12 22:24:04 2017 +0300

----------------------------------------------------------------------
 .../profiles/tosca-simple-1.0/artifacts.yaml    |   8 +-
 .../profiles/tosca-simple-1.0/capabilities.yaml |   2 +-
 .../profiles/tosca-simple-1.0/data.yaml         |   2 +-
 .../profiles/tosca-simple-1.0/groups.yaml       |   2 +-
 .../profiles/tosca-simple-1.0/interfaces.yaml   |   2 +-
 .../profiles/tosca-simple-1.0/nodes.yaml        |   2 +-
 .../profiles/tosca-simple-1.0/policies.yaml     |  10 +-
 .../tosca-simple-1.0/relationships.yaml         |   2 +-
 .../tosca-simple-nfv-1.0/artifacts.yaml         |  84 +++++
 .../tosca-simple-nfv-1.0/capabilities.yaml      |  99 ++----
 .../profiles/tosca-simple-nfv-1.0/data.yaml     | 305 ++++++++++++++---
 .../profiles/tosca-simple-nfv-1.0/groups.yaml   |  56 ----
 .../profiles/tosca-simple-nfv-1.0/nodes.yaml    | 323 ++++++++++++-------
 .../tosca-simple-nfv-1.0/relationships.yaml     |  37 +--
 .../tosca-simple-nfv-1.0.yaml                   |   2 +-
 15 files changed, 604 insertions(+), 332 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1e883c57/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/artifacts.yaml
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/artifacts.yaml b/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/artifacts.yaml
index af99340..cfb0df5 100644
--- a/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/artifacts.yaml
+++ b/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/artifacts.yaml
@@ -17,7 +17,7 @@ artifact_types:
 
   tosca.artifacts.Root:
     _extensions:
-      shorthand_name: Root # ARIA NOTE: ommitted in the spec
+      shorthand_name: Root # ARIA NOTE: omitted in the spec
       type_qualified_name: tosca:Root
       specification: tosca-simple-1.0
       specification_section: 5.3.1
@@ -41,7 +41,7 @@ artifact_types:
   
   tosca.artifacts.Deployment:
     _extensions:
-      shorthand_name: Deployment # ARIA NOTE: ommitted in the spec
+      shorthand_name: Deployment # ARIA NOTE: omitted in the spec
       type_qualified_name: tosca:Deployment
       specification: tosca-simple-1.0
       specification_section: 5.3.3.1
@@ -67,7 +67,7 @@ artifact_types:
   
   tosca.artifacts.Deployment.Image.VM:
     _extensions:
-      shorthand_name: Deployment.VM # ARIA NOTE: ommitted in the spec
+      shorthand_name: Deployment.VM # ARIA NOTE: omitted in the spec
       type_qualified_name: tosca:Deployment.VM
       specification: tosca-simple-1.0
       specification_section: 5.3.3.4
@@ -85,7 +85,7 @@ artifact_types:
   
   tosca.artifacts.Implementation:
     _extensions:
-      shorthand_name: Implementation # ARIA NOTE: ommitted in the spec
+      shorthand_name: Implementation # ARIA NOTE: omitted in the spec
       type_qualified_name: tosca:Implementation
       specification: tosca-simple-1.0
       specification_section: 5.3.4.1

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1e883c57/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/capabilities.yaml
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/capabilities.yaml b/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/capabilities.yaml
index 0b81a16..30abe10 100644
--- a/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/capabilities.yaml
+++ b/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/capabilities.yaml
@@ -17,7 +17,7 @@ capability_types:
 
   tosca.capabilities.Root:
     _extensions:
-      shorthand_name: Root # ARIA NOTE: ommitted in the spec
+      shorthand_name: Root # ARIA NOTE: omitted in the spec
       type_qualified_name: tosca:Root
       specification: tosca-simple-1.0
       specification_section: 5.4.1

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1e883c57/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/data.yaml
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/data.yaml b/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/data.yaml
index 5210aa0..771a969 100644
--- a/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/data.yaml
+++ b/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/data.yaml
@@ -95,7 +95,7 @@ data_types:
 
   tosca.datatypes.Root:
     _extensions:
-      shorthand_name: Root # ARIA NOTE: ommitted in the spec
+      shorthand_name: Root # ARIA NOTE: omitted in the spec
       type_qualified_name: tosca:Root
       specification: tosca-simple-1.0
       specification_section: 5.2.1

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1e883c57/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/groups.yaml
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/groups.yaml b/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/groups.yaml
index 31cfc55..66cc25f 100644
--- a/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/groups.yaml
+++ b/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/groups.yaml
@@ -17,7 +17,7 @@ group_types:
 
   tosca.groups.Root:
     _extensions:
-      shorthand_name: Root # ARIA NOTE: ommitted in the spec
+      shorthand_name: Root # ARIA NOTE: omitted in the spec
       type_qualified_name: tosca:Root
       specification: tosca-simple-1.0
       specification_section: 5.9.1

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1e883c57/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/interfaces.yaml
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/interfaces.yaml b/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/interfaces.yaml
index 1e83ef9..473bd98 100644
--- a/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/interfaces.yaml
+++ b/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/interfaces.yaml
@@ -17,7 +17,7 @@ interface_types:
 
   tosca.interfaces.Root:
     _extensions:
-      shorthand_name: Root # ARIA NOTE: ommitted in the spec
+      shorthand_name: Root # ARIA NOTE: omitted in the spec
       type_qualified_name: tosca:Root
       specification: tosca-simple-1.0
       specification_section: 5.7.3

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1e883c57/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/nodes.yaml
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/nodes.yaml b/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/nodes.yaml
index bb33b6f..1d2fe90 100644
--- a/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/nodes.yaml
+++ b/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/nodes.yaml
@@ -214,7 +214,7 @@ node_types:
   
   tosca.nodes.DBMS:
     _extensions:
-      shorthand_name: DBMS # ARIA NOTE: ommitted in the spec
+      shorthand_name: DBMS # ARIA NOTE: omitted in the spec
       type_qualified_name: tosca:DBMS
       specification: tosca-simple-1.0
       specification_section: 5.8.6

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1e883c57/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/policies.yaml
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/policies.yaml b/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/policies.yaml
index 015d2b0..c65e38b 100644
--- a/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/policies.yaml
+++ b/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/policies.yaml
@@ -17,7 +17,7 @@ policy_types:
 
   tosca.policies.Root:
     _extensions:
-      shorthand_name: Root # ARIA NOTE: ommitted in the spec
+      shorthand_name: Root # ARIA NOTE: omitted in the spec
       type_qualified_name: tosca:Root
       specification: tosca-simple-1.0
       specification_section: 5.10.1
@@ -27,7 +27,7 @@ policy_types:
   
   tosca.policies.Placement:
     _extensions:
-      shorthand_name: Placement # ARIA NOTE: ommitted in the spec
+      shorthand_name: Placement # ARIA NOTE: omitted in the spec
       type_qualified_name: tosca:Placement
       specification: tosca-simple-1.0
       specification_section: 5.10.2
@@ -38,7 +38,7 @@ policy_types:
   
   tosca.policies.Scaling:
     _extensions:
-      shorthand_name: Scaling # ARIA NOTE: ommitted in the spec
+      shorthand_name: Scaling # ARIA NOTE: omitted in the spec
       type_qualified_name: tosca:Scaling
       specification: tosca-simple-1.0
       specification_section: 5.10.3
@@ -49,7 +49,7 @@ policy_types:
   
   tosca.policies.Update:
     _extensions:
-      shorthand_name: Update # ARIA NOTE: ommitted in the spec
+      shorthand_name: Update # ARIA NOTE: omitted in the spec
       type_qualified_name: tosca:Update
       specification: tosca-simple-1.0
       specification_section: 5.10.4
@@ -60,7 +60,7 @@ policy_types:
   
   tosca.policies.Performance:
     _extensions:
-      shorthand_name: Performance # ARIA NOTE: ommitted in the spec
+      shorthand_name: Performance # ARIA NOTE: omitted in the spec
       type_qualified_name: tosca:Performance
       specification: tosca-simple-1.0
       specification_section: 5.10.5

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1e883c57/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/relationships.yaml
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/relationships.yaml b/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/relationships.yaml
index 6ea4d12..b9d3176 100644
--- a/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/relationships.yaml
+++ b/extensions/aria_extension_tosca/profiles/tosca-simple-1.0/relationships.yaml
@@ -17,7 +17,7 @@ relationship_types:
 
   tosca.relationships.Root:
     _extensions:
-      shorthand_name: Root # ARIA NOTE: ommitted in the spec
+      shorthand_name: Root # ARIA NOTE: omitted in the spec
       type_qualified_name: tosca:Root
       specification: tosca-simple-1.0
       specification_section: 5.6.1

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1e883c57/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/artifacts.yaml
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/artifacts.yaml b/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/artifacts.yaml
new file mode 100644
index 0000000..2427d9f
--- /dev/null
+++ b/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/artifacts.yaml
@@ -0,0 +1,84 @@
+# 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.
+
+artifact_types:
+
+  tosca.artifacts.nfv.SwImage:
+    _extensions:
+      shorthand_name: SwImage
+      type_qualified_name: tosca:SwImage
+      specification: tosca-simple-nfv-1.0
+      specification_section: 5.4.1
+      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896067'
+    derived_from: tosca.artifacts.Deployment.Image
+    properties:
+      name:
+        description: >-
+          Name of this software image.
+        type: string
+        required: true
+      version:
+        description: >-
+          Version of this software image.
+        type: string
+        required: true
+      checksum:
+        description: >-
+          Checksum of the software image file.
+        type: string
+      container_format:
+        description: >-
+          The container format describes the container file format in which software image is
+          provided.
+        type: string
+        required: true
+      disk_format:
+        description: >-
+          The disk format of a software image is the format of the underlying disk image.
+        type: string
+        required: true
+      min_disk:
+        description: >-
+          The minimal disk size requirement for this software image.
+        type: scalar-unit.size
+        required: true
+      min_ram:
+        description: >-
+          The minimal disk size requirement for this software image.
+        type: scalar-unit.size
+        required: false
+      size: # ARIA NOTE: section [5.4.1.1 Properties] calls this field 'Size'
+        description: >-
+          The size of this software image
+        type: scalar-unit.size
+        required: true
+      sw_image:
+        description: >-
+          A reference to the actual software image within VNF Package, or url.
+        type: string
+        required: true
+      operating_system:
+        description: >-
+          Identifies the operating system used in the software image.
+        type: string
+        required: false
+      supported _virtualization_enviroment:
+        description: >-
+          Identifies the virtualization environments (e.g. hypervisor) compatible with this software
+          image.
+        type: list
+        entry_schema:
+          type: string
+        required: false

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1e883c57/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/capabilities.yaml
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/capabilities.yaml b/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/capabilities.yaml
index 6bc6b67..7b6363f 100644
--- a/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/capabilities.yaml
+++ b/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/capabilities.yaml
@@ -15,58 +15,13 @@
 
 capability_types:
 
-  tosca.capabilities.Compute.Container.Architecture:
-    _extensions:
-      shorthand_name: Compute.Container.Architecture
-      type_qualified_name: tosca:Compute.Container.Architecture
-      specification: tosca-simple-nfv-1.0
-      specification_section: 8.2.1
-      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html#DEFN_TYPE_CAPABILITIES_CONTAINER'
-    description: >-
-      Enhance compute architecture capability that needs to be typically use for performance sensitive NFV workloads.
-    derived_from: tosca.capabilities.Container
-    properties:
-      mem_page_size:
-        description: >-
-          Describe page size of the VM:
-  
-          * small page size is typically 4KB
-          * large page size is typically 2MB
-          * any page size maps to system default
-          * custom MB value: sets TLB size to this specific value
-        type: string
-        # ARIA NOTE: seems wrong in the spec
-        #constraints:
-        #  - [ normal, huge ]
-      cpu_allocation:
-        description: >-
-          Describes CPU allocation requirements like dedicated CPUs (cpu pinning), socket count, thread count, etc.
-        type: tosca.datatypes.compute.Container.Architecture.CPUAllocation
-        required: false
-      numa_node_count:
-        description: >-
-          Specifies the symmetric count of NUMA nodes to expose to the VM. vCPU and Memory equally split across this number of
-          NUMA.
-  
-          NOTE: the map of numa_nodes should not be specified.
-        type: integer
-        required: false 
-      numa_nodes:
-        description: >-
-          Asymmetric allocation of vCPU and Memory across the specific NUMA nodes (CPU sockets and memory banks).
-  
-          NOTE: symmetric numa_node_count should not be specified.
-        type: map
-        entry_schema: tosca.datatypes.compute.Container.Architecture.NUMA
-        required: false
-
   tosca.capabilities.nfv.VirtualBindable:
     _extensions:
       shorthand_name: VirtualBindable
       type_qualified_name: tosca:VirtualBindable
       specification: tosca-simple-nfv-1.0
-      specification_section: 8.2.2
-      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html#_Toc419290220'
+      specification_section: 5.5.1
+      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896069'
     description: >-
       A node type that includes the VirtualBindable capability indicates that it can be pointed by
       tosca.relationships.nfv.VirtualBindsTo relationship type.
@@ -77,33 +32,39 @@ capability_types:
       shorthand_name: Metric
       type_qualified_name: tosca:Metric
       specification: tosca-simple-nfv-1.0
-      specification_section: 8.2.3
-      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html#_Toc418607874'
+      specification_section: 5.5.2
+      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896070'
     description: >-
       A node type that includes the Metric capability indicates that it can be monitored using an nfv.relationships.Monitor
       relationship type.
     derived_from: tosca.capabilities.Endpoint
 
-  tosca.capabilities.nfv.Forwarder:
+  tosca.capabilities.nfv.VirtualCompute:
     _extensions:
-      shorthand_name: Forwarder
-      type_qualified_name: tosca:Forwarder
+      shorthand_name: VirtualCompute
+      type_qualified_name: tosca:VirtualCompute
       specification: tosca-simple-nfv-1.0
-      specification_section: 10.3.1
-      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html#_Toc447714718'
-    description: >-
-      A node type that includes the Forwarder capability indicates that it can be pointed by tosca.relationships.nfv.FowardsTo
-      relationship type.
+      specification_section: 5.5.3
+      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896071'
     derived_from: tosca.capabilities.Root
-
-  tosca.capabilities.nfv.VirtualLinkable:
-    _extensions:
-      shorthand_name: VirtualLinkable
-      type_qualified_name: tosca:VirtualLinkable
-      specification: tosca-simple-nfv-1.0
-      specification_section: 11.3.1
-      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html#_Toc447714735'
-    description: >-
-      A node type that includes the VirtualLinkable capability indicates that it can be pointed by
-      tosca.relationships.nfv.VirtualLinksTo relationship type.
-    derived_from: tosca.capabilities.Node
+    properties:
+      requested_additional_capabilities:
+        # ARIA NOTE: in section [5.5.3.1 Properties] the name of this property is
+        # "request_additional_capabilities", and its type is not a map, but
+        # tosca.datatypes.nfv.RequestedAdditionalCapability
+        description: >-
+          Describes additional capability for a particular VDU.
+        type: map
+        entry_schema:
+           type: tosca.datatypes.nfv.RequestedAdditionalCapability
+        required: false
+      virtual_memory:
+        description: >-
+          Describes virtual memory of the virtualized compute.
+        type: tosca.datatypes.nfv.VirtualMemory
+        required: true
+      virtual_cpu:
+        description: >-
+          Describes virtual CPU(s) of the virtualized compute.
+        type: tosca.datatypes.nfv.VirtualCpu
+        required: true

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1e883c57/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/data.yaml
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/data.yaml b/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/data.yaml
index 89e3565..889dcf7 100644
--- a/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/data.yaml
+++ b/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/data.yaml
@@ -15,77 +15,304 @@
 
 data_types:
 
-  tosca.datatypes.compute.Container.Architecture.CPUAllocation:
+  tosca.datatypes.nfv.L2AddressData:
+    # TBD
     _extensions:
-      shorthand_name: Container.Architecture.CPUAllocation # seems to be a mistake in the spec; the norm is to add a "Container.Architecture." prefix
-      type_qualified_name: tosca:Container.Architecture.CPUAllocation
+      shorthand_name: L2AddressData
+      type_qualified_name: tosca:L2AddressData
       specification: tosca-simple-nfv-1.0
-      specification_section: 8.3.1
+      specification_section: 5.3.1
+      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896055'
+
+  tosca.datatypes.nfv.L3AddressData:
+    _extensions:
+      shorthand_name: L3AddressData
+      type_qualified_name: tosca:L3AddressData
+      specification: tosca-simple-nfv-1.0
+      specification_section: 5.3.2
+      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896056'
     description: >-
-      Granular CPU allocation requirements for NFV workloads.
+      The L3AddressData type is a complex TOSCA data type used to describe L3AddressData information
+      element as defined in [ETSI GS NFV-IFA 011], it provides the information on the IP addresses
+      to be assigned to the connection point instantiated from the parent Connection Point
+      Descriptor.
     derived_from: tosca.datatypes.Root
     properties:
-      cpu_affinity:
+      ip_address_assignment:
+        description: >-
+          Specify if the address assignment is the responsibility of management and orchestration
+          function or not. If it is set to True, it is the management and orchestration function
+          responsibility.
+        type: boolean
+        required: true
+      floating_ip_activated:
+        description: Specify if the floating IP scheme is activated on the Connection Point or not.
+        type: boolean
+        required: true
+      ip_address_type:
         description: >-
-          Describes whether vCPU need to be pinned to dedicated CPU core or shared dynamically.
+          Define address type. The address type should be aligned with the address type supported by
+          the layer_protocol properties of the parent VnfExtCpd.
         type: string
+        required: false
         constraints:
-          - valid_values: [ shared, dedicated ]
+          - valid_values: [ ipv4, ipv6 ]
+      number_of_ip_address:
+        description: >-
+          Minimum number of IP addresses to be assigned.
+        type: integer
         required: false
-      thread_allocation:
+
+  tosca.datatypes.nfv.AddressData:
+    _extensions:
+      shorthand_name: AddressData
+      type_qualified_name: tosca:AddressData
+      specification: tosca-simple-nfv-1.0
+      specification_section: 5.3.3
+      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896057'
+    description: >-
+      The AddressData type is a complex TOSCA data type used to describe AddressData information
+      element as defined in [ETSI GS NFV-IFA 011], it provides information on the addresses to be
+      assigned to the connection point(s) instantiated from a Connection Point Descriptor.
+    derived_from: tosca.datatypes.Root
+    properties:
+      address_type:
         description: >-
-          Describe thread allocation requirement.
+          Describes the type of the address to be assigned to the connection point instantiated from
+          the parent Connection Point Descriptor. The content type shall be aligned with the address
+          type supported by the layerProtocol property of the parent Connection Point Descriptor.
         type: string
+        required: true
         constraints:
-          - valid_values: [ avoid, isolate, separate, prefer ]
+          - valid_values: [ mac_address, ip_address ]
+      l2_address_data:
+        # Shall be present when the addressType is mac_address.
+        description: >-
+          Provides the information on the MAC addresses to be assigned to the connection point(s)
+          instantiated from the parent Connection Point Descriptor.
+        type: tosca.datatypes.nfv.L2AddressData # Empty in "GS NFV IFA011 V0.7.3"
         required: false
-      socket_count:
+      l3_address_data:
+        # Shall be present when the addressType is ip_address.
         description: >-
-          Number of CPU sockets.
-        type: integer
+          Provides the information on the IP addresses to be assigned to the connection point
+          instantiated from the parent Connection Point Descriptor.
+        type: tosca.datatypes.nfv.L3AddressData
         required: false
-      core_count:
+
+  tosca.datatypes.nfv.VirtualNetworkInterfaceRequirements:
+    _extensions:
+      shorthand_name: VirtualNetworkInterfaceRequirements
+      type_qualified_name: tosca:VirtualNetworkInterfaceRequirements
+      specification: tosca-simple-nfv-1.0
+      specification_section: 5.3.4
+      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896058'
+    description: >-
+      The VirtualNetworkInterfaceRequirements type is a complex TOSCA data type used to describe
+      VirtualNetworkInterfaceRequirements information element as defined in [ETSI GS NFV-IFA 011],
+      it provides the information to specify requirements on a virtual network interface realising the
+      CPs instantiated from this CPD.
+    derived_from: tosca.datatypes.Root
+    properties:
+      name:
         description: >-
-          Number of cores per socket.
-        type: integer
+          Provides a human readable name for the requirement.
+        type: string
         required: false
-      thread_count:
+      description:
         description: >-
-          Number of threads per core.
-        type: integer
+          Provides a human readable description for the requirement.
+        type: string
         required: false
+      support_mandatory:
+        description: >-
+          Indicates whether fulfilling the constraint is mandatory (TRUE) for successful operation
+          or desirable (FALSE).
+        type: boolean
+        required: false
+      requirement:
+        description: >-
+          Specifies a requirement such as the support of SR-IOV, a particular data plane
+          acceleration library, an API to be exposed by a NIC, etc.
+        type: string # ARIA NOTE: the spec says "not specified", but TOSCA requires a type
+        required: true
 
-  tosca.datatypes.compute.Container.Architecture.NUMA:
+  tosca.datatypes.nfv.ConnectivityType:
     _extensions:
-      shorthand_name: Container.Architecture.NUMA # ARIA NOTE: seems to be a mistake in the spec; the norm is to add a "Container.Architecture." prefix
-      type_qualified_name: tosca:Container.Architecture.NUMA
+      shorthand_name: ConnectivityType
+      type_qualified_name: tosca:ConnectivityType
       specification: tosca-simple-nfv-1.0
-      specification_section: 8.3.2
-      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html#_Toc447714697'
+      specification_section: 5.3.5
+      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896059'
     description: >-
-      Granular Non-Uniform Memory Access (NUMA) topology requirements for NFV workloads.
+      The TOSCA ConnectivityType type is a complex TOSCA data type used to describe ConnectivityType
+      information element as defined in [ETSI GS NFV-IFA 011].
     derived_from: tosca.datatypes.Root
     properties:
-      id:
+      layer_protocol:
         description: >-
-          CPU socket identifier.
-        type: integer
+          Identifies the protocol this VL gives access to (ethernet, mpls, odu2, ipv4, ipv6,
+          pseudo_wire).
+        type: string
+        required: true
         constraints:
-          - greater_or_equal: 0
+          - valid_values: [ ethernet, mpls, odu2, ipv4, ipv6, pseudo_wire ]
+      flow_pattern:
+        description: >-
+          Identifies the flow pattern of the connectivity (Line, Tree, Mesh).
+        type: string
         required: false
-      vcpus:
+
+  tosca.datatypes.nfv.RequestedAdditionalCapability:
+    _extensions:
+      shorthand_name: RequestedAdditionalCapability
+      type_qualified_name: tosca:RequestedAdditionalCapability
+      specification: tosca-simple-nfv-1.0
+      specification_section: 5.3.6
+      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896060'
+    description: >-
+      RequestAdditionalCapability describes additional capability for a particular VDU.
+    derived_from: tosca.datatypes.Root
+    properties:
+      request_additional_capability_name:
         description: >-
-          List of specific host cpu numbers within a NUMA socket complex.
-  
-          TODO: need a new base type, with non-overlapping, positive value validation (exclusivity),
+          Identifies a requested additional capability for the VDU.
+        type: string
+        required: true
+      support_mandatory:
+        description: >-
+          Indicates whether the requested additional capability is mandatory for successful
+          operation.
+        type: string
+        required: true
+      min_requested_additional_capability_version:
+        description: >-
+          Identifies the minimum version of the requested additional capability.
+        type: string
+        required: false
+      preferred_requested_additional_capability_version:
+        description: >-
+          Identifies the preferred version of the requested additional capability.
+        type: string
+        required: false
+      target_performance_parameters:
+        description: >-
+          Identifies specific attributes, dependent on the requested additional capability type.
         type: map
         entry_schema:
-          type: integer
+          type: string
+        required: true
+
+  tosca.datatypes.nfv.VirtualMemory:
+    _extensions:
+      shorthand_name: VirtualMemory
+      type_qualified_name: tosca:VirtualMemory
+      specification: tosca-simple-nfv-1.0
+      specification_section: 5.3.7
+      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896061'
+    description: >-
+      VirtualMemory describes virtual memory for a particular VDU.
+    derived_from: tosca.datatypes.Root
+    properties:
+      virtual_mem_size:
+        description: Amount of virtual memory.
+        type: scalar-unit.size
+        required: true
+      virtual_mem_oversubscription_policy:
+        description: >-
+          The memory core oversubscription policy in terms of virtual memory to physical memory on
+          the platform. The cardinality can be 0 during the allocation request, if no particular
+          value is requested.
+        type: string
         required: false
-      mem_size:
+      numa_enabled:
         description: >-
-          Size of memory allocated from this NUMA memory bank.
-        type: scalar-unit.size
+          It specifies the memory allocation to be cognisant of the relevant process/core
+          allocation. The cardinality can be 0 during the allocation request, if no particular value
+          is requested.
+        type: boolean
+        required: false
+
+  tosca.datatypes.nfv.VirtualCpu:
+    _extensions:
+      shorthand_name: VirtualCpu
+      type_qualified_name: tosca:VirtualCpu
+      specification: tosca-simple-nfv-1.0
+      specification_section: 5.3.8
+      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896062'
+    description: >-
+      VirtualMemory describes virtual memory for a particular VDU.
+    derived_from: tosca.datatypes.Root
+    properties:
+      cpu_architecture:
+        description: >-
+          CPU architecture type. Examples are x86, ARM.
+        type: string
+        required: false
+      num_virtual_cpu:
+        description: >-
+          Number of virtual CPUs.
+        type: integer
+        required: true
+      virtual_cpu_clock:
+        description: >-
+          Minimum virtual CPU clock rate.
+        type: scalar-unit.frequency
+        required: false
+      virtual_cpu_oversubscription_policy:
+        description: >-
+          CPU core oversubscription policy.
+        type: string
+        required: false
+      virtual_cpu_pinning:
+        description: >-
+          The virtual CPU pinning configuration for the virtualized compute resource.
+        type: tosca.datatypes.nfv.VirtualCpuPinning
+        required: false
+
+  tosca.datatypes.nfv.VirtualCpuPinning:
+    _extensions:
+      shorthand_name: VirtualCpuPinning
+      type_qualified_name: tosca:VirtualCpuPinning
+      specification: tosca-simple-nfv-1.0
+      specification_section: 5.3.9
+      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896064'
+    description: >-
+      VirtualCpuPinning describes CPU pinning configuration for a particular CPU.
+    derived_from: tosca.datatypes.Root
+    properties:
+      cpu_pinning_policy:
+        description: >-
+          Indicates the policy for CPU pinning.
+        type: string
         constraints:
-          - greater_or_equal: 0 MB
+          - valid_values: [ static, dynamic ]
+        required: false
+      cpu_pinning_map:
+        description: >-
+          If cpuPinningPolicy is defined as "static", the cpuPinningMap provides the map of pinning
+          virtual CPU cores to physical CPU cores/threads.
+        type: map
+        entry_schema:
+          type: string
+        required: false
+
+  tosca.datatypes.nfv.VnfcConfigurableProperties:
+    _extensions:
+      shorthand_name: VnfcconfigurableProperties
+      type_qualified_name: tosca:VnfcconfigurableProperties
+      specification: tosca-simple-nfv-1.0
+      specification_section: 5.3.10
+      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896065'
+    # ARIA NOTE: description is mangled in spec
+    description: >-
+      VnfcConfigurableProperties describes additional configurable properties of a VNFC.
+    derived_from: tosca.datatypes.Root
+    properties:
+      additional_vnfc_configurable_properties:
+        description: >-
+          Describes additional configuration for VNFC.
+        type: map
+        entry_schema:
+          type: string
         required: false

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1e883c57/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/groups.yaml
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/groups.yaml b/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/groups.yaml
deleted file mode 100644
index 5eb87c8..0000000
--- a/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/groups.yaml
+++ /dev/null
@@ -1,56 +0,0 @@
-# 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.
-
-group_types:
-
-  tosca.groups.nfv.VNFFG:
-    _extensions:
-      shorthand_name: VNFFG # ARIA NOTE: the spec must be mistaken here, says "VL"
-      type_qualified_name: tosca:VNFFG
-      specification: tosca-simple-nfv-1.0
-      specification_section: 10.6.1
-      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html#_Toc447714727'
-    description: >-
-      The NFV VNFFG group type represents a logical VNF forwarding graph entity as defined by [ETSI GS NFV-MAN 001 v1.1.1].
-    derived_from: tosca.groups.Root
-    properties:
-      vendor:
-        description: >-
-          Specify the vendor generating this VNFFG.
-        type: string
-      version:
-        description: >-
-          Specify the identifier (e.g. name), version, and description of service this VNFFG is describing.
-        type: string
-      number_of_endpoints:
-        description: >-
-          Count of the external endpoints included in this VNFFG, to form an index.
-        type: integer
-      dependent_virtual_link:
-        description: >-
-          Reference to a list of VLD used in this Forwarding Graph.
-        type: list
-        entry_schema: string
-      connection_point:
-        description: >-
-          Reference to Connection Points forming the VNFFG.
-        type: list
-        entry_schema: string
-      constituent_vnfs:
-        description: >-
-          Reference to a list of VNFD used in this VNF Forwarding Graph.
-        type: list
-        entry_schema: string
-    members: [ tosca.nodes.nfv.FP ]

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1e883c57/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/nodes.yaml
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/nodes.yaml b/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/nodes.yaml
index 0dfe38d..73f0ecd 100644
--- a/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/nodes.yaml
+++ b/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/nodes.yaml
@@ -15,169 +15,246 @@
 
 node_types:
 
-  tosca.nodes.nfv.VNF:
+  tosca.nodes.nfv.VDU.Compute:
     _extensions:
-      shorthand_name: VNF # ARIA NOTE: ommitted in the spec
-      type_qualified_name: tosca:VNF
+      shorthand_name: VDU.Compute
+      type_qualified_name: tosca:VDU.Compute
       specification: tosca-simple-nfv-1.0
-      specification_section: 8.5.1
-      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html#_Toc379455076'
+      specification_section: 5.9.2
+      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896079'
     description: >-
-      The NFV VNF Node Type represents a Virtual Network Function as defined by [ETSI GS NFV-MAN 001 v1.1.1]. It is the default
-      type that all other VNF Node Types derive from. This allows for all VNF nodes to have a consistent set of features for
-      modeling and management (e.g., consistent definitions for requirements, capabilities and lifecycle interfaces).
-    derived_from: tosca.nodes.Root
+      The TOSCA nfv.VDU.Compute node type represents the virtual compute part of a VDU entity which
+      it mainly describes the deployment and operational behavior of a VNF component (VNFC), as
+      defined by [ETSI NFV IFA011].
+    derived_from: tosca.nodes.Compute
     properties:
-      id:
+      name:
         description: >-
-          ID of this VNF.
+          Human readable name of the VDU.
         type: string
-      vendor:
+        required: true
+      description:
         description: >-
-          Name of the vendor who generate this VNF.
+          Human readable description of the VDU.
         type: string
-      version:
+        required: true
+      boot_order:
+        description: >-
+          The key indicates the boot index (lowest index defines highest boot priority).
+          The Value references a descriptor from which a valid boot device is created e.g.
+          VirtualStorageDescriptor from which a VirtualStorage instance is created. If no boot order
+          is defined the default boot order defined in the VIM or NFVI shall be used.
+        type: list # ARIA NOTE: an explicit index (boot index) is unnecessary, contrary to IFA011
+        entry_schema:
+          type: string
+        required: false
+      nfvi_constraints:
+        description: >-
+          Describes constraints on the NFVI for the VNFC instance(s) created from this VDU.
+          For example, aspects of a secure hosting environment for the VNFC instance that involve
+          additional entities or processes. More software images can be attached to the
+          virtualization container using virtual_storage.
+        type: list
+        entry_schema:
+          type: string
+        required: false
+      configurable_properties:
         description: >-
-          Version of the software for this VNF.
+          Describes the configurable properties of all VNFC instances based on this VDU.
+        type: map
+        entry_schema:
+          type: tosca.datatypes.nfv.VnfcConfigurableProperties
+        required: true
+    attributes:
+      # ARIA NOTE: The attributes are only described in section [5.9.2.5 Definition], but are not
+      # mentioned in section [5.9.2.2 Attributes]. Additionally, it does not seem to make sense to
+      # deprecate inherited attributes, as it breaks the inheritence contract.
+      private_address:
         type: string
-    requirements:
-      - virtual_link:
-          capability: tosca.capabilities.nfv.VirtualLinkable
-          relationship: tosca.relationships.nfv.VirtualLinksTo
-
-  tosca.nodes.nfv.VDU:
-    _extensions:
-      shorthand_name: VDU
-      type_qualified_name: tosca:VDU
-      specification: tosca-simple-nfv-1.0
-      specification_section: 8.5.2
-      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html#_Toc419290242'
-    description: >-
-      The NFV vdu node type represents a logical vdu entity as defined by [ETSI GS NFV-MAN 001 v1.1.1].
-    derived_from: tosca.nodes.Root
+        status: deprecated
+      public_address:
+        type: string
+        status: deprecated
+      networks:
+        type: map
+        entry_schema:
+          type: tosca.datatypes.network.NetworkInfo
+        status: deprecated
+      ports:
+        type: map
+        entry_schema:
+          type: tosca.datatypes.network.PortInfo
+        status: deprecated
     capabilities:
-      nfv_compute:
-        type: tosca.capabilities.Compute.Container.Architecture
+      virtual_compute:
+        description: >-
+          Describes virtual compute resources capabilities.
+        type: tosca.capabilities.nfv.VirtualCompute
       virtual_binding:
+        description: >-
+          Defines ability of VirtualBindable.
         type: tosca.capabilities.nfv.VirtualBindable
       monitoring_parameter:
+        # ARIA NOTE: commented out in 5.9.2.5
+        description: >-
+          Monitoring parameter, which can be tracked for a VNFC based on this VDU. Examples include:
+          memory-consumption, CPU-utilisation, bandwidth-consumption, VNFC downtime, etc.        
         type: tosca.capabilities.nfv.Metric
+    #requirements:
+      # ARIA NOTE: virtual_storage is TBD
+      
+      # ARIA NOTE: csd04 attempts to deprecate the inherited local_storage requirement, but this
+      # is not possible in TOSCA
+    artifacts:
+      sw_image:
+        description: >-
+          Describes the software image which is directly loaded on the virtualization container
+          realizing this virtual storage.
+        file: '' # ARIA NOTE: missing value even though it is required in TOSCA
+        type: tosca.artifacts.nfv.SwImage
 
-  tosca.nodes.nfv.CP:
+  tosca.nodes.nfv.VDU.VirtualStorage:
     _extensions:
-      shorthand_name: CP
-      type_qualified_name: tosca:CP
+      shorthand_name: VirtualStorage # ARIA NOTE: seems wrong in spec
+      type_qualified_name: tosca:VirtualStorage # ARIA NOTE: seems wrong in spec
       specification: tosca-simple-nfv-1.0
-      specification_section: 8.5.3
-      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html#_Toc419290245'
+      specification_section: 5.9.3
+      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896080'
     description: >-
-      The NFV CP node represents a logical connection point entity as defined by [ETSI GS NFV-MAN 001 v1.1.1]. A connection point
-      may be, for example, a virtual port, a virtual NIC address, a physical port, a physical NIC address or the endpoint of an IP
-      VPN enabling network connectivity. It is assumed that each type of connection point will be modeled using subtypes of the CP
-      type.
-    derived_from: tosca.nodes.network.Port
+      The NFV VirtualStorage node type represents a virtual storage entity which it describes the
+      deployment and operational behavior of a virtual storage resources, as defined by
+      [ETSI NFV IFA011].
+    derived_from: tosca.nodes.Root
     properties:
-      type:
+      type_of_storage:
         description: >-
-          This may be, for example, a virtual port, a virtual NIC address, a SR-IOV port, a physical port, a physical NIC address
-          or the endpoint of an IP VPN enabling network connectivity.
+          Type of virtualized storage resource.
         type: string
-      anti_spoof_protection:
+        required: true
+      size_of_storage:
         description: >-
-          Indicates of whether anti-spoofing rule need to be enabled for this vNIC. This is applicable only when CP type is virtual
-          NIC (vPort).
+          Size of virtualized storage resource (in GB).
+        type: scalar-unit.size
+        required: true
+      rdma_enabled:
+        description: >-
+          Indicate if the storage support RDMA.
         type: boolean
         required: false
-    attributes:
-      address:
+    artifacts:
+      sw_image:
         description: >-
-          The actual virtual NIC address that is been assigned when instantiating the connection point.
-        type: string
-    requirements:
-      - virtual_link:
-          capability: tosca.capabilities.nfv.VirtualLinkable
-          relationship: tosca.relationships.nfv.VirtualLinksTo
-      - virtual_binding:
-          capability: tosca.capabilities.nfv.VirtualBindable
-          relationship: tosca.relationships.nfv.VirtualBindsTo
+          Describes the software image which is directly loaded on the virtualization container
+          realizing this virtual storage.
+        file: '' # ARIA NOTE: missing in spec
+        type: tosca.artifacts.nfv.SwImage
 
-  tosca.nodes.nfv.FP:
+  tosca.nodes.nfv.Cpd:
     _extensions:
-      shorthand_name: FP # ARIA NOTE: the spec must be mistaken here, says "VL"
-      type_qualified_name: tosca:FP
+      shorthand_name: Cpd
+      type_qualified_name: tosca:Cpd
       specification: tosca-simple-nfv-1.0
-      specification_section: 10.5.1
-      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html#_Toc447714722'
+      specification_section: 5.9.4
+      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896081'
     description: >-
-      The NFV FP node type represents a logical network forwarding path entity as defined by [ETSI GS NFV-MAN 001 v1.1.1].
+      The TOSCA nfv.Cpd node represents network connectivity to a compute resource or a VL as defined
+      by [ETSI GS NFV-IFA 011]. This is an abstract type used as parent for the various Cpd types.
     derived_from: tosca.nodes.Root
     properties:
-      policy:
+      layer_protocol:
         description: >-
-          A policy or rule to apply to the NFP
+          Identifies which protocol the connection point uses for connectivity purposes.
         type: string
+        constraints:
+          - valid_values: [ ethernet, mpls, odu2, ipv4, ipv6, pseudo_wire ]
         required: false
-    requirements:
-      - forwarder:
-          capability: tosca.capabilities.nfv.Forwarder
-
-  #
-  # Virtual link
-  #
-
-  tosca.nodes.nfv.VL:
-    _extensions:
-      shorthand_name: VL
-      type_qualified_name: tosca:VL
-      specification: tosca-simple-nfv-1.0
-      specification_section: 9.1
-      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html#_Toc419290251'
-    description: >-
-      The NFV VL node type represents a logical virtual link entity as defined by [ETSI GS NFV-MAN 001 v1.1.1]. It is the default
-      type from which all other virtual link types derive.
-    derived_from: tosca.nodes.network.Network
-    properties:
-      vendor:
+      role: # Name in ETSI NFV IFA011 v0.7.3 cpRole
         description: >-
-          Vendor generating this VLD.
+          Identifies the role of the port in the context of the traffic flow patterns in the VNF or
+          parent NS. For example a VNF with a tree flow pattern within the VNF will have legal
+          cpRoles of ROOT and LEAF.
         type: string
-    capabilities:
-      virtual_linkable:
-        type: tosca.capabilities.nfv.VirtualLinkable        
-
-  tosca.nodes.nfv.VL.ELine:
-    _extensions:
-      shorthand_name: VL.ELine # ARIA NOTE: ommitted in the spec
-      type_qualified_name: tosca:VL.ELine
-      specification: tosca-simple-nfv-1.0
-      specification_section: 9.2
-      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html#_Toc419290256'
-    description: >-
-      The NFV VL.ELine node represents an E-Line virtual link entity.
-    derived_from: tosca.nodes.nfv.VL  
-    capabilities:
-      virtual_linkable:
-        type: tosca.capabilities.nfv.VirtualLinkable
-        occurrences: [ 2, UNBOUNDED ] # ARIA NOTE: the spec is wrong here, must be a range
+        constraints:
+          - valid_values: [ root, leaf ]
+        required: false
+      description:
+        description: >-
+          Provides human-readable information on the purpose of the connection point
+          (e.g. connection point for control plane traffic).
+        type: string
+        required: false
+      address_data:
+        description: >-
+          Provides information on the addresses to be assigned to the connection point(s) instantiated
+          from this Connection Point Descriptor.
+        type: list
+        entry_schema:
+          type: tosca.datatypes.nfv.AddressData
+        required: false
 
-  tosca.nodes.nfv.VL.ELAN:
+  tosca.nodes.nfv.VduCpd:
     _extensions:
-      shorthand_name: VL.ELAN # ARIA NOTE: ommitted in the spec
-      type_qualified_name: tosca:VL.ELAN
-      specification: tosca-simple-nfv-1.0
-      specification_section: 9.3
-      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html#_Toc419290257'
+       shorthand_name: VduCpd
+       type_qualified_name: tosca:VduCpd
+       specification: tosca-simple-nfv-1.0
+       specification_section: 5.9.5
+       specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896082'
     description: >-
-      The NFV VL.ELan node represents an E-LAN virtual link entity.
-    derived_from: tosca.nodes.network.Network
+      The TOSCA nfv.VduCpd node type represents a type of TOSCA Cpd node and describes network
+      connectivity between a VNFC instance (based on this VDU) and an internal VL as defined by
+      [ETSI GS NFV-IFA 011].
+    derived_from: tosca.nodes.nfv.Cpd
+    properties:
+      bitrate_requirement:
+        description: >-
+          Bitrate requirement on this connection point.
+        type: integer
+        required: false
+      virtual_network_interface_requirements:
+        description: >-
+          Specifies requirements on a virtual network interface realising the CPs instantiated from
+          this CPD.
+        type: list
+        entry_schema:
+          type: VirtualNetworkInterfaceRequirements
+        required: false
+    requirements:
+     # ARIA NOTE: seems to be a leftover from csd03
+     # - virtual_link:
+     #     description: Describes the requirements for linking to virtual link
+     #     capability: tosca.capabilities.nfv.VirtualLinkable
+     #     relationship: tosca.relationships.nfv.VirtualLinksTo
+     #     node: tosca.nodes.nfv.VnfVirtualLinkDesc
+      - virtual_binding:
+          capability: tosca.capabilities.nfv.VirtualBindable
+          relationship: tosca.relationships.nfv.VirtualBindsTo
+          node: tosca.nodes.nfv.VDU.Compute # ARIA NOTE: seems wrong in spec
 
-  tosca.nodes.nfv.VL.ETree:
+  tosca.nodes.nfv.VnfVirtualLinkDesc:
     _extensions:
-      shorthand_name: VL.ETree # ARIA NOTE: ommitted in the spec
-      type_qualified_name: tosca:VL.ETree
-      specification: tosca-simple-nfv-1.0
-      specification_section: 9.4
-      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html#_Toc419290258'
+       shorthand_name: VnfVirtualLinkDesc
+       type_qualified_name: tosca:VnfVirtualLinkDesc
+       specification: tosca-simple-nfv-1.0
+       specification_section: 5.9.6
+       specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896083'
     description: >-
-      The NFV VL.ETree node represents an E-Tree virtual link entity.
-    derived_from: tosca.nodes.nfv.VL
+      The TOSCA nfv.VnfVirtualLinkDesc node type represents a logical internal virtual link as
+      defined by [ETSI GS NFV-IFA 011].
+    derived_from: tosca.nodes.Root
+    properties:
+      connectivity_type:
+        description: >-
+          specifies the protocol exposed by the VL and the flow pattern supported by the VL.
+        type: tosca.datatypes.nfv.ConnectivityType
+        required: true
+      description:
+        description: >-
+          Provides human-readable information on the purpose of the VL (e.g. control plane traffic).
+        type: string
+        required: false
+      test_access:
+        description: >-
+          Test access facilities available on the VL (e.g. none, passive, monitoring, or active
+          (intrusive) loopbacks at endpoints.
+        type: string
+        required: false

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1e883c57/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/relationships.yaml
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/relationships.yaml b/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/relationships.yaml
index b745735..4cf99a2 100644
--- a/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/relationships.yaml
+++ b/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/relationships.yaml
@@ -20,45 +20,24 @@ relationship_types:
       shorthand_name: VirtualBindsTo
       type_qualified_name: tosca:VirtualBindsTo
       specification: tosca-simple-nfv-1.0
-      specification_section: 8.4.1
-      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html#_Toc419290234'
+      specification_section: 5.7.1
+      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896074'
     description: >-
       This relationship type represents an association relationship between VDU and CP node types.
     derived_from: tosca.relationships.DependsOn
     valid_target_types: [ tosca.capabilities.nfv.VirtualBindable ]
 
+  # ARIA NOTE: csd04 lacks the definition of tosca.relationships.nfv.Monitor (the derived_from and
+  # valid_target_types), so we are using the definition in csd03 section 8.4.2.
   tosca.relationships.nfv.Monitor:
     _extensions:
       shorthand_name: Monitor
       type_qualified_name: tosca:Monitor
       specification: tosca-simple-nfv-1.0
-      specification_section: 8.4.2
-      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html#_Toc418607880'
+      specification_section: 5.7.2
+      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html#_Toc482896075'
     description: >-
-      This relationship type represents an association relationship to the Metric capability of VDU node types.
+      This relationship type represents an association relationship to the Metric capability of VDU
+      node types.
     derived_from: tosca.relationships.ConnectsTo
     valid_target_types: [ tosca.capabilities.nfv.Metric ]
-
-  tosca.relationships.nfv.ForwardsTo:
-    _extensions:
-      shorthand_name: ForwardsTo
-      type_qualified_name: tosca:ForwardsTo
-      specification: tosca-simple-nfv-1.0
-      specification_section: 10.4.1
-      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html#_Toc447714720'
-    description: >-
-      This relationship type represents a traffic flow between two connection point node types.
-    derived_from: tosca.relationships.Root
-    valid_target_types: [ tosca.capabilities.nfv.Forwarder ]
-
-  tosca.relationships.nfv.VirtualLinksTo:
-    _extensions:
-      shorthand_name: VirtualLinksTo
-      type_qualified_name: tosca:VirtualLinksTo
-      specification: tosca-simple-nfv-1.0
-      specification_section: 11.4.1
-      specification_url: 'http://docs.oasis-open.org/tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html#_Toc447714737'
-    description: >-
-      This relationship type represents an association relationship between VNFs and VL node types.
-    derived_from: tosca.relationships.DependsOn
-    valid_target_types: [ tosca.capabilities.nfv.VirtualLinkable ]

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1e883c57/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/tosca-simple-nfv-1.0.yaml
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/tosca-simple-nfv-1.0.yaml b/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/tosca-simple-nfv-1.0.yaml
index 911ff3b..764c739 100644
--- a/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/tosca-simple-nfv-1.0.yaml
+++ b/extensions/aria_extension_tosca/profiles/tosca-simple-nfv-1.0/tosca-simple-nfv-1.0.yaml
@@ -14,8 +14,8 @@
 # limitations under the License.
 
 imports:
+  - artifacts.yaml
   - capabilities.yaml
   - data.yaml
-  - groups.yaml
   - nodes.yaml
   - relationships.yaml