Merge pull request #227 from djay87/master

ARIA-118 plugin.yaml importing
diff --git a/aria/core.py b/aria/core.py
index e3b3b36..d526885 100644
--- a/aria/core.py
+++ b/aria/core.py
@@ -21,6 +21,7 @@
 from .parser import consumption
 from .parser.loading.location import UriLocation
 from .orchestrator import topology
+from .utils import collections
 
 
 class Core(object):
@@ -46,16 +47,17 @@
         return self._plugin_manager
 
     def validate_service_template(self, service_template_path):
-        self._parse_service_template(service_template_path)
+        self.parse_service_template(service_template_path)
 
     def create_service_template(self, service_template_path, service_template_dir,
                                 service_template_name):
-        context = self._parse_service_template(service_template_path)
+        context = self.parse_service_template(service_template_path)
         service_template = context.modeling.template
         service_template.name = service_template_name
         self.model_storage.service_template.put(service_template)
         self.resource_storage.service_template.upload(
             entry_id=str(service_template.id), source=service_template_dir)
+        return service_template
 
     def delete_service_template(self, service_template_id):
         service_template = self.model_storage.service_template.get(service_template_id)
@@ -114,10 +116,12 @@
 
         self.model_storage.service.delete(service)
 
-    @staticmethod
-    def _parse_service_template(service_template_path):
+    def parse_service_template(self, service_template_path):
+        plugin_dir = self.plugin_manager._plugins_dir
         context = consumption.ConsumptionContext()
         context.presentation.location = UriLocation(service_template_path)
+        #Add plugin resource storage to import location prefixes
+        context.loading.prefixes = collections.StrictList([plugin_dir])
         # Most of the parser uses the topology package in order to manipulate the models.
         # However, here we use the Consumer mechanism, but this should change in the future.
         consumption.ConsumerChain(
diff --git a/extensions/aria_extension_tosca/simple_v1_0/presenter.py b/extensions/aria_extension_tosca/simple_v1_0/presenter.py
index e84decc..fef30d1 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/presenter.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/presenter.py
@@ -38,6 +38,8 @@
     SIMPLE_PROFILE_LOCATION = 'tosca-simple-1.0/tosca-simple-1.0.yaml'
     SPECIAL_IMPORTS = {
         'aria-1.0': 'aria-1.0/aria-1.0.yaml'}
+    PLUGIN_IMPORT_FILE = '/plugin.yaml'
+    PLUGIN_REPOSITORY = 'plugins'
 
     @property
     @cachedmethod
@@ -74,7 +76,12 @@
             import_locations.append(self.SIMPLE_PROFILE_LOCATION)
         imports = self._get('service_template', 'imports')
         if imports:
-            import_locations += [self.SPECIAL_IMPORTS.get(i.file, i.file) for i in imports]
+            for i in imports:
+                if i.repository == self.PLUGIN_REPOSITORY:
+                    #Add plugin.yaml from plugin resource storage to import locations
+                    import_locations += [i.file + self.PLUGIN_IMPORT_FILE]
+                else:
+                    import_locations += [self.SPECIAL_IMPORTS.get(i.file, i.file)]
         return FrozenList(import_locations) if import_locations else EMPTY_READ_ONLY_LIST
 
     @cachedmethod
diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/test_imports.py b/tests/extensions/aria_extension_tosca/simple_v1_0/test_imports.py
index 07a0d9b..d15edf7 100644
--- a/tests/extensions/aria_extension_tosca/simple_v1_0/test_imports.py
+++ b/tests/extensions/aria_extension_tosca/simple_v1_0/test_imports.py
@@ -16,6 +16,7 @@
 
 import pytest
 
+from tests.helpers import get_resource_uri
 from . import data
 from ....mechanisms.web_server import WebServer
 
@@ -38,6 +39,8 @@
     derived_from: UnknownType
 """
 
+PLUGIN_RESOURCES = "plugins"
+
 @pytest.fixture(scope='session')
 def repository():
     repository = WebServer()
@@ -146,6 +149,21 @@
       type: MyNode
 """, dict(repository=repository)).assert_success()
 
+#Plugin
+#Test case for importing plugin.yaml files via 'plugins' repository
+def test_import_plugin(parser):
+    plugin_dir = get_resource_uri(PLUGIN_RESOURCES)
+    parser.parse_literal("""
+tosca_definitions_version: tosca_simple_yaml_1_0
+imports:
+  - aria-1.0
+  - file: import-plugin-1.0.0
+    repository: plugins
+topology_template:
+  node_templates:
+    Network:
+      type: myapp.nodes.Network
+""", plugin_dir=plugin_dir).assert_success()
 
 # Namespace
 
diff --git a/tests/mechanisms/parsing/aria.py b/tests/mechanisms/parsing/aria.py
index 67adcc9..77ea975 100644
--- a/tests/mechanisms/parsing/aria.py
+++ b/tests/mechanisms/parsing/aria.py
@@ -24,6 +24,7 @@
     ServiceTemplate
 )
 from aria.utils.imports import import_fullname
+from aria.utils import collections
 
 from . import (Parser, Parsed)
 
@@ -32,6 +33,7 @@
     def _parse_literal(self, text, **kwargs):
         context = AriaParser.create_context(import_profile=kwargs.get('import_profile', False),
                                             adhoc_inputs=kwargs.get('adhoc_inputs', True),
+                                            plugin_dir=kwargs.get('plugin_dir', None),
                                             validate_normative=kwargs.get('validate_normative',
                                                                           False))
         context.presentation.location = LiteralLocation(text)
@@ -52,6 +54,7 @@
                        cache=True,
                        import_profile=None,
                        adhoc_inputs=None,
+                       plugin_dir=None,
                        validate_normative=None):
         context = ConsumptionContext()
         context.loading.loader_source = import_fullname(loader_source)()
@@ -66,6 +69,8 @@
             context.presentation.configuration['tosca.adhoc_inputs'] = adhoc_inputs
         if validate_normative is not None:
             context.presentation.configuration['validate_normative'] = validate_normative
+        if plugin_dir:
+            context.loading.prefixes = collections.StrictList([plugin_dir])
         context.presentation.print_exceptions = debug
         return context
 
diff --git a/tests/resources/plugins/import-plugin-1.0.0/plugin.yaml b/tests/resources/plugins/import-plugin-1.0.0/plugin.yaml
new file mode 100644
index 0000000..9f7fe21
--- /dev/null
+++ b/tests/resources/plugins/import-plugin-1.0.0/plugin.yaml
@@ -0,0 +1,16 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+
+topology_template:
+
+  policies:
+    import-plugin:
+      description: >-
+        plugin to test import of plugin.yaml.
+      type: aria.Plugin
+      properties:
+        version: 1.0.0
+
+node_types:
+
+  myapp.nodes.Network: {}