Azure-plugin not sending REST calls to Azure cloud 19/71319/1
authorVidisha <Vidisha.De@amdocs.com>
Fri, 26 Oct 2018 15:07:28 +0000 (18:07 +0300)
committerVidisha <Vidisha.De@amdocs.com>
Fri, 26 Oct 2018 15:10:03 +0000 (18:10 +0300)
Change-Id: I2179d1a99f3fdede34c7f21069b3af2fcaf6776c
Issue-ID: MULTICLOUD-385
Signed-off-by: Vidisha <Vidisha.De@amdocs.com>
20 files changed:
azure/aria/aria-extension-cloudify/src/aria/aria/orchestrator/workflow_runner.py
azure/aria/aria-rest-server/VERSION [new file with mode: 0644]
azure/aria/aria-rest-server/build.py [new file with mode: 0644]
azure/aria/aria-rest-server/pom.xml [new file with mode: 0644]
azure/aria/aria-rest-server/setup.py [new file with mode: 0644]
azure/aria/aria-rest-server/src/main/python/aria-rest/LICENSE [new file with mode: 0644]
azure/aria/aria-rest-server/src/main/python/aria-rest/__init__.py [new file with mode: 0644]
azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/__init__.py [new file with mode: 0644]
azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/rest.py [new file with mode: 0644]
azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/templates/index.html [new file with mode: 0644]
azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/util.py [new file with mode: 0644]
azure/aria/aria-rest-server/src/main/python/aria-rest/rest.py [new file with mode: 0644]
azure/aria/aria-rest-server/src/main/python/aria-rest/setup.py [new file with mode: 0644]
azure/aria/aria-rest-server/src/main/python/aria-rest/templates/index.html [new file with mode: 0644]
azure/docker/Dockerfile
azure/multicloud_azure/pub/aria/service.py
azure/multicloud_azure/pub/config/config.py
azure/multicloud_azure/pub/utils/restcall.py
azure/multicloud_azure/tests/test_aria_view.py
azure/run.sh

index 0c52e32..eb4efeb 100644 (file)
@@ -30,6 +30,7 @@ from ..modeling import models
 from ..modeling import utils as modeling_utils
 from ..utils.imports import import_fullname
 
+
 DEFAULT_TASK_MAX_ATTEMPTS = 30
 DEFAULT_TASK_RETRY_INTERVAL = 30
 
@@ -68,30 +69,24 @@ class WorkflowRunner(object):
         self._resource_storage = resource_storage
 
         # the IDs are stored rather than the models themselves, so this module could be used
-        # by several threads without raising errors on model objects shared between threadsF
+        # by several threads without raising errors on model objects shared between threads
 
         if self._is_resume:
-            self._service_id = service_id
-            # self._service_id = self.execution.service.id
-            # self._workflow_name = model_storage.execution.get(self._execution_id).workflow_name
-            self._workflow_name = workflow_name
-            self._validate_workflow_exists_for_service()
             self._execution_id = execution_id
-
+            self._service_id = self.execution.service.id
+            self._workflow_name = model_storage.execution.get(self._execution_id).workflow_name
         else:
             self._service_id = service_id
             self._workflow_name = workflow_name
             self._validate_workflow_exists_for_service()
             self._execution_id = self._create_execution_model(inputs).id
 
-        self._create_execution_model(inputs, execution_id)
-
         self._workflow_context = WorkflowContext(
             name=self.__class__.__name__,
             model_storage=self._model_storage,
             resource_storage=resource_storage,
             service_id=service_id,
-            execution_id=execution_id,
+            execution_id=self._execution_id,
             workflow_name=self._workflow_name,
             task_max_attempts=task_max_attempts,
             task_retry_interval=task_retry_interval)
@@ -100,13 +95,13 @@ class WorkflowRunner(object):
         executor = executor or ProcessExecutor(plugin_manager=plugin_manager)
 
         # 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.itervalues())
+        execution_inputs_dict = dict(inp.unwrapped for inp in self.execution.inputs.itervalues())
 
-        if not self._is_resume:
-            workflow_fn = self._get_workflow_fn()
-            self._tasks_graph = workflow_fn(ctx=self._workflow_context, **execution_inputs_dict)
-            compiler = graph_compiler.GraphCompiler(self._workflow_context, executor.__class__)
-            compiler.compile(self._tasks_graph)
+        if not self._is_resume:
+            workflow_fn = self._get_workflow_fn()
+            self._tasks_graph = workflow_fn(ctx=self._workflow_context, **execution_inputs_dict)
+            compiler = graph_compiler.GraphCompiler(self._workflow_context, executor.__class__)
+            compiler.compile(self._tasks_graph)
 
         self._engine = engine.Engine(executors={executor.__class__: executor})
 
@@ -116,7 +111,7 @@ class WorkflowRunner(object):
 
     @property
     def execution(self):
-        return self._model_storage.execution.get(self._execution_id)
+        return self._model_storage.execution.get(self.execution_id)
 
     @property
     def service(self):
@@ -130,7 +125,7 @@ class WorkflowRunner(object):
     def cancel(self):
         self._engine.cancel_execution(ctx=self._workflow_context)
 
-    def _create_execution_model(self, inputs, execution_id):
+    def _create_execution_model(self, inputs):
         execution = models.Execution(
             created_at=datetime.utcnow(),
             service=self.service,
@@ -148,7 +143,6 @@ class WorkflowRunner(object):
                                                              supplied_inputs=inputs or {})
         execution.inputs = modeling_utils.merge_parameter_values(
             inputs, workflow_inputs, model_cls=models.Input)
-        execution.id = execution_id
         # TODO: these two following calls should execute atomically
         self._validate_no_active_executions(execution)
         self._model_storage.execution.put(execution)
@@ -156,17 +150,17 @@ class WorkflowRunner(object):
 
     def _validate_workflow_exists_for_service(self):
         if self._workflow_name not in self.service.workflows and \
-                self._workflow_name not in builtin.BUILTIN_WORKFLOWS:
+                        self._workflow_name not in builtin.BUILTIN_WORKFLOWS:
             raise exceptions.UndeclaredWorkflowError(
                 'No workflow policy {0} declared in service {1}'
-                    .format(self._workflow_name, self.service.name))
+                .format(self._workflow_name, self.service.name))
 
     def _validate_no_active_executions(self, execution):
         active_executions = [e for e in self.service.executions if e.is_active()]
         if active_executions:
             raise exceptions.ActiveExecutionsError(
                 "Can't start execution; Service {0} has an active execution with ID {1}"
-                    .format(self.service.name, active_executions[0].id))
+                .format(self.service.name, active_executions[0].id))
 
     def _get_workflow_fn(self):
         if self._workflow_name in builtin.BUILTIN_WORKFLOWS:
diff --git a/azure/aria/aria-rest-server/VERSION b/azure/aria/aria-rest-server/VERSION
new file mode 100644 (file)
index 0000000..f755149
--- /dev/null
@@ -0,0 +1 @@
+1.0.0-SNAPSHOT
diff --git a/azure/aria/aria-rest-server/build.py b/azure/aria/aria-rest-server/build.py
new file mode 100644 (file)
index 0000000..cd2bcbf
--- /dev/null
@@ -0,0 +1,95 @@
+#
+# ============LICENSE_START===================================================
+# Copyright (c) 2018 Amdocs.  All rights reserved.
+# ===================================================================
+# Licensed 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.
+# ============LICENSE_END====================================================
+#
+
+import subprocess
+import os
+import sys
+import glob
+import xml.etree.ElementTree as etree
+
+# create and enter venv
+def create_venv( name):
+    if subprocess.call("virtualenv {}".format(name), shell = True):
+        raise Exception("virtualenv create failed")
+    ret = subprocess.call(". {}/bin/activate && python {} run". \
+                    format(name,__file__), shell = True)
+    sys.exit(ret)
+
+def init_venv():
+    subprocess.call("pip install -U pip", shell = True)
+    subprocess.call("pip install -U setuptools", shell = True)
+    subprocess.call("pip install wheel", shell = True)
+    subprocess.call("pip install twine", shell = True)
+
+
+if len(sys.argv) == 1:
+    create_venv ("mavenvenv")
+else:
+    init_venv()
+
+    if os.environ['MVN_PHASE'] == 'package':
+        wheelname = os.environ['WHEEL_NAME']
+        inputdir = os.environ['INPUT_DIR']
+        outputdir = os.environ['OUTPUT_DIR']
+        savedir = os.getcwd()
+        os.chdir(inputdir)
+
+        if subprocess.call( [ "python",
+                             "setup.py",
+                             "bdist_wheel",
+                             "-d",
+                             outputdir
+                             ]):
+            sys.stderr("wheel create failed")
+            sys.exit(1)
+        f = glob.glob(outputdir+"/*.whl")[0]
+        os.rename(f , outputdir+"/"+ wheelname)
+
+    elif os.environ['MVN_PHASE'] == 'deploy':
+
+        it = etree.iterparse(os.environ['SETTINGS_FILE'])
+        for _, el in it:
+            el.tag = el.tag.split('}', 1)[1]  # strip namespace
+        settings = it.root
+
+        username = settings.find('.//server[id="{}"]/username'.format(
+                                os.environ['PYPI_SERVERID'])).text
+        password = settings.find('.//server[id="{}"]/password'.format(
+                                os.environ['PYPI_SERVERID'])).text
+
+        try:
+            if subprocess.call( [ "twine",
+                             "upload",
+                             "--username",
+                             username,
+                             "--password",
+                             password,
+                             "--repository-url",
+                             os.environ["PYPI_SERVER_BASEURL"],
+                             os.environ["WHEEL_PATH"]
+                             ] ):
+                sys.stderr.write("pypi upload failed")
+                sys.exit(1)
+        finally:
+            subprocess.call("rm -rf mavenvenv", shell = True)
+
+        sys.exit(0)
+    else:
+        sys.stderr.write("Unrecognized phase '{}'\n".format(
+            os.environ('MVN_PHASE')))
+        sys.exit(1)
diff --git a/azure/aria/aria-rest-server/pom.xml b/azure/aria/aria-rest-server/pom.xml
new file mode 100644 (file)
index 0000000..6bfa5c2
--- /dev/null
@@ -0,0 +1,114 @@
+<?xml version="1.0"?>
+<!--
+    /*
+    * ============LICENSE_START===================================================
+    * Copyright (c) 2018 Amdocs.  All rights reserved.
+    * ===================================================================
+    * Licensed 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.
+    * ============LICENSE_END====================================================
+    */
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>pom</packaging>
+  <groupId>org.onap.multicloud.aria</groupId>
+  <artifactId>ariarest</artifactId>
+  <name>ariarest</name>
+  <version>0.1.0-SNAPSHOT</version>
+  <description>ARIA REST API wheel build</description>
+  <parent>
+    <groupId>org.onap.multicloud.azure</groupId>
+    <artifactId>multicloud-azure</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+  </parent>
+
+  <properties>
+    <python_version>2</python_version>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <wheel.name>${project.artifactId}-${project.version}-py${python_version}-none-any.whl</wheel.name>
+    <python.sourceDirectory>${project.basedir}/src/main/python/aria-rest</python.sourceDirectory>
+    <onap.nexus.pypiserver.baseurl>http://192.168.33.1:8081/repository/pypi-internal/</onap.nexus.pypiserver.baseurl>
+    <onap.nexus.pypiserver.serverid>ecomp-snapshots</onap.nexus.pypiserver.serverid>
+  </properties>
+  <build>
+    <plugins>
+      <plugin>
+       <groupId>org.codehaus.mojo</groupId>
+       <artifactId>build-helper-maven-plugin</artifactId>
+       <version>3.0.0</version>
+       <executions>
+         <execution>
+           <id>write-python-version</id>
+           <goals>
+             <goal>regex-property</goal>
+           </goals>
+           <phase>initialize</phase>
+           <configuration>
+             <name>python_version</name>
+             <regex>-SNAPSHOT</regex>
+             <value>${project.version}</value>
+             <replacement>\.dev0</replacement>
+             <failIfNoMatch>false</failIfNoMatch>
+           </configuration>
+         </execution>
+       </executions>
+      </plugin>
+      <plugin>
+       <groupId>org.codehaus.mojo</groupId>
+       <artifactId>exec-maven-plugin</artifactId>
+       <version>1.6.0</version>
+       <executions>
+         <execution>
+            <id>package</id>
+           <phase>package</phase>
+           <goals><goal>exec</goal></goals>
+           <configuration>
+              <executable>python</executable>
+              <arguments>
+               <argument>${project.basedir}/build.py</argument>
+             </arguments>
+             <environmentVariables>
+               <MVN_PHASE>package</MVN_PHASE>
+               <WHEEL_NAME>${wheel.name}</WHEEL_NAME>
+               <INPUT_DIR>${project.basedir}/src/main/python/aria-rest</INPUT_DIR>
+               <OUTPUT_DIR>${project.build.directory}</OUTPUT_DIR>
+              </environmentVariables>
+           </configuration>
+         </execution>
+          <execution>
+            <id>deploy</id>
+           <phase>deploy</phase>
+           <goals><goal>exec</goal></goals>
+           <configuration>
+              <executable>python</executable>
+             <arguments>
+               <argument>${project.basedir}/build.py</argument>
+             </arguments>
+             <environmentVariables>
+               <MVN_PHASE>deploy</MVN_PHASE>
+                <PROJECT_VERSION>${project.version}</PROJECT_VERSION>
+               <DOCKERREGISTRY_SNAPSHOT>${onap.nexus.dockerregistry.snapshot}</DOCKERREGISTRY_SNAPSHOT>
+               <DOCKERREGISTRY_RELEASE>${onap.nexus.dockerregistry.release}</DOCKERREGISTRY_RELEASE>
+                <PYPI_SERVER_BASEURL>${onap.nexus.pypiserver.baseurl}</PYPI_SERVER_BASEURL>
+               <PYPI_SERVERID>${onap.nexus.pypiserver.serverid}</PYPI_SERVERID>
+               <WHEEL_PATH>${project.build.directory}/${wheel.name}</WHEEL_PATH>
+             </environmentVariables>
+           </configuration>
+          </execution>   
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
+
diff --git a/azure/aria/aria-rest-server/setup.py b/azure/aria/aria-rest-server/setup.py
new file mode 100644 (file)
index 0000000..1f68901
--- /dev/null
@@ -0,0 +1,41 @@
+# org.onap.dcae
+# ============LICENSE_START====================================================
+# Copyright (c) 2018 Amdocs. All rights reserved.
+# =============================================================================
+# Licensed 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.
+# ============LICENSE_END======================================================
+#
+# ECOMP is a trademark and service mark of AT&T Intellectual Property.
+
+from setuptools import setup, find_packages
+
+try:
+  with open('VERSION') as v_file:
+    version = v_file.read().strip()
+except IOError:
+    print "There was a problem parsing the VERSION file."
+
+setup(
+  name='aria-rest-server',
+  version=version,
+  packages=find_packages(),
+  author = '',
+  author_email = '',
+  description = ('Library for ...'),
+  license = 'Apache 2.0',
+  keywords = '',
+  url = '',
+  zip_safe = True,
+  install_requires=[],
+  entry_points = {}
+)
diff --git a/azure/aria/aria-rest-server/src/main/python/aria-rest/LICENSE b/azure/aria/aria-rest-server/src/main/python/aria-rest/LICENSE
new file mode 100644 (file)
index 0000000..48bef24
--- /dev/null
@@ -0,0 +1,18 @@
+#
+# ============LICENSE_START===================================================
+# Copyright (c) 2018 Amdocs.  All rights reserved.
+# ===================================================================
+# Licensed 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.
+# ============LICENSE_END====================================================
+#
+
diff --git a/azure/aria/aria-rest-server/src/main/python/aria-rest/__init__.py b/azure/aria/aria-rest-server/src/main/python/aria-rest/__init__.py
new file mode 100644 (file)
index 0000000..adb446c
--- /dev/null
@@ -0,0 +1,19 @@
+
+#
+# ============LICENSE_START===================================================
+# Copyright (c) 2018 Amdocs.  All rights reserved.
+# ===================================================================
+# Licensed 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.
+# ============LICENSE_END====================================================
+#
+
diff --git a/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/__init__.py b/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/__init__.py
new file mode 100644 (file)
index 0000000..adb446c
--- /dev/null
@@ -0,0 +1,19 @@
+
+#
+# ============LICENSE_START===================================================
+# Copyright (c) 2018 Amdocs.  All rights reserved.
+# ===================================================================
+# Licensed 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.
+# ============LICENSE_END====================================================
+#
+
diff --git a/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/rest.py b/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/rest.py
new file mode 100644 (file)
index 0000000..ecddff6
--- /dev/null
@@ -0,0 +1,90 @@
+#
+# ============LICENSE_START===================================================
+# Copyright (c) 2018 Amdocs. All rights reserved.
+# ===================================================================
+# Licensed 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.
+# ============LICENSE_END====================================================
+#
+
+from flask import Flask, request, jsonify
+from flask_autodoc.autodoc import Autodoc
+from aria import install_aria_extensions
+from aria.cli.core import aria
+from aria.utils import threading
+from aria.orchestrator.workflow_runner import WorkflowRunner
+from aria.orchestrator.workflows.executor.dry import DryExecutor
+import util
+
+version_id = "v0"
+route_base = "/api/multicloud-azure/" + version_id + "/"
+app = Flask("onap-aria-rest")
+auto = Autodoc(app)
+
+execution_state = util.SafeDict()
+
+
+def main():
+    install_aria_extensions()
+    app.run(host='0.0.0.0', port=5000, threaded=True)
+
+
+# start execution
+@app.route(
+    route_base +
+    "services/<service_id>/executions/<workflow_name>",
+    methods=['POST'])
+@auto.doc()
+@aria.pass_model_storage
+@aria.pass_resource_storage
+@aria.pass_plugin_manager
+@aria.pass_logger
+def start_execution(
+        service_id,
+        workflow_name,
+        model_storage,
+        resource_storage,
+        plugin_manager,
+        logger):
+    """
+    Start an execution for the specified service
+    """
+    body = request.json or {}
+    executor = DryExecutor(
+        ) if 'executor' in body and body['executor'] == 'dry' else None
+
+    inputs = body['inputs'] if 'inputs' in body else None
+    task_max_attempts = (body['task_max_attempts']
+                         if 'task_max_attempts' in body else 30)
+    task_retry_interval = (body['task_retry_interval']
+                           if 'task_retry_interval' in body else 30)
+
+    runner = WorkflowRunner(model_storage, resource_storage, plugin_manager,
+                            service_id=service_id,
+                            workflow_name=workflow_name,
+                            inputs=inputs,
+                            executor=executor,
+                            task_max_attempts=task_max_attempts,
+                            task_retry_interval=task_retry_interval)
+
+    service = model_storage.service.get(service_id)
+    tname = '{}_{}_{}'.format(service.name, workflow_name, runner.execution_id)
+    thread = threading.ExceptionThread(target=runner.execute,
+                                       name=tname)
+    thread.start()
+    execution_state[str(runner.execution_id)] = [runner, thread]
+    logger.info("execution {} started".format(runner.execution_id))
+    return jsonify({"id": runner.execution_id}), 202
+
+
+if __name__ == "__main__":
+    app.run(host='0.0.0.0', port=5000, threaded=True)
diff --git a/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/templates/index.html b/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/templates/index.html
new file mode 100644 (file)
index 0000000..932a6b1
--- /dev/null
@@ -0,0 +1,23 @@
+<!--
+#
+# ============LICENSE_START===================================================
+# Copyright (c) 2018 Amdocs.  All rights reserved.
+# ===================================================================
+# Licensed 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.
+# ============LICENSE_END====================================================
+#
+-->
+
+<body>
+<h1>Not Implemented</h1>
+</body>
diff --git a/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/util.py b/azure/aria/aria-rest-server/src/main/python/aria-rest/aria_rest/util.py
new file mode 100644 (file)
index 0000000..ecd46b1
--- /dev/null
@@ -0,0 +1,48 @@
+#
+# ============LICENSE_START===================================================
+# Copyright (c) 2018 Amdocs.  All rights reserved.
+# ===================================================================
+# Licensed 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.
+# ============LICENSE_END====================================================
+#
+
+
+import threading
+
+
+def make_template_name(user, template_name):
+    return "{}.{}".format(user, template_name)
+
+
+class SafeDict(dict):
+    def __init__(self, *args):
+        self._lockobj = threading.Lock()
+        dict.__init__(self, args)
+
+    def __getitem__(self, key):
+        try:
+            self._lockobj.acquire()
+            val = dict.__getitem__(self, key)
+        except:
+            raise
+        finally:
+            self._lockobj.release()
+
+    def __setitem__(self, key, value):
+        try:
+            self._lockobj.acquire()
+            dict.__setitem__(self, key, value)
+        except:
+            raise
+        finally:
+            self._lockobj.release()
diff --git a/azure/aria/aria-rest-server/src/main/python/aria-rest/rest.py b/azure/aria/aria-rest-server/src/main/python/aria-rest/rest.py
new file mode 100644 (file)
index 0000000..c0858bf
--- /dev/null
@@ -0,0 +1,57 @@
+#
+# ============LICENSE_START===================================================
+# Copyright (c) 2018 Amdocs.  All rights reserved.
+# ===================================================================
+# Licensed 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.
+# ============LICENSE_END====================================================
+#
+
+from flask import Flask, render_template
+from aria.exceptions import AriaException
+
+version_id = "0.1"
+route_base = "/api/" + version_id + "/"
+app = Flask("onap-aria-rest")
+
+@app.route("/")
+def index():
+  return render_template('index.html')
+
+
+@app.route(route_base + "templates/", methods = ['GET'])
+def list_templates():
+
+@app.route(route_base + "templates/<template_id>", methods = ['POST'])
+def install_template( template_id ):
+
+  # GET CSAR FROM SDC
+
+  # DEPLOY CSAR
+
+  # UPDATE A&AI?
+
+  return "template {} instantiated"
+
+@app.route(route_base + "templates/<template_id>", methods = ['DELETE'])
+def delete_template( template_id ):
+
+  # RUN UNINSTALL
+
+  # DELETE TEMPLATE
+
+  # UPDATE A&AI?
+
+  return "template {} deleted"
+
+if __name__ == "__main__":
+  app.run()
diff --git a/azure/aria/aria-rest-server/src/main/python/aria-rest/setup.py b/azure/aria/aria-rest-server/src/main/python/aria-rest/setup.py
new file mode 100644 (file)
index 0000000..86fd5a0
--- /dev/null
@@ -0,0 +1,42 @@
+#
+# ============LICENSE_START===================================================
+# Copyright (c) 2018 Amdocs.  All rights reserved.
+# ===================================================================
+# Licensed 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.
+# ============LICENSE_END====================================================
+#
+
+
+from setuptools import setup
+
+setup(
+    zip_safe=True,
+    name='aria-rest',
+    version='0.1',
+    author='dewayne',
+    author_email='dewayne@cloudify.co',
+    packages=[
+        'aria_rest'
+    ],
+    entry_points = {
+      'console_scripts' : ['aria-rest=aria_rest.rest:main']
+    },
+    license='LICENSE',
+    description='Aria REST API for ONAP',
+    install_requires=[
+        'distribute',
+        'Flask==0.12.2',
+        'flask-autodoc==0.1.2',
+        'apache-ariatosca==0.2.0'
+    ]
+)
diff --git a/azure/aria/aria-rest-server/src/main/python/aria-rest/templates/index.html b/azure/aria/aria-rest-server/src/main/python/aria-rest/templates/index.html
new file mode 100644 (file)
index 0000000..6d74cfc
--- /dev/null
@@ -0,0 +1,3 @@
+<body>
+<h1>Not Implemented</h1>
+</body>
index 70924e3..e7bb479 100644 (file)
@@ -10,7 +10,7 @@ ENV AAI_PASSWORD "AAI"
 ENV MR_ADDR "127.0.0.1"
 ENV MR_PORT "3904"
 
-EXPOSE 9004
+EXPOSE 9008
 
 RUN apt-get update && \
     apt-get install -y unzip && \
@@ -27,6 +27,9 @@ RUN pip install .
 WORKDIR /tmp/aria-extension-cloudify
 RUN pip install .
 
+WORKDIR /tmp/aria-rest-server/src/main/python/aria-rest
+RUN pip install .
+
 RUN pip install --force-reinstall  pip==9.0.1
 WORKDIR /tmp
 ADD docker/cloudify_azure_plugin-1.4.2-py27-none-linux_x86_64.wgn /tmp/
@@ -40,7 +43,6 @@ RUN  cd /opt/ && \
     rm -rf multicloud-azure.zip && \
     pip install -r multicloud_azure/requirements.txt
 
-
 WORKDIR /opt
 RUN chmod +x multicloud_azure/docker/*.sh && chmod +x multicloud_azure/*.sh
 ENTRYPOINT multicloud_azure/docker/docker-entrypoint.sh
index 637858a..2c99611 100644 (file)
@@ -17,13 +17,12 @@ import time
 import os
 
 from multicloud_azure.pub.aria import util
+from multicloud_azure.pub.utils.restcall import call_aria_rest
 from aria.cli.core import aria
 from aria.cli import utils
 from aria.core import Core
 from aria.cli import service_template_utils
 from aria.storage import exceptions as storage_exceptions
-from aria.utils import threading
-from aria.orchestrator.workflow_runner import WorkflowRunner as Runner
 
 LOG = logging.getLogger(__name__)
 
@@ -48,12 +47,10 @@ class AriaServiceImpl(object):
             status, template_name + time.strftime('%Y%m%d%H%M%S'), inputs)
         if (status[1] != 200):
             return status[0], status[1]
-        execution_id = time.strftime('%Y%m%d%H%M%S')
-        thread = threading.ExceptionThread(target=self.start_execution,
-                                           args=(status[2].id, execution_id,
-                                                 inputs, 'install'))
-        thread.start()
-        return execution_id, 200
+        status = call_aria_rest(status[2].id, 'install')
+        if (status[2] != "202"):
+            return status[1], status[2]
+        return json.loads(status[1])['id'], 200
 
     @aria.pass_model_storage
     @aria.pass_resource_storage
@@ -111,35 +108,6 @@ class AriaServiceImpl(object):
         logger.info("service {} created".format(service.name))
         return "service {} created".format(service.name), 200, service
 
-    @aria.pass_model_storage
-    @aria.pass_resource_storage
-    @aria.pass_plugin_manager
-    @aria.pass_logger
-    def start_execution(self, service_id, execution_id, input, workflow_name,
-                        model_storage,
-                        resource_storage,
-                        plugin_manager,
-                        logger):
-        """
-        Start an execution for the specified service
-        """
-        input = input['sdnc_directives'] if'sdnc_directives'in input else None
-        runner = Runner(model_storage, resource_storage, plugin_manager,
-                        execution_id=execution_id,
-                        service_id=service_id,
-                        workflow_name=workflow_name,
-                        inputs=input)
-
-        service = model_storage.service.get(service_id)
-        tname = '{}_{}_{}'.format(service.name, workflow_name,
-                                  runner.execution_id)
-        thread = threading.ExceptionThread(target=runner.execute,
-                                           name=tname)
-        thread.start()
-        execution_state[str(runner.execution_id)] = [runner, thread]
-        logger.info("execution {} started".format(runner.execution_id))
-        return json.dumps({"id": runner.execution_id}), 202
-
     @aria.pass_model_storage
     @aria.pass_logger
     def show_execution(self, execution_id, model_storage, logger):
index db09fd6..511f0ca 100644 (file)
@@ -39,3 +39,6 @@ FORWARDED_FOR_FIELDS = ["HTTP_X_FORWARDED_FOR", "HTTP_X_FORWARDED_HOST",
 
 # [Local Config]
 API_SERVER_PORT = 9004
+
+# [ARIA]
+ARIA_SERVER_URL = 'http://127.0.0.1:5000/api/multicloud-azure/v0'
index ff5ca6a..0b0ef33 100644 (file)
@@ -23,6 +23,7 @@ from multicloud_azure.pub.config.config import AAI_SERVICE_URL
 from multicloud_azure.pub.config.config import AAI_USERNAME
 from multicloud_azure.pub.config.config import AAI_PASSWORD
 from multicloud_azure.pub.config.config import MSB_SERVICE_IP, MSB_SERVICE_PORT
+from multicloud_azure.pub.config.config import ARIA_SERVER_URL
 
 from multicloud_azure.pub.exceptions import VimDriverAzureException
 
@@ -341,3 +342,12 @@ class AAIClient(object):
                         {'value': cloud_dpdk_info.get("libversion")})
                     })
         return ovsdpdk_capability
+
+
+def call_aria_rest(service_id, workflow_name):
+    base_url = "%s" % (ARIA_SERVER_URL)
+    resource = ("/services/%s/executions/%s" % (service_id, workflow_name))
+    headers = {}
+    headers['content-type'] = 'text/plain'
+    return call_req(base_url, "", "", rest_no_auth, resource, "POST",
+                    headers=headers)
index 69c18e7..3bbd105 100644 (file)
@@ -136,35 +136,6 @@ class WorkoadViewTest(unittest.TestCase):
                                                     plugin_manager,
                                                     logger))
 
-    @mock.patch.object(AriaServiceImpl, 'start_execution')
-    @aria.pass_model_storage
-    @aria.pass_resource_storage
-    @aria.pass_plugin_manager
-    @aria.pass_logger
-    def test_start_execution(self, mock_template_info, model_storage,
-                             resource_storage, plugin_manager, logger):
-        class Workload:
-            def __init__(self, status_id, execution_id, name, input):
-                self.status_id = status_id
-                self.execution_id = execution_id
-                self.input = input
-                self.name = name
-
-        service = Workload(1, 2, "a", "w")
-        mock_template_info.return_value = service
-
-        class Request:
-            def __init__(self, query_params):
-                self.query_params = query_params
-
-        req = Request({'k': 'v'})
-        self.assertNotEqual(200,
-                            self.fsv.start_execution(req, 123, 456, "a1", "b1",
-                                                     model_storage,
-                                                     resource_storage,
-                                                     plugin_manager,
-                                                     logger))
-
     def test_show_execution(self):
         service_op = AriaServiceImpl()
         self.assertNotEqual(200,
index babf0c9..e781063 100644 (file)
@@ -31,6 +31,7 @@ then
     python multivimbroker/scripts/api.py
 else
     # nohup python manage.py runserver 0.0.0.0:9008 2>&1 &
+    nohup aria-rest 2>&1 &
     nohup uwsgi --http :9008 --module multicloud_azure.wsgi --master --processes 4 &
     nohup python -m multicloud_azure.event_listener.server 2>&1 &