osdf rearchitecture into apps and libs 11/99611/2
authorvrvarma <vv8305@att.com>
Fri, 13 Dec 2019 15:24:55 +0000 (10:24 -0500)
committervrvarma <vv8305@att.com>
Fri, 13 Dec 2019 15:29:45 +0000 (10:29 -0500)
Change-Id: I2db2f8e252bd5e60807b2ffabf5a5b193a789f7a
Signed-off-by: vrvarma <vv8305@att.com>
Issue-ID: OPTFRA-637

83 files changed:
apps/__init__.py [moved from osdf/optimizers/pciopt/solver/__init__.py with 100% similarity]
apps/license/__init__.py [new file with mode: 0644]
apps/license/optimizers/__init__.py [new file with mode: 0644]
apps/license/optimizers/simple_license_allocation.py [moved from osdf/optimizers/licenseopt/simple_license_allocation.py with 100% similarity]
apps/pci/__init__.py [new file with mode: 0644]
apps/pci/models/__init__.py [new file with mode: 0644]
apps/pci/models/api/__init__.py [new file with mode: 0644]
apps/pci/models/api/pciOptimizationRequest.py [moved from osdf/models/api/pciOptimizationRequest.py with 97% similarity]
apps/pci/models/api/pciOptimizationResponse.py [moved from osdf/models/api/pciOptimizationResponse.py with 97% similarity]
apps/pci/optimizers/__init__.py [new file with mode: 0644]
apps/pci/optimizers/configdb.py [moved from osdf/optimizers/pciopt/configdb.py with 100% similarity]
apps/pci/optimizers/pci_opt_processor.py [moved from osdf/optimizers/pciopt/pci_opt_processor.py with 99% similarity]
apps/pci/optimizers/solver/__init__.py [new file with mode: 0644]
apps/pci/optimizers/solver/min_confusion.mzn [moved from osdf/optimizers/pciopt/solver/min_confusion.mzn with 100% similarity]
apps/pci/optimizers/solver/min_confusion_inl.mzn [moved from osdf/optimizers/pciopt/solver/min_confusion_inl.mzn with 100% similarity]
apps/pci/optimizers/solver/no_conflicts_no_confusion.mzn [moved from osdf/optimizers/pciopt/solver/no_conflicts_no_confusion.mzn with 100% similarity]
apps/pci/optimizers/solver/optimizer.py [moved from osdf/optimizers/pciopt/solver/optimizer.py with 100% similarity]
apps/pci/optimizers/solver/pci_utils.py [moved from osdf/optimizers/pciopt/solver/pci_utils.py with 100% similarity]
apps/placement/__init__.py [new file with mode: 0644]
apps/placement/models/__init__.py [new file with mode: 0644]
apps/placement/models/api/__init__.py [new file with mode: 0644]
apps/placement/models/api/placementRequest.py [moved from osdf/models/api/placementRequest.py with 98% similarity]
apps/placement/models/api/placementResponse.py [moved from osdf/models/api/placementResponse.py with 98% similarity]
apps/placement/optimizers/__init__.py [new file with mode: 0644]
apps/placement/optimizers/conductor/__init__.py [moved from osdf/optimizers/placementopt/conductor/__init__.py with 100% similarity]
apps/placement/optimizers/conductor/api_builder.py [moved from osdf/optimizers/placementopt/conductor/api_builder.py with 97% similarity]
apps/placement/optimizers/conductor/conductor.py [moved from osdf/optimizers/placementopt/conductor/conductor.py with 97% similarity]
apps/placement/optimizers/conductor/remote_opt_processor.py [moved from osdf/optimizers/placementopt/conductor/remote_opt_processor.py with 96% similarity]
apps/placement/optimizers/conductor/translation.py [moved from osdf/optimizers/placementopt/conductor/translation.py with 99% similarity]
apps/placement/templates/conductor_interface.json [moved from osdf/templates/conductor_interface.json with 100% similarity]
apps/placement/templates/plc_opt_request.jsont [moved from osdf/templates/plc_opt_request.jsont with 100% similarity]
apps/placement/templates/plc_opt_response.jsont [moved from osdf/templates/plc_opt_response.jsont with 100% similarity]
apps/placement/templates/policy_request.jsont [moved from osdf/templates/policy_request.jsont with 100% similarity]
apps/route/__init__.py [new file with mode: 0644]
apps/route/optimizers/__init__.py [new file with mode: 0644]
apps/route/optimizers/simple_route_opt.py [moved from osdf/optimizers/routeopt/simple_route_opt.py with 100% similarity]
apps/templates/cms_opt_request.jsont [moved from osdf/templates/cms_opt_request.jsont with 100% similarity]
apps/templates/cms_opt_request.jsont_1707_v1 [moved from osdf/templates/cms_opt_request.jsont_1707_v1 with 100% similarity]
apps/templates/cms_opt_request_1702.jsont [moved from osdf/templates/cms_opt_request_1702.jsont with 100% similarity]
apps/templates/cms_opt_response.jsont [moved from osdf/templates/cms_opt_response.jsont with 100% similarity]
apps/templates/license_opt_request.jsont [moved from osdf/templates/license_opt_request.jsont with 100% similarity]
apps/templates/test_cms_nb_req_from_client.jsont [moved from osdf/templates/test_cms_nb_req_from_client.jsont with 100% similarity]
apps/templates/test_plc_nb_req_from_client.jsont [moved from osdf/templates/test_plc_nb_req_from_client.jsont with 100% similarity]
assembly.xml
docker/Dockerfile
docker/assembly/osdf-files.xml [new file with mode: 0644]
osdf/apps/__init__.py [new file with mode: 0644]
osdf/apps/baseapp.py [new file with mode: 0644]
osdf/config/__init__.py
osdf/logging/osdf_logging.py
osdf/utils/mdc_utils.py
osdfapp.py
pom.xml
requirements.txt
script/TagVersion.groovy [new file with mode: 0644]
test/conductor/test_conductor_calls.py
test/conductor/test_conductor_translation.py
test/config/log.yml [new file with mode: 0644]
test/configdb/test_configdb_calls.py
test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Affinity_vCPE_1.json
test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Capacity_vGMuxInfra.json
test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Capacity_vG_1.json
test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Distance_vGMuxInfra_1.json
test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Distance_vG_1.json
test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/Placement_Optimization_1.json
test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/QueryPolicy_vCPE.json
test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/QueryPolicy_vCPE_2.json
test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/hpa_policy_vGMuxInfra_1.json
test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/hpa_policy_vG_1.json
test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/vnfPolicy_vG.json
test/functest/simulators/policy/response-payloads/pdp-has-vcpe-good/vnfPolicy_vGMuxInfra.json
test/functest/simulators/simulated-config/log.yml [new file with mode: 0644]
test/mainapp/test_osdfapp.py
test/policy/test_policy_interface.py
test/test_ConductorApiBuilder.py
test/test_PolicyCalls.py
test/test_api_validation.py
test/test_get_opt_query_data.py
test/test_process_pci_anr_opt.py
test/test_process_pci_opt.py
test/test_process_placement_opt.py
test/test_so_response_gen.py
tox.ini

diff --git a/apps/license/__init__.py b/apps/license/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/apps/license/optimizers/__init__.py b/apps/license/optimizers/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/apps/pci/__init__.py b/apps/pci/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/apps/pci/models/__init__.py b/apps/pci/models/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/apps/pci/models/api/__init__.py b/apps/pci/models/api/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
similarity index 97%
rename from osdf/models/api/pciOptimizationRequest.py
rename to apps/pci/models/api/pciOptimizationRequest.py
index f5ec6b7..02b67a2 100644 (file)
@@ -19,7 +19,7 @@
 from schematics.types import BaseType, StringType, URLType, IntType
 from schematics.types.compound import ModelType, ListType, DictType
 
-from .common import OSDFModel
+from osdf.models.api.common import OSDFModel
 
 
 class RequestInfo(OSDFModel):
similarity index 97%
rename from osdf/models/api/pciOptimizationResponse.py
rename to apps/pci/models/api/pciOptimizationResponse.py
index 71d0986..019a43a 100644 (file)
@@ -19,7 +19,7 @@
 from schematics.types import StringType, IntType
 from schematics.types.compound import ModelType, ListType
 
-from .common import OSDFModel
+from osdf.models.api.common import OSDFModel
 
 
 class PCISolution(OSDFModel):
diff --git a/apps/pci/optimizers/__init__.py b/apps/pci/optimizers/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
similarity index 99%
rename from osdf/optimizers/pciopt/pci_opt_processor.py
rename to apps/pci/optimizers/pci_opt_processor.py
index 47c4288..9948d55 100644 (file)
@@ -18,6 +18,7 @@
 
 import traceback
 
+from onaplogging.mdcContext import MDC
 from requests import RequestException
 
 from osdf.logging.osdf_logging import metrics_log, MH, error_log
diff --git a/apps/pci/optimizers/solver/__init__.py b/apps/pci/optimizers/solver/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/apps/placement/__init__.py b/apps/placement/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/apps/placement/models/__init__.py b/apps/placement/models/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/apps/placement/models/api/__init__.py b/apps/placement/models/api/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
similarity index 98%
rename from osdf/models/api/placementRequest.py
rename to apps/placement/models/api/placementRequest.py
index a10ddc3..a0941cf 100644 (file)
@@ -16,7 +16,7 @@
 # -------------------------------------------------------------------------
 #
 
-from .common import OSDFModel
+from osdf.models.api.common import OSDFModel
 from schematics.types import BaseType, StringType, URLType, IntType, BooleanType
 from schematics.types.compound import ModelType, ListType, DictType
 
similarity index 98%
rename from osdf/models/api/placementResponse.py
rename to apps/placement/models/api/placementResponse.py
index 063a9a8..13b8d7a 100644 (file)
@@ -16,7 +16,7 @@
 # -------------------------------------------------------------------------
 #
 
-from .common import OSDFModel
+from osdf.models.api.common import OSDFModel
 from schematics.types import BaseType, StringType
 from schematics.types.compound import ModelType, ListType, DictType
 
diff --git a/apps/placement/optimizers/__init__.py b/apps/placement/optimizers/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
@@ -20,7 +20,7 @@ import json
 
 from jinja2 import Template
 
-import osdf.optimizers.placementopt.conductor.translation as tr
+import apps.placement.optimizers.conductor.translation as tr
 from osdf.adapters.policy.utils import group_policies_gen
 from osdf.utils.programming_utils import list_flatten
 
@@ -49,7 +49,7 @@ def _build_parameters(group_policies, request_json):
 
 
 def conductor_api_builder(request_json, flat_policies: list, local_config,
-                          template="osdf/templates/conductor_interface.json"):
+                          template="apps/placement/templates/conductor_interface.json"):
     """Build an OSDF southbound API call for HAS-Conductor/Placement optimization
     :param request_json: parameter data received from a client
     :param flat_policies: policy data received from the policy platform (flat policies)
@@ -26,8 +26,8 @@ import time
 from jinja2 import Template\r
 from requests import RequestException\r
 \r
+from apps.placement.optimizers.conductor.api_builder import conductor_api_builder\r
 from osdf.logging.osdf_logging import debug_log\r
-from osdf.optimizers.placementopt.conductor.api_builder import conductor_api_builder\r
 from osdf.utils.interfaces import RestClient\r
 from osdf.operation.exceptions import BusinessException\r
 \r
@@ -21,8 +21,8 @@ from requests import RequestException
 import traceback
 from osdf.operation.error_handling import build_json_error_body
 from osdf.logging.osdf_logging import metrics_log, MH, error_log
-from osdf.optimizers.placementopt.conductor import conductor
-from osdf.optimizers.licenseopt.simple_license_allocation import license_optim
+from apps.placement.optimizers.conductor import conductor
+from apps.license.optimizers.simple_license_allocation import license_optim
 from osdf.utils.interfaces import get_rest_client
 from osdf.utils.mdc_utils import mdc_from_json
 
@@ -23,7 +23,7 @@ import re
 from osdf.utils.data_conversion import text_to_symbol
 from osdf.utils.programming_utils import dot_notation
 
-policy_config_mapping = yaml.load(open('config/has_config.yaml')).get('policy_config_mapping')
+policy_config_mapping = yaml.safe_load(open('config/has_config.yaml')).get('policy_config_mapping')
 
 
 def get_opt_query_data(req_json, policies):
diff --git a/apps/route/__init__.py b/apps/route/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/apps/route/optimizers/__init__.py b/apps/route/optimizers/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
index 24379d4..c6e724a 100644 (file)
@@ -30,6 +30,7 @@
                 <include>*.md</include>
             </includes>
             <excludes>
+                <exclude>**/__pycache__/**</exclude>
                 <exclude>**/*.pyc</exclude>
                 <exclude>config/preload_secrets.yaml</exclude>
             </excludes>
index 5a2c460..0f271c8 100644 (file)
@@ -30,35 +30,40 @@ ENV https_proxy $HTTPS_PROXY
 ENV OSDF_PORT "8699"
 EXPOSE ${OSDF_PORT}
 
-ENV MZN 2.1.6
-ENV MZN_BASENAME MiniZincIDE-${MZN}-bundle-linux-x86_64
+ENV MZN 2.3.2
+ENV MZN_BASENAME MiniZincIDE-${MZN}-bundle-linux
 ENV MZN_GH_BASE https://github.com/MiniZinc/MiniZincIDE
-ENV MZN_DL_URL ${MZN_GH_BASE}/releases/download/${MZN}/${MZN_BASENAME}.tgz
+ENV MZN_DL_URL ${MZN_GH_BASE}/releases/download/${MZN}/${MZN_BASENAME}-x86_64.tgz
 
 RUN apt-get update -y \
     && apt-get install -y vim unzip wget libmpfr-dev \
     && apt-get install -y git libqt5printsupport5 build-essential \
     && apt-get install -y python3 python3-setuptools python3-dev \
     && easy_install3 pip \
-    && pip install --upgrade virtualenv pip wheel 
+    && pip install --upgrade virtualenv pip wheel setuptools
 
 RUN ln -s /usr/bin/python3.5 /usr/bin/python
 
 # Minizinc
-RUN wget -q $MZN_DL_URL -O mz.tgz \
-    && tar xzf mz.tgz \
+RUN wget -q $MZN_DL_URL -O /tmp/mz.tgz \
+    && tar xzf /tmp/mz.tgz \
     && mv $MZN_BASENAME /mz-dist \
-    && rm mz.tgz \
-    && echo PATH=/mz-dist:$PATH >> ~/.bashrc
+    && rm /tmp/mz.tgz \
+    && echo PATH=/mz-dist/bin:$PATH >> ~/.bashrc \
+    && echo 'export LD_LIBRARY_PATH=/mz-dist/lib:LD_LIBRARY_PATH' >> ~/.bashrc
 
 ENV SHELL /bin/bash
 ENV PATH /mz-dist:$PATH
 
 # OSDF
 WORKDIR /opt/osdf
-RUN wget -O /opt/osdf.zip "https://nexus.onap.org/service/local/artifact/maven/redirect?r=${REPO}&g=org.onap.optf.osdf&a=optf-osdf&e=zip&v=${MVN_ARTIFACT_VERSION}" && \
-    unzip -q -o -B /opt/osdf.zip -d /opt/ && \
-    rm -f /opt/osdf.zip
+#RUN wget -O /opt/osdf.zip "https://nexus.onap.org/service/local/artifact/maven/redirect?r=releases&g=org.onap.optf.osdf&a=optf-osdf&e=zip&v=1.3.4" && \
+#    unzip -q -o -B /opt/osdf.zip -d /opt/ && \
+#    rm -f /opt/osdf.zip
+
+COPY onap-osdf-tm/optf-osdf-${MVN_ARTIFACT_VERSION}.zip /tmp/optf-osdf.zip
+COPY onap-osdf-tm/apps /opt/osdf/apps
+RUN unzip -q -o -B /tmp/optf-osdf.zip -d /opt/ && rm -f /tmp/optf-osdf.zip
 RUN mkdir -p /var/log/onap/optf/osdf/
 RUN pip install --no-cache-dir -r requirements.txt
 
diff --git a/docker/assembly/osdf-files.xml b/docker/assembly/osdf-files.xml
new file mode 100644 (file)
index 0000000..fc8a864
--- /dev/null
@@ -0,0 +1,66 @@
+<!--
+       Copyright (C) 2019 AT&T Intellectual Property. 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.
+
+-->
+
+<!--
+    Copyright (c) 2018 Intel Corporation. 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.
+-->
+
+<assembly
+       xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.1"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.1 http://maven.apache.org/xsd/assembly-1.1.1.xsd">
+       <id>osdf-files</id>
+
+       <formats>
+               <format>tar.gz</format>
+       </formats>
+       <includeBaseDirectory>false</includeBaseDirectory>
+
+
+       <fileSets>
+               <fileSet>
+                       <includes>
+                               <include>${project.build.finalName}.zip</include>
+                       </includes>
+                       <directory>${project.build.directory}</directory>
+                       <outputDirectory>/</outputDirectory>
+               </fileSet>
+               <fileSet>
+                       <includes>
+                               <include>apps/**</include>
+                       </includes>
+                       <excludes>
+                <exclude>**/*.pyc</exclude>
+                               <exclude>**/__pycache__/**</exclude>
+            </excludes>
+                       <outputDirectory>/</outputDirectory>
+               </fileSet>
+
+       </fileSets>
+</assembly>
diff --git a/osdf/apps/__init__.py b/osdf/apps/__init__.py
new file mode 100644 (file)
index 0000000..370bc06
--- /dev/null
@@ -0,0 +1,2 @@
+import yaml
+yaml.warnings({'YAMLLoadWarning': False})
\ No newline at end of file
diff --git a/osdf/apps/baseapp.py b/osdf/apps/baseapp.py
new file mode 100644 (file)
index 0000000..cfa7e5d
--- /dev/null
@@ -0,0 +1,166 @@
+# -------------------------------------------------------------------------
+#   Copyright (c) 2015-2017 AT&T Intellectual Property
+#
+#   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.
+#
+# -------------------------------------------------------------------------
+#
+
+"""
+OSDF Manager Main Flask Application
+"""
+
+import json
+import ssl
+import sys
+import time
+import traceback
+from optparse import OptionParser
+
+import pydevd
+from flask import Flask, request, Response, g
+from requests import RequestException
+from schematics.exceptions import DataError
+
+import osdf.adapters.aaf.sms as sms
+import osdf.operation.responses
+from osdf.config.base import osdf_config
+from osdf.logging.osdf_logging import error_log, debug_log
+from osdf.operation.error_handling import request_exception_to_json_body, internal_error_message
+from osdf.operation.exceptions import BusinessException
+from osdf.utils.mdc_utils import clear_mdc, mdc_from_json, default_mdc
+
+ERROR_TEMPLATE = osdf.ERROR_TEMPLATE
+
+app = Flask(__name__)
+
+BAD_CLIENT_REQUEST_MESSAGE = 'Client sent an invalid request'
+
+
+@app.errorhandler(BusinessException)
+def handle_business_exception(e):
+    """An exception explicitly raised due to some business rule"""
+    error_log.error("Synchronous error for request id {} {}".format(g.request_id, traceback.format_exc()))
+    err_msg = ERROR_TEMPLATE.render(description=str(e))
+    response = Response(err_msg, content_type='application/json; charset=utf-8')
+    response.status_code = 400
+    return response
+
+
+@app.errorhandler(RequestException)
+def handle_request_exception(e):
+    """Returns a detailed synchronous message to the calling client
+    when osdf fails due to a remote call to another system"""
+    error_log.error("Synchronous error for request id {} {}".format(g.request_id, traceback.format_exc()))
+    err_msg = request_exception_to_json_body(e)
+    response = Response(err_msg, content_type='application/json; charset=utf-8')
+    response.status_code = 400
+    return response
+
+
+@app.errorhandler(DataError)
+def handle_data_error(e):
+    """Returns a detailed message to the calling client when the initial synchronous message is invalid"""
+    error_log.error("Synchronous error for request id {} {}".format(g.request_id, traceback.format_exc()))
+
+    body_dictionary = {
+        "serviceException": {
+            "text": BAD_CLIENT_REQUEST_MESSAGE,
+            "exceptionMessage": str(e.errors),
+            "errorType": "InvalidClientRequest"
+        }
+    }
+
+    body_as_json = json.dumps(body_dictionary)
+    response = Response(body_as_json, content_type='application/json; charset=utf-8')
+    response.status_code = 400
+    return response
+
+
+@app.before_request
+def log_request():
+    g.request_start = time.clock()
+    if request.get_json():
+
+        request_json = request.get_json()
+        g.request_id = request_json['requestInfo']['requestId']
+        mdc_from_json(request_json)
+    else:
+        g.request_id = "N/A"
+        default_mdc()
+
+
+
+@app.after_request
+def log_response(response):
+    clear_mdc()
+    return response
+
+
+@app.errorhandler(500)
+def internal_failure(error):
+    """Returned when unexpected coding errors occur during initial synchronous processing"""
+    error_log.error("Synchronous error for request id {} {}".format(g.request_id, traceback.format_exc()))
+    response = Response(internal_error_message, content_type='application/json; charset=utf-8')
+    response.status_code = 500
+    return response
+
+
+def get_options(argv):
+    program_version_string = '%%prog %s' % "v1.0"
+    program_longdesc = ""
+    program_license = ""
+
+    parser = OptionParser(version=program_version_string, epilog=program_longdesc, description=program_license)
+    parser.add_option("-l", "--local", dest="local", help="run locally", action="store_true", default=False)
+    parser.add_option("-t", "--devtest", dest="devtest", help="run in dev/test environment", action="store_true",
+                      default=False)
+    parser.add_option("-d", "--debughost", dest="debughost", help="IP Address of host running debug server", default='')
+    parser.add_option("-p", "--debugport", dest="debugport", help="Port number of debug server", type=int, default=5678)
+    opts, args = parser.parse_args(argv)
+
+    if opts.debughost:
+        debug_log.debug('pydevd.settrace({}, port={})'.format(opts.debughost, opts.debugport))
+        pydevd.settrace(opts.debughost, port=opts.debugport)
+    return opts
+
+
+def build_ssl_context():
+    ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
+    ssl_context.set_ciphers('ECDHE-RSA-AES128-SHA256:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH')
+    ssl_context.load_cert_chain(sys_conf['ssl_context'][0], sys_conf['ssl_context'][1])
+    return ssl_context
+
+
+def run_app():
+    global sys_conf
+    sys_conf = osdf_config['core']['osdf_system']
+    ports = sys_conf['osdf_ports']
+    internal_port, external_port = ports['internal'], ports['external']
+    local_host = sys_conf['osdf_ip_default']
+    common_app_opts = dict(host=local_host, threaded=True, use_reloader=False)
+    ssl_opts = sys_conf.get('ssl_context')
+    if ssl_opts:
+        common_app_opts.update({'ssl_context': build_ssl_context()})
+    opts = get_options(sys.argv)
+    # Load secrets from SMS
+    sms.load_secrets()
+    if not opts.local and not opts.devtest:  # normal deployment
+        app.run(port=internal_port, debug=False, **common_app_opts)
+    else:
+        port = internal_port if opts.local else external_port
+        app.run(port=port, debug=True, **common_app_opts)
+
+
+if __name__ == "__main__":
+    run_app()
index 86156a1..e32d44e 100644 (file)
@@ -27,6 +27,6 @@ class CoreConfig(metaclass=MetaSingleton):
 
     def get_core_config(self, config_file=None):
         if self.core_config is None:
-            self.core_config = yaml.load(open(config_file))
+            self.core_config = yaml.safe_load(open(config_file))
         return self.core_config
 
index e457f18..a5a9739 100755 (executable)
@@ -191,6 +191,7 @@ class OOF_OSDFLogMessageFormatter(object):
 
     @staticmethod
     def received_http_response(resp):
+        """ """
         return "Received response [code: {}, headers: {}, data: {}]".format(
             resp.status_code, resp.headers, resp.__dict__)
 
index 6da67bd..b98cbf0 100644 (file)
@@ -42,11 +42,17 @@ def default_server_info():
         MDC.put('serverIPAddress', server_ip_address)
 
 
-def mdc_from_json(request_json):
+def default_mdc():
     MDC.put('instanceUUID', uuid.uuid1())
     MDC.put('serviceName', 'OOF_OSDF')
     MDC.put('threadID', threading.currentThread().getName())
     default_server_info()
+    MDC.put('requestID', 'N/A')
+    MDC.put('partnerName', 'N/A')
+
+
+def mdc_from_json(request_json):
+    default_mdc()
     MDC.put('requestID', request_json['requestInfo']['requestId'])
     MDC.put('partnerName', request_json['requestInfo']['sourceId'])
 
index 1cfb8a3..71106fd 100755 (executable)
@@ -21,99 +21,24 @@ OSDF Manager Main Flask Application
 """
 
 import json
-import ssl
-import sys
-import time
-import traceback
-from optparse import OptionParser
 from threading import Thread  # for scaling up, may need celery with RabbitMQ or redis
 
-import pydevd
-import yaml
-from flask import Flask, request, Response, g
-from requests import RequestException
-from schematics.exceptions import DataError
+from flask import request, g
 
-yaml.warnings({'YAMLLoadWarning': False})
-
-import osdf.adapters.aaf.sms as sms
-import osdf.operation.responses
+from osdf.apps.baseapp import app, run_app
+from apps.pci.models.api.pciOptimizationRequest import PCIOptimizationAPI
+from apps.pci.optimizers.pci_opt_processor import process_pci_optimation
+from apps.placement.models.api.placementRequest import PlacementAPI
+from apps.placement.optimizers.conductor.remote_opt_processor import process_placement_opt
+from apps.route.optimizers.simple_route_opt import RouteOpt
 from osdf.adapters.policy.interface import get_policies
 from osdf.adapters.policy.interface import upload_policy_models
 from osdf.config.base import osdf_config
-from osdf.logging.osdf_logging import MH, audit_log, error_log, debug_log
-from osdf.models.api.pciOptimizationRequest import PCIOptimizationAPI
-from osdf.models.api.placementRequest import PlacementAPI
-from osdf.operation.error_handling import request_exception_to_json_body, internal_error_message
-from osdf.operation.exceptions import BusinessException
+from osdf.logging.osdf_logging import MH, audit_log
 from osdf.operation.responses import osdf_response_for_request_accept as req_accept
-from osdf.optimizers.pciopt.pci_opt_processor import process_pci_optimation
-from osdf.optimizers.placementopt.conductor.remote_opt_processor import process_placement_opt
-from osdf.optimizers.routeopt.simple_route_opt import RouteOpt
 from osdf.utils import api_data_utils
-from osdf.utils.mdc_utils import clear_mdc, mdc_from_json
 from osdf.webapp.appcontroller import auth_basic
 
-ERROR_TEMPLATE = osdf.ERROR_TEMPLATE
-
-app = Flask(__name__)
-
-BAD_CLIENT_REQUEST_MESSAGE = 'Client sent an invalid request'
-
-
-@app.errorhandler(BusinessException)
-def handle_business_exception(e):
-    """An exception explicitly raised due to some business rule"""
-    error_log.error("Synchronous error for request id {} {}".format(g.request_id, traceback.format_exc()))
-    err_msg = ERROR_TEMPLATE.render(description=str(e))
-    response = Response(err_msg, content_type='application/json; charset=utf-8')
-    response.status_code = 400
-    return response
-
-
-@app.errorhandler(RequestException)
-def handle_request_exception(e):
-    """Returns a detailed synchronous message to the calling client
-    when osdf fails due to a remote call to another system"""
-    error_log.error("Synchronous error for request id {} {}".format(g.request_id, traceback.format_exc()))
-    err_msg = request_exception_to_json_body(e)
-    response = Response(err_msg, content_type='application/json; charset=utf-8')
-    response.status_code = 400
-    return response
-
-
-@app.errorhandler(DataError)
-def handle_data_error(e):
-    """Returns a detailed message to the calling client when the initial synchronous message is invalid"""
-    error_log.error("Synchronous error for request id {} {}".format(g.request_id, traceback.format_exc()))
-
-    body_dictionary = {
-        "serviceException": {
-            "text": BAD_CLIENT_REQUEST_MESSAGE,
-            "exceptionMessage": str(e.errors),
-            "errorType": "InvalidClientRequest"
-        }
-    }
-
-    body_as_json = json.dumps(body_dictionary)
-    response = Response(body_as_json, content_type='application/json; charset=utf-8')
-    response.status_code = 400
-    return response
-
-
-@app.before_request
-def log_request():
-    g.request_start = time.clock()
-    request_json = request.get_json()
-    g.request_id = request_json['requestInfo']['requestId']
-    mdc_from_json(request_json)
-
-
-@app.after_request
-def log_response(response):
-    clear_mdc()
-    return response
-
 
 @app.route("/api/oof/v1/healthcheck", methods=["GET"])
 def do_osdf_health_check():
@@ -194,59 +119,5 @@ def do_pci_optimization():
                       request_status="accepted", status_message="")
 
 
-@app.errorhandler(500)
-def internal_failure(error):
-    """Returned when unexpected coding errors occur during initial synchronous processing"""
-    error_log.error("Synchronous error for request id {} {}".format(g.request_id, traceback.format_exc()))
-    response = Response(internal_error_message, content_type='application/json; charset=utf-8')
-    response.status_code = 500
-    return response
-
-
-def get_options(argv):
-    program_version_string = '%%prog %s' % "v1.0"
-    program_longdesc = ""
-    program_license = ""
-
-    parser = OptionParser(version=program_version_string, epilog=program_longdesc, description=program_license)
-    parser.add_option("-l", "--local", dest="local", help="run locally", action="store_true", default=False)
-    parser.add_option("-t", "--devtest", dest="devtest", help="run in dev/test environment", action="store_true",
-                      default=False)
-    parser.add_option("-d", "--debughost", dest="debughost", help="IP Address of host running debug server", default='')
-    parser.add_option("-p", "--debugport", dest="debugport", help="Port number of debug server", type=int, default=5678)
-    opts, args = parser.parse_args(argv)
-
-    if opts.debughost:
-        debug_log.debug('pydevd.settrace({}, port={})'.format(opts.debughost, opts.debugport))
-        pydevd.settrace(opts.debughost, port=opts.debugport)
-    return opts
-
-
-def build_ssl_context():
-    ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
-    ssl_context.set_ciphers('ECDHE-RSA-AES128-SHA256:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH')
-    ssl_context.load_cert_chain(sys_conf['ssl_context'][0], sys_conf['ssl_context'][1])
-    return ssl_context
-
-
 if __name__ == "__main__":
-
-    sys_conf = osdf_config['core']['osdf_system']
-    ports = sys_conf['osdf_ports']
-    internal_port, external_port = ports['internal'], ports['external']
-
-    local_host = sys_conf['osdf_ip_default']
-    common_app_opts = dict(host=local_host, threaded=True, use_reloader=False)
-
-    ssl_opts = sys_conf.get('ssl_context')
-    if ssl_opts:
-        common_app_opts.update({'ssl_context': build_ssl_context()})
-
-    opts = get_options(sys.argv)
-    # Load secrets from SMS
-    sms.load_secrets()
-    if not opts.local and not opts.devtest:  # normal deployment
-        app.run(port=internal_port, debug=False, **common_app_opts)
-    else:
-        port = internal_port if opts.local else external_port
-        app.run(port=port, debug=True, **common_app_opts)
+    run_app()
diff --git a/pom.xml b/pom.xml
index 4b513ea..5ac2477 100644 (file)
--- a/pom.xml
+++ b/pom.xml
         <sonar.pluginname>python</sonar.pluginname>
         <sonar.inclusions>**/**.py,osdfapp.py</sonar.inclusions>
         <sonar.exclusions>test/**.py</sonar.exclusions>
+        <maven.build.timestamp.format>yyyyMMdd'T'HHmmss'Z'</maven.build.timestamp.format>
+        <osdf.build.timestamp>${maven.build.timestamp}</osdf.build.timestamp>
+        <osdf.project.version>${project.version}</osdf.project.version>
+        <osdf.docker.repository>nexus3.onap.org:10003</osdf.docker.repository>
+               <image.namespace>${osdf.docker.repository}/onap/optf-osdf</image.namespace>
     </properties>
 
     <build>
                     <retryFailedDeploymentCount>2</retryFailedDeploymentCount>
                 </configuration>
             </plugin>
+            <plugin>
+                               <groupId>org.codehaus.groovy.maven</groupId>
+                               <artifactId>gmaven-plugin</artifactId>
+                               <version>1.0</version>
+                               <executions>
+                                       <execution>
+                                               <phase>validate</phase>
+                                               <goals>
+                                                       <goal>execute</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <source>${project.basedir}/script/TagVersion.groovy</source>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+            <plugin>
+                               <groupId>io.fabric8</groupId>
+                               <artifactId>docker-maven-plugin</artifactId>
+                               <version>0.26.0</version>
+                               <configuration>
+                                       <verbose>true</verbose>
+                                       <apiVersion>1.23</apiVersion>
+                                       <images>
+                                               <image>
+                                                       <name>${image.namespace}</name>
+                                                       <alias>optf-osdf</alias>
+                                                       <build>
+                                                               <cleanup>true</cleanup>
+                                                               <tags>
+                                                                       <tag>latest</tag>
+                                                                       <tag>${project.docker.latesttagtimestamp.version}</tag>
+                                                                       <tag>${project.docker.latesttag.version}</tag>
+                                                               </tags>
+
+                                                               <dockerFile>${project.basedir}/docker/Dockerfile</dockerFile>
+                                                               <assembly>
+                                                                       <descriptor>${project.basedir}/docker/assembly/osdf-files.xml</descriptor>
+                                                                       <name>onap-osdf-tm</name>
+                                                               </assembly>
+                                                               <args>
+                                    <MVN_ARTIFACT_VERSION>${project.version}</MVN_ARTIFACT_VERSION>
+                                    <REPO>${project.repo}</REPO>
+
+                                                                       <!-- plugin cannot handle empty (no proxy) arguments
+                                                                       <http_proxy_arg>${docker.http_proxy}</http_proxy_arg>
+                                                                       <https_proxy_arg>${docker.https_proxy}</https_proxy_arg>
+                                                                       -->
+                                                               </args>
+                                                       </build>
+                                               </image>
+                                       </images>
+                               </configuration>
+                               <executions>
+                                       <execution>
+                                               <id>generate-images</id>
+                                               <phase>install</phase>
+                                               <goals>
+                                                       <goal>build</goal>
+                                               </goals>
+                                       </execution>
+                                       <execution>
+                                               <id>push-images</id>
+                                               <phase>deploy</phase>
+                                               <goals>
+                                                       <goal>build</goal>
+                                                       <goal>push</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <image>${image.namespace}:%l</image>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
         </plugins>
     </build>
 </project>
index 0ea452e..8001016 100644 (file)
@@ -9,8 +9,7 @@ python-dateutil>=2.5.3
 PyYAML>=3.12
 requests>=2.14.2
 schematics>=2.0.0
-docopt>=0.6.2
 pydevd==1.4.0
 onapsmsclient>=0.0.4
-pymzn==0.17.1
+pymzn>=0.18.3
 onappylog>=1.0.9
diff --git a/script/TagVersion.groovy b/script/TagVersion.groovy
new file mode 100644 (file)
index 0000000..6ed6558
--- /dev/null
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP OSDF
+ * ================================================================================
+ * Copyright (C) 2018 AT&T Intellectual Property. 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============================================
+ * ===================================================================
+ * 
+ */
+
+package org.onap.osdf.maven.scripts
+
+println project.properties['osdf.project.version']
+
+def versionTag
+if ( project.properties['osdf.project.version'] != null ) {
+    versionArray = project.properties['osdf.project.version'].split('\\.|-');
+    versionTag = versionArray[0] + '.' + versionArray[1] + '.' + versionArray[2]
+    timestamp = project.properties['osdf.build.timestamp']
+}
+
+if ( project.properties['osdf.project.version'].endsWith("-SNAPSHOT") ) {
+    project.properties['project.docker.latesttag.version']=versionTag + "-SNAPSHOT-latest";
+    project.properties['project.docker.latesttagtimestamp.version']=versionTag + "-SNAPSHOT-"+timestamp;
+    project.properties['project.repo'] = 'snapshots'
+} else { 
+    project.properties['project.docker.latesttag.version']=baseTag + "-STAGING-latest";
+    project.properties['project.docker.latesttagtimestamp.version']=versionTag + "-STAGING-"+timestamp;
+    project.properties['project.repo'] = 'releases'
+} 
+
+println 'New Tag for docker: ' + project.properties['project.docker.latesttag.version'];
\ No newline at end of file
index 77d9a72..52e0367 100644 (file)
@@ -17,7 +17,7 @@
 #
 import unittest
 
-from osdf.optimizers.placementopt.conductor import conductor
+from apps.placement.optimizers.conductor import conductor
 import osdf.config.loader as config_loader
 from osdf.utils.interfaces import json_from_file
 from osdf.utils.programming_utils import DotDict
index 27711f5..ad70157 100644 (file)
 #
 # -------------------------------------------------------------------------
 #
-import mock
 import unittest
 
-from flask import Response
-from mock import patch
 from osdf.adapters.local_data import local_policies
-from osdf.optimizers.placementopt.conductor import translation as tr
-from osdf.utils.interfaces import json_from_file, yaml_from_file
+from apps.placement.optimizers.conductor import translation as tr
+from osdf.utils.interfaces import json_from_file
 
 
 class TestConductorTranslation(unittest.TestCase):
diff --git a/test/config/log.yml b/test/config/log.yml
new file mode 100644 (file)
index 0000000..0b8815f
--- /dev/null
@@ -0,0 +1,95 @@
+version: 1
+disable_existing_loggers: True
+
+loggers:
+  error:
+    handlers: [error_handler]
+    level: "WARN"
+    propagate: True
+  debug:
+    handlers: [debug_handler]
+    level: "DEBUG"
+    propagate: True
+  metrics:
+    handlers: [metrics_handler]
+    level: "INFO"
+    propagate: True
+  audit:
+    handlers: [audit_handler]
+    level: "INFO"
+    propagate: True
+handlers:
+  debug_handler:
+    level: "DEBUG"
+    class: "logging.handlers.TimedRotatingFileHandler"
+    filename: "logs/debug.log"
+    formatter: "debugFormat"
+    when: midnight
+    interval: 1
+    utc: True
+    delay: False
+    backupCount: 10
+  error_handler:
+    level: "WARN"
+    class: "logging.handlers.TimedRotatingFileHandler"
+    filename: "logs/error.log"
+    formatter: "errorFormat"
+    when: midnight
+    interval: 1
+    utc: True
+    delay: False
+    backupCount: 10
+  metrics_handler:
+    level: "INFO"
+    class: "logging.handlers.TimedRotatingFileHandler"
+    filename: "logs/metrics.log"
+    formatter: "metricsFormat"
+    when: midnight
+    interval: 1
+    utc: True
+    delay: False
+    backupCount: 10
+  audit_handler:
+    level: "INFO"
+    class: "logging.handlers.TimedRotatingFileHandler"
+    filename: "logs/audit.log"
+    formatter: "auditFormat"
+    when: midnight
+    interval: 1
+    utc: True
+    delay: False
+    backupCount: 10
+formatters:
+  standard:
+    format: "%(asctime)s|||||%(name)s||%(thread)||%(funcName)s||%(levelname)s||%(message)s"
+  debugFormat:
+    format: "%(asctime)s|||||%(name)s||%(thread)s||%(funcName)s||%(levelname)s||%(message)s||||%(mdc)s"
+    mdcfmt: "{requestID} {threadID} {serverName} {serviceName} {instanceUUID} {upperLogLevel} {severity} {serverIPAddress} {server} {IPAddress} {className} {timer} {detailMessage}"
+    datefmt: "%Y-%m-%d %H:%M:%S"
+    (): onaplogging.mdcformatter.MDCFormatter
+  errorFormat:
+    format: "%(asctime)s|||||%(name)s||%(thread)s||%(funcName)s||%(levelname)s||%(message)s||||%(mdc)s"
+    mdcfmt: "{requestID} {threadID} {serviceName} {partnerName} {targetEntity} {targetServiceName} {errorCode} {errorDescription} {detailMessage}"
+    datefmt: "%Y-%m-%d %H:%M:%S"
+    (): onaplogging.mdcformatter.MDCFormatter
+  auditFormat:
+    format: "%(asctime)s|||||%(name)s||%(thread)s||%(funcName)s||%(levelname)s||%(message)s||||%(mdc)s"
+    mdcfmt: "{requestID} {serviceInstanceID} {threadID} {serverName} {serviceName} {partnerName} {statusCode} {responseCode} {responseDescription} {instanceUUID} {upperLogLevel} {severity} \
+             {serverIPAddress} {timer} {server} {IPAddress} {className} {unused} {processKey} {customField1} {customField2} {customField3} {customField4} {detailMessage}"
+    datefmt: "%Y-%m-%d %H:%M:%S"
+    (): onaplogging.mdcformatter.MDCFormatter
+  metricsFormat:
+    format: "%(asctime)s|||||%(name)s||%(thread)s||%(funcName)s||%(levelname)s||%(message)s||||%(mdc)s"
+    mdcfmt: "{requestID} {serviceInstanceID} {threadID} {serverName} {serviceName} {partnerName} \
+             {targetEntity} {targetServiceName} {statusCode} {responseCode} {responseDescription} \
+             {instanceUUID} {upperLogLevel} {severity} {serverIPAddress} {timer} {server} {IPAddress} \
+             {className} {unused} {processKey} {targetVirtualEntity} {customField1} {customField2} \
+             {customField3} {customField4} {detailMessage}"
+    datefmt: "%Y-%m-%d %H:%M:%S"
+    (): onaplogging.mdcformatter.MDCFormatter
+
+  mdcFormat:
+    format: "%(asctime)s|||||%(name)s||%(thread)s||%(funcName)s||%(levelname)s||%(message)s||||%(mdc)s"
+    mdcfmt: "{requestID} {invocationID} {serviceName} {serviceIP}"
+    datefmt: "%Y-%m-%d %H:%M:%S"
+    (): onaplogging.mdcformatter.MDCFormatter
index eb799e7..a6f1c97 100644 (file)
@@ -16,7 +16,7 @@
 # -------------------------------------------------------------------------
 #
 
-from osdf.optimizers.pciopt.configdb import request
+from apps.pci.optimizers.configdb import request
 import osdf.config.loader as config_loader
 from osdf.utils.interfaces import json_from_file
 from osdf.utils.programming_utils import DotDict
index 6f0ecb3..2953589 100644 (file)
@@ -1,7 +1,7 @@
 {
-    "service": "zone",
-    "policyName": "OSDF_R2.Affinity_vCPE_1",
-    "description": "Optimization query policy for vCPE",
+    "service": "affinityPolicy",
+    "policyName": "OSDF_DUBLIN.Affinity_vCPE_1",
+    "description": "Zone policy for vCPE",
     "templateVersion": "OpenSource.version.1",
     "version": "test1",
     "priority": "3",
index 2578544..010cf3f 100644 (file)
@@ -1,6 +1,6 @@
 {
     "service": "vim_fit",
-    "policyName": "OSDF_R2.Capacity_vGMuxInfra",
+    "policyName": "OSDF_DUBLIN.Capacity_vGMuxInfra",
     "description": "Capacity policy for vGMuxInfra",
     "templateVersion": "OpenSource.version.1",
     "version": "test1",
index c1682fa..fedcc4f 100644 (file)
@@ -1,6 +1,6 @@
 {
     "service": "vim_fit",
-    "policyName": "OSDF_R2.Capacity_vG_1",
+    "policyName": "OSDF_DUBLIN.Capacity_vG_1",
     "description": "Capacity policy for vG",
     "templateVersion": "OpenSource.version.1",
     "version": "test1",
index 61ec500..e3ba83c 100644 (file)
@@ -1,6 +1,6 @@
 {
-  "service": "distance_to_location",
-  "policyName": "OSDF_R2.Distance_vGMuxInfra",
+  "service": "distancePolicy",
+  "policyName": "OSDF_DUBLIN.Distance_vGMuxInfra",
   "description": "Distance Policy for vGMuxInfra",
   "templateVersion": "OpenSource.version.1",
   "version": "test1",
   "guard": "False",
   "content": {
     "distanceProperties": {
-      "locationInfo": "customer_location",
+      "locationInfo": "customer_loc",
       "distance": { "value": "500", "operator": "<", "unit": "km" }
     },
     "identity": "distance-vGMuxInfra",
     "resources": ["vGMuxInfra"],
     "policyScope": ["vCPE", "US", "INTERNATIONAL", "ip", "vGMuxInfra"],
-    "policyType": "distancePolicy",
+    "policyType": "distance_to_location",
     "applicableResources": "any"
   }
 }
index 06c3ada..c498c7a 100644 (file)
@@ -1,6 +1,6 @@
 {
-  "service": "distance_to_location",
-  "policyName": "OSDF_R2.Distance_vG_1",
+  "service": "distancePolicy",
+  "policyName": "OSDF_DUBLIN.Distance_vG_1",
   "description": "Distance Policy for vG",
   "templateVersion": "OpenSource.version.1",
   "version": "test1",
   "guard": "False",
   "content": {
     "distanceProperties": {
-      "locationInfo": "customer_location",
+      "locationInfo": "customer_loc",
       "distance": { "value": "1500", "operator": "<", "unit": "km" }
     },
     "identity": "distance-vG",
     "resources": ["vG"],
     "policyScope": ["vCPE", "US", "INTERNATIONAL", "ip", "vG"],
-    "policyType": "distancePolicy",
+    "policyType": "distance_to_location",
     "applicableResources": "any"
   }
 }
index ab3c586..9b062b0 100644 (file)
@@ -1,6 +1,6 @@
 {
-    "service": "placementOptimization",
-    "policyName": "OSDF_R2.Placement_Optimization_1",
+    "service": "optimizationPolicy",
+    "policyName": "OSDF_DUBLIN.Placement_Optimization_1",
     "description": "Placement Optimization Policy for vGMuxInfra",
     "templateVersion": "OpenSource.version.1",
     "version": "test1",
                     "parameter": "hpa_score",
                     "weight": "200",
                     "operator": "product"
+                },
+                {
+                    "resources": ["vFW"],
+                    "customerLocationInfo": "customer_loc",
+                    "parameter": "distance",
+                    "weight": "100",
+                    "operator": "product"
+                },
+                {
+                    "resources": ["vFW"],
+                    "parameter": "hpa_score",
+                    "weight": "200",
+                    "operator": "product"
                 }
             ],
             "operator": "sum"
         },
         "identity": "optimization",
         "policyScope": ["vCPE", "US", "INTERNATIONAL", "ip", "vGMuxInfra", "vG"],
-        "policyType": "placementOptimization",
+        "policyType": "placement_optimization",
         "objective": "minimize"
     }
 }
index 27f49d2..5097964 100644 (file)
@@ -1,7 +1,7 @@
 {
-  "service": "optimizationQueryPolicy",
-  "policyName": "OSDF_R2.QueryPolicy_vCPE",
-  "description": "Optimization query policy for vCPE",
+  "service": "queryPolicy",
+  "policyName": "OSDF_DUBLIN.QueryPolicy_vCPE",
+  "description": "Query policy for vCPE",
   "templateVersion": "OpenSource.version.1",
   "version": "test1",
   "priority": "3",
@@ -14,7 +14,7 @@
       {"attribute":"customerLongitude", "attribute_location": "customerLongitude"}
     ],
     "policyScope": ["vCPE", "US", "INTERNATIONAL", "ip", "vGMuxInfra", "vG"],
-    "policyType": "optimizationQueryPolicy",
+    "policyType": "request_param_query",
     "serviceName": "vCPE",
     "identity": "vCPE_Query_Policy"
   }
index 7f1db83..e398f39 100644 (file)
@@ -1,10 +1,10 @@
 {
-  "service": "optimizationQueryPolicy",
-  "policyName": "oofBeijing.queryPolicy_vCPE",
-  "description": "Optimization query policy for vCPE",
-  "templateVersion": "0.0.1",
-  "version": "oofBeijing",
-  "priority": "5",
+  "service": "queryPolicy",
+  "policyName": "OSDF_DUBLIN.queryPolicy_vCPE",
+  "description": "Query policy for vCPE",
+  "templateVersion": "OpenSource.version.1",
+  "version": "test1",
+  "priority": "3",
   "riskType": "test",
   "riskLevel": "2",
   "guard": "False",
@@ -17,7 +17,8 @@
       {"attribute":"customerLongitude", "attribute_location": "customerLongitude", "value": 2.2}
     ],
     "serviceName": "vCPE",
-    "policyScope": ["vCPE", "US", "INTERNATIONAL", "ip", "vGMuxInfra", "vG", "optimizationQueryPolicy"],
-    "policyType": "optimizationQueryPolicy"
+    "policyScope": ["vCPE", "US", "INTERNATIONAL", "ip", "vGMuxInfra", "vG"],
+    "policyType": "request_param_query",
+    "identity": "vCPE_Query_Policy"
   }
 }
index ce0b7e3..690f5dc 100644 (file)
@@ -1,6 +1,6 @@
 {
     "service": "hpaPolicy",
-    "policyName": "OSDF_R2.hpa_policy_vGMuxInfra_1",
+    "policyName": "OSDF_DUBLIN.hpa_policy_vGMuxInfra_1",
     "description": "HPA policy for vGMuxInfra",
     "templateVersion": "OpenSource.version.1",
     "version": "test1",
@@ -9,10 +9,10 @@
     "riskLevel": "2",
     "guard": "False",
     "content": {
-      "resources": "vGMuxInfra",
-      "identity": "hpaPolicy_vGMuxInfra",
+      "resources": ["vGMuxInfra"],
+      "identity": "hpa-vGMuxInfra",
       "policyScope": ["vCPE", "US", "INTERNATIONAL", "ip", "vGMuxInfra"],
-      "policyType": "hpaPolicy",
+      "policyType": "hpa",
       "flavorFeatures": [
         {
           "id": "vgmux_1",
index 5d2499f..b29c67d 100644 (file)
@@ -1,6 +1,6 @@
 {
     "service": "hpaPolicy",
-    "policyName": "OSDF_R2.hpa_policy_vG_1",
+    "policyName": "OSDF_DUBLIN.hpa_policy_vG_1",
     "description": "HPA policy for vG",
     "templateVersion": "OpenSource.version.1",
     "version": "test1",
@@ -9,10 +9,10 @@
     "riskLevel": "2",
     "guard": "False",
     "content": {
-      "resources": "vG",
-      "identity": "hpaPolicy_vG",
+      "resources": ["vG"],
+      "identity": "hpa-vG",
       "policyScope": ["vCPE", "US", "INTERNATIONAL", "ip", "vG"],
-      "policyType": "hpaPolicy",
+      "policyType": "hpa",
       "flavorFeatures": [
         {
           "id": "vg_1",
index d215078..b047686 100644 (file)
@@ -1,6 +1,6 @@
 {
     "service": "vnfPolicy",
-    "policyName": "OSDF_R2.vnfPolicy_vG",
+    "policyName": "OSDF_DUBLIN.vnfPolicy_vG",
     "description": "vnfPolicy",
     "templateVersion": "OpenSource.version.1",
     "version": "test1",
index 6849105..45d67f6 100644 (file)
@@ -1,6 +1,6 @@
 {
     "service": "vnfPolicy",
-    "policyName": "OSDF_R2.vnfPolicy_vGMuxInfra",
+    "policyName": "OSDF_DUBLIN.vnfPolicy_vGMuxInfra",
     "description": "vnfPolicy",
     "templateVersion": "OpenSource.version.1",
     "version": "test1",
diff --git a/test/functest/simulators/simulated-config/log.yml b/test/functest/simulators/simulated-config/log.yml
new file mode 100644 (file)
index 0000000..0b8815f
--- /dev/null
@@ -0,0 +1,95 @@
+version: 1
+disable_existing_loggers: True
+
+loggers:
+  error:
+    handlers: [error_handler]
+    level: "WARN"
+    propagate: True
+  debug:
+    handlers: [debug_handler]
+    level: "DEBUG"
+    propagate: True
+  metrics:
+    handlers: [metrics_handler]
+    level: "INFO"
+    propagate: True
+  audit:
+    handlers: [audit_handler]
+    level: "INFO"
+    propagate: True
+handlers:
+  debug_handler:
+    level: "DEBUG"
+    class: "logging.handlers.TimedRotatingFileHandler"
+    filename: "logs/debug.log"
+    formatter: "debugFormat"
+    when: midnight
+    interval: 1
+    utc: True
+    delay: False
+    backupCount: 10
+  error_handler:
+    level: "WARN"
+    class: "logging.handlers.TimedRotatingFileHandler"
+    filename: "logs/error.log"
+    formatter: "errorFormat"
+    when: midnight
+    interval: 1
+    utc: True
+    delay: False
+    backupCount: 10
+  metrics_handler:
+    level: "INFO"
+    class: "logging.handlers.TimedRotatingFileHandler"
+    filename: "logs/metrics.log"
+    formatter: "metricsFormat"
+    when: midnight
+    interval: 1
+    utc: True
+    delay: False
+    backupCount: 10
+  audit_handler:
+    level: "INFO"
+    class: "logging.handlers.TimedRotatingFileHandler"
+    filename: "logs/audit.log"
+    formatter: "auditFormat"
+    when: midnight
+    interval: 1
+    utc: True
+    delay: False
+    backupCount: 10
+formatters:
+  standard:
+    format: "%(asctime)s|||||%(name)s||%(thread)||%(funcName)s||%(levelname)s||%(message)s"
+  debugFormat:
+    format: "%(asctime)s|||||%(name)s||%(thread)s||%(funcName)s||%(levelname)s||%(message)s||||%(mdc)s"
+    mdcfmt: "{requestID} {threadID} {serverName} {serviceName} {instanceUUID} {upperLogLevel} {severity} {serverIPAddress} {server} {IPAddress} {className} {timer} {detailMessage}"
+    datefmt: "%Y-%m-%d %H:%M:%S"
+    (): onaplogging.mdcformatter.MDCFormatter
+  errorFormat:
+    format: "%(asctime)s|||||%(name)s||%(thread)s||%(funcName)s||%(levelname)s||%(message)s||||%(mdc)s"
+    mdcfmt: "{requestID} {threadID} {serviceName} {partnerName} {targetEntity} {targetServiceName} {errorCode} {errorDescription} {detailMessage}"
+    datefmt: "%Y-%m-%d %H:%M:%S"
+    (): onaplogging.mdcformatter.MDCFormatter
+  auditFormat:
+    format: "%(asctime)s|||||%(name)s||%(thread)s||%(funcName)s||%(levelname)s||%(message)s||||%(mdc)s"
+    mdcfmt: "{requestID} {serviceInstanceID} {threadID} {serverName} {serviceName} {partnerName} {statusCode} {responseCode} {responseDescription} {instanceUUID} {upperLogLevel} {severity} \
+             {serverIPAddress} {timer} {server} {IPAddress} {className} {unused} {processKey} {customField1} {customField2} {customField3} {customField4} {detailMessage}"
+    datefmt: "%Y-%m-%d %H:%M:%S"
+    (): onaplogging.mdcformatter.MDCFormatter
+  metricsFormat:
+    format: "%(asctime)s|||||%(name)s||%(thread)s||%(funcName)s||%(levelname)s||%(message)s||||%(mdc)s"
+    mdcfmt: "{requestID} {serviceInstanceID} {threadID} {serverName} {serviceName} {partnerName} \
+             {targetEntity} {targetServiceName} {statusCode} {responseCode} {responseDescription} \
+             {instanceUUID} {upperLogLevel} {severity} {serverIPAddress} {timer} {server} {IPAddress} \
+             {className} {unused} {processKey} {targetVirtualEntity} {customField1} {customField2} \
+             {customField3} {customField4} {detailMessage}"
+    datefmt: "%Y-%m-%d %H:%M:%S"
+    (): onaplogging.mdcformatter.MDCFormatter
+
+  mdcFormat:
+    format: "%(asctime)s|||||%(name)s||%(thread)s||%(funcName)s||%(levelname)s||%(message)s||||%(mdc)s"
+    mdcfmt: "{requestID} {invocationID} {serviceName} {serviceIP}"
+    datefmt: "%Y-%m-%d %H:%M:%S"
+    (): onaplogging.mdcformatter.MDCFormatter
index 7fbe707..d1f6d7e 100644 (file)
 #
 # -------------------------------------------------------------------------
 #
-import osdfapp
+
 import unittest
 
+from osdf.apps import baseapp
 from osdf.operation.exceptions import BusinessException
 from requests import Request, RequestException
 from schematics.exceptions import DataError
@@ -28,7 +29,7 @@ from unittest.mock import patch
 class TestOSDFApp(TestCase):
 
     def setUp(self):
-        self.patcher_g = patch('osdfapp.g', return_value={'request_id':'DUMMY-REQ'})
+        self.patcher_g = patch('osdf.apps.baseapp.g', return_value={'request_id':'DUMMY-REQ'})
         self.Mock_g = self.patcher_g.start()
         # self.patcher2 = patch('package.module.Class2')
         # self.MockClass2 = self.patcher2.start()
@@ -47,26 +48,26 @@ class TestOSDFApp(TestCase):
  
     def test_handle_business_exception(self):
         e = BusinessException("Business Exception Description")
-        resp = osdfapp.handle_business_exception(e)
+        resp = baseapp.handle_business_exception(e)
         assert resp.status_code == 400
 
     def test_handle_request_exception(self):
         e = self.dummy_request_exception()
-        resp = osdfapp.handle_request_exception(e)
+        resp = baseapp.handle_request_exception(e)
         assert resp.status_code == 400
 
     def test_handle_data_error(self):
         e = DataError({"A1": "A1 Data Error"})
-        resp = osdfapp.handle_data_error(e)
+        resp = baseapp.handle_data_error(e)
         assert resp.status_code == 400
 
     def test_internal_failure(self):
         e = Exception("An Internal Error")
-        resp = osdfapp.internal_failure(e)
+        resp = baseapp.internal_failure(e)
         assert resp.status_code == 500
 
     def test_get_options_default(self):
-        opts = osdfapp.get_options(["PROG"])  # ensure nothing breaks
+        opts = baseapp.get_options(["PROG"])  # ensure nothing breaks
 
 
 if __name__ == "__main__":
index 4f1efcf..082b7f9 100644 (file)
 #
 # -------------------------------------------------------------------------
 #
-import mock
 import os
 import unittest
 
-from osdf.adapters.local_data import local_policies
+import mock
+
 import osdf.config.loader as config_loader
+from osdf.adapters.local_data import local_policies
+from osdf.adapters.policy import interface as pol
 from osdf.utils.interfaces import json_from_file
 from osdf.utils.programming_utils import DotDict
-from osdf.optimizers.placementopt.conductor import translation as tr
-from osdf.adapters.policy import interface as pol
 
 
 class TestPolicyInterface(unittest.TestCase):
index 7e38f4d..e69e954 100644 (file)
@@ -19,8 +19,8 @@ import unittest
 import json
 import yaml
 
+from apps.placement.optimizers.conductor.api_builder import conductor_api_builder
 from osdf.adapters.local_data import local_policies
-from osdf.optimizers.placementopt.conductor.api_builder import conductor_api_builder
 from osdf.utils.interfaces import json_from_file
 
 
@@ -28,7 +28,7 @@ class TestConductorApiBuilder(unittest.TestCase):
 
     def setUp(self):
         self.main_dir = ""
-        self.conductor_api_template = self.main_dir + "osdf/templates/conductor_interface.json"
+        self.conductor_api_template = self.main_dir + "apps/placement/templates/conductor_interface.json"
         self.local_config_file = self.main_dir + "config/common_config.yaml"
         policy_data_path = self.main_dir + "test/policy-local-files"                 # "test/policy-local-files"
 
index 4c9366a..e7e8eab 100644 (file)
@@ -24,7 +24,7 @@ from osdf.adapters.policy import interface
 from osdf.utils.interfaces import RestClient, json_from_file
 import yaml
 from mock import patch
-from osdf.optimizers.placementopt.conductor import translation
+from apps.placement.optimizers.conductor import translation
 from osdf.operation.exceptions import BusinessException
 
 
index 389ff62..73d03cd 100644 (file)
 import json
 import unittest
 
-from osdf.models.api.placementRequest import PlacementAPI
-from osdf.models.api.placementResponse import PlacementResponse
-from schematics.exceptions import ModelValidationError
+from schematics.exceptions import DataError
+
+from apps.placement.models.api.placementRequest import PlacementAPI
+from apps.placement.models.api.placementResponse import PlacementResponse
 
 
 class TestReqValidation(unittest.TestCase):
@@ -37,7 +38,7 @@ class TestReqValidation(unittest.TestCase):
 
     def test_req_failure(self):
         req_json = {}
-        self.assertRaises(ModelValidationError, lambda: PlacementAPI(req_json).validate())
+        self.assertRaises(DataError, lambda: PlacementAPI(req_json).validate())
 
 
 class TestResponseValidation(unittest.TestCase):
@@ -54,7 +55,7 @@ class TestResponseValidation(unittest.TestCase):
 
     def test_invalid_response(self):
         resp_json = {}
-        self.assertRaises(ModelValidationError, lambda: PlacementResponse(resp_json).validate())
+        self.assertRaises(DataError, lambda: PlacementResponse(resp_json).validate())
 
 
 if __name__ == "__main__":
index 1e2db17..a7a4d88 100644 (file)
@@ -17,7 +17,7 @@
 #
 import unittest
 import json
-from osdf.optimizers.placementopt.conductor.translation import get_opt_query_data
+from apps.placement.optimizers.conductor.translation import get_opt_query_data
 
 
 class TestGetOptQueryData(unittest.TestCase):
index 8c6a34c..b717d32 100644 (file)
 #
 # -------------------------------------------------------------------------
 #
-import mock
 import unittest
 
+import mock
 from flask import Response
 from mock import patch
-from osdf.adapters.local_data import local_policies
-from osdf.optimizers.pciopt.pci_opt_processor import process_pci_optimation
+
 import osdf.config.loader as config_loader
+from apps.pci.optimizers.pci_opt_processor import process_pci_optimation
+from osdf.adapters.local_data import local_policies
 from osdf.utils.interfaces import json_from_file
 from osdf.utils.programming_utils import DotDict
 
@@ -31,19 +32,19 @@ class TestProcessPlacementOpt(unittest.TestCase):
 
     def setUp(self):
         mock_req_accept_message = Response("Accepted Request", content_type='application/json; charset=utf-8')
-        self.patcher_req = patch('osdf.optimizers.pciopt.configdb.request',
+        self.patcher_req = patch('apps.pci.optimizers.configdb.request',
                                  return_value={"solutionInfo": {"placementInfo": "dummy"}})
         self.patcher_req_accept = patch('osdf.operation.responses.osdf_response_for_request_accept',
                                         return_value=mock_req_accept_message)
         self.patcher_callback = patch(
-            'osdf.optimizers.pciopt.pci_opt_processor.process_pci_optimation',
+            'apps.pci.optimizers.pci_opt_processor.process_pci_optimation',
             return_value=mock_req_accept_message)
 
         mock_mzn_response = [{'pci': {0: 0, 1: 1, 2: 2, 3: 3, 4: 0}, 'used_ignorables': [0]}]
 
         self.patcher_minizinc_callback = patch(
-            'osdf.optimizers.pciopt.solver.optimizer.solve',
-            return_value=mock_mzn_response )
+            'apps.pci.optimizers.solver.optimizer.solve',
+            return_value=mock_mzn_response)
         self.patcher_RestClient = patch(
             'osdf.utils.interfaces.RestClient', return_value=mock.MagicMock())
         self.Mock_req = self.patcher_req.start()
@@ -71,9 +72,8 @@ class TestProcessPlacementOpt(unittest.TestCase):
         request_json = json_from_file(parameter_data_file)
         policies = [json_from_file(policy_data_path + '/' + name) for name in valid_policies_files]
 
-        templ_string = process_pci_optimation(request_json, self.osdf_config,policies)
+        templ_string = process_pci_optimation(request_json, self.osdf_config, policies)
 
 
 if __name__ == "__main__":
     unittest.main()
-
index 31aa5fb..ffbc718 100644 (file)
@@ -21,7 +21,7 @@ import unittest
 from flask import Response
 from mock import patch
 from osdf.adapters.local_data import local_policies
-from osdf.optimizers.pciopt.pci_opt_processor import process_pci_optimation
+from apps.pci.optimizers.pci_opt_processor import process_pci_optimation
 import osdf.config.loader as config_loader
 from osdf.utils.interfaces import json_from_file
 from osdf.utils.programming_utils import DotDict
@@ -31,18 +31,18 @@ class TestProcessPlacementOpt(unittest.TestCase):
 
     def setUp(self):
         mock_req_accept_message = Response("Accepted Request", content_type='application/json; charset=utf-8')
-        self.patcher_req = patch('osdf.optimizers.pciopt.configdb.request',
+        self.patcher_req = patch('apps.pci.optimizers.configdb.request',
                                  return_value={"solutionInfo": {"placementInfo": "dummy"}})
         self.patcher_req_accept = patch('osdf.operation.responses.osdf_response_for_request_accept',
                                         return_value=mock_req_accept_message)
         self.patcher_callback = patch(
-            'osdf.optimizers.pciopt.pci_opt_processor.process_pci_optimation',
+            'apps.pci.optimizers.pci_opt_processor.process_pci_optimation',
             return_value=mock_req_accept_message)
 
         mock_mzn_response = [{'pci': {0: 0, 1: 1, 2: 2}}]
 
         self.patcher_minizinc_callback = patch(
-            'osdf.optimizers.pciopt.solver.optimizer.solve',
+            'apps.pci.optimizers.solver.optimizer.solve',
             return_value=mock_mzn_response )
         self.patcher_RestClient = patch(
             'osdf.utils.interfaces.RestClient', return_value=mock.MagicMock())
index 62a1ce6..64b69a8 100644 (file)
@@ -20,8 +20,9 @@ import unittest
 
 from flask import Response
 from mock import patch
+
+from apps.placement.optimizers.conductor.remote_opt_processor import process_placement_opt
 from osdf.adapters.local_data import local_policies
-from osdf.optimizers.placementopt.conductor.remote_opt_processor import process_placement_opt
 from osdf.utils.interfaces import json_from_file, yaml_from_file
 
 
@@ -29,12 +30,12 @@ class TestProcessPlacementOpt(unittest.TestCase):
 
     def setUp(self):
         mock_req_accept_message = Response("Accepted Request", content_type='application/json; charset=utf-8')
-        self.patcher_req = patch('osdf.optimizers.placementopt.conductor.conductor.request',
+        self.patcher_req = patch('apps.placement.optimizers.conductor.conductor.request',
                                  return_value={"solutionInfo": {"placementInfo": "dummy"}})
         self.patcher_req_accept = patch('osdf.operation.responses.osdf_response_for_request_accept',
                                         return_value=mock_req_accept_message)
         self.patcher_callback = patch(
-            'osdf.optimizers.placementopt.conductor.remote_opt_processor.process_placement_opt',
+            'apps.placement.optimizers.conductor.remote_opt_processor.process_placement_opt',
             return_value=mock_req_accept_message)
         self.patcher_RestClient = patch(
             'osdf.utils.interfaces.RestClient', return_value=mock.MagicMock())
index ab73ef6..6705cc8 100644 (file)
 # -------------------------------------------------------------------------
 #
 import unittest
-import json
-import yaml
+
+from apps.placement.optimizers.conductor.conductor import conductor_response_processor
 from osdf.utils.interfaces import json_from_file
-from osdf.optimizers.placementopt.conductor.conductor import conductor_response_processor
 from osdf.utils.interfaces import RestClient
 
 
diff --git a/tox.ini b/tox.ini
index 4723f46..58ed633 100644 (file)
--- a/tox.ini
+++ b/tox.ini
@@ -8,7 +8,6 @@ distribute = False
 setenv   =
     OSDF_CONFIG_FILE={toxinidir}/test/config/osdf_config.yaml
 commands =
-    - cat /etc/hosts
     /bin/bash test/functest/scripts/start-simulators.sh
     coverage run --module pytest --junitxml xunit-results.xml
     coverage xml --omit=".tox/py3/*","test/*"