aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/app/config_binding_service/__init__.py46
-rw-r--r--app/app/config_binding_service/client.py297
-rw-r--r--app/app/config_binding_service/controller.py108
-rw-r--r--app/app/config_binding_service/logging.py204
-rw-r--r--app/app/config_binding_service/openapi.yaml112
-rwxr-xr-xapp/app/main.py28
-rw-r--r--app/app/pom.xml270
-rw-r--r--app/app/setup.py34
-rw-r--r--app/app/tests/__init__.py21
-rw-r--r--app/app/tests/conftest.py70
-rw-r--r--app/app/tests/test_api.py103
-rw-r--r--app/app/tests/test_client.py206
-rw-r--r--app/app/tox.ini26
-rw-r--r--app/pom.xml80
-rw-r--r--app/uwsgi.ini3
15 files changed, 0 insertions, 1608 deletions
diff --git a/app/app/config_binding_service/__init__.py b/app/app/config_binding_service/__init__.py
deleted file mode 100644
index 306a762..0000000
--- a/app/app/config_binding_service/__init__.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# ============LICENSE_START=======================================================
-# Copyright (c) 2017-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.
-# ============LICENSE_END=========================================================
-#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-
-import os
-import connexion
-
-
-class BadEnviornmentENVNotFound(Exception):
- """
- Specific exception to be raised when a required ENV varaible is missing
- """
- pass
-
-
-def get_consul_uri():
- """
- This method waterfalls reads an envioronmental variable called CONSUL_HOST
- If that doesn't work, it raises an Exception
- """
- if "CONSUL_HOST" in os.environ:
- # WARNING! TODO! Currently the env file does not include the port.
- # But some other people think that the port should be a part of that.
- # For now, I'm hardcoding 8500 until this gets resolved.
- return "http://{0}:{1}".format(os.environ["CONSUL_HOST"], 8500)
- else:
- raise BadEnviornmentENVNotFound("CONSUL_HOST")
-
-
-# this has to be here due to circular dependency
-app = connexion.App(__name__, specification_dir='.')
-app.add_api('openapi.yaml', arguments={'title': 'Config Binding Service'})
diff --git a/app/app/config_binding_service/client.py b/app/app/config_binding_service/client.py
deleted file mode 100644
index c6a6753..0000000
--- a/app/app/config_binding_service/client.py
+++ /dev/null
@@ -1,297 +0,0 @@
-# ============LICENSE_START=======================================================
-# Copyright (c) 2017-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=========================================================
-#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-
-import re
-from functools import partial, reduce
-import base64
-import copy
-import json
-import requests
-import six
-from config_binding_service import get_consul_uri
-from config_binding_service.logging import utc, metrics
-
-
-CONSUL = get_consul_uri()
-
-template_match_rels = re.compile("\{{2}([^\}\{]*)\}{2}")
-template_match_dmaap = re.compile("<{2}([^><]*)>{2}")
-
-###
-# Cusom Exception
-###
-
-
-class CantGetConfig(Exception):
- """
- Represents an exception where a required key in consul isn't there
- """
-
- def __init__(self, code, response):
- self.code = code
- self.response = response
-
-
-class BadRequest(Exception):
- """
- Exception to be raised when the user tried to do something they shouldn't
- """
-
- def __init__(self, response):
- self.code = 400
- self.response = response
-
-
-###
-# Private Functions
-###
-
-
-def _consul_get_all_as_transaction(service_component_name, raw_request, xer):
- """
- Use Consul's transaction API to get all keys of the form service_component_name:*
- Return a dict with all the values decoded
- """
- payload = [
- {
- "KV": {
- "Verb": "get-tree",
- "Key": service_component_name,
- }
- }]
-
- bts = utc()
- response = requests.put("{0}/v1/txn".format(CONSUL), json=payload)
- metrics(raw_request, bts, xer, "Consul", "/v1/txn".format(service_component_name), response.status_code, __name__, msg="Retrieving Consul transaction for all keys for {0}".format(service_component_name))
-
- try:
- response.raise_for_status()
- except requests.exceptions.HTTPError as exc:
- raise CantGetConfig(exc.response.status_code, exc.response.text)
-
- result = json.loads(response.text)['Results']
-
- new_res = {}
- for res in result:
- key = res["KV"]["Key"]
- val = base64.b64decode(res["KV"]["Value"]).decode("utf-8")
- try:
- new_res[key] = json.loads(val)
- except json.decoder.JSONDecodeError:
- new_res[key] = "INVALID JSON" # TODO, should we just include the original value somehow?
-
- if service_component_name not in new_res:
- raise CantGetConfig(404, "")
-
- return new_res
-
-
-def _get_config_rels_dmaap(service_component_name, raw_request, xer):
- allk = _consul_get_all_as_transaction(service_component_name, raw_request, xer)
- config = allk[service_component_name]
- rels = allk.get(service_component_name + ":rels", [])
- dmaap = allk.get(service_component_name + ":dmaap", {})
- return config, rels, dmaap
-
-
-def _get_connection_info_from_consul(service_component_name):
- """
- Call consul's catalog
- TODO: currently assumes there is only one service
-
- DEPRECATION NOTE:
- This function existed when DCAE was using Consul to resolve service component's connection information.
- This relied on a "rels" key and a Cloudify relationship plugin to set up the magic.
- The consensous is that this feature is no longer used.
- This functionality is very likely deprecated by Kubernetes service discovery mechanism, and DMaaP.
-
- This function also includes logic related to CDAP, which is also likely deprecated.
-
- This code shall remain here for now but is at risk of being deleted in a future release.
- """
- # Note: there should be a metrics log here, but see the deprecation note above; this function is due to be deleted.
- res = requests.get("{0}/v1/catalog/service/{1}".format(CONSUL, service_component_name))
- res.raise_for_status()
- services = res.json()
- if services == []:
- return None # later will get filtered out
- ip_addr = services[0]["ServiceAddress"]
- port = services[0]["ServicePort"]
-
- if "cdap_app" in service_component_name:
- redirectish_url = "http://{0}:{1}/application/{2}".format(ip_addr, port, service_component_name)
- res = requests.get(redirectish_url)
- res.raise_for_status()
- details = res.json()
- # Pick out the details to expose to the component developers. These keys come from the broker API
- return {key: details[key] for key in ["connectionurl", "serviceendpoints"]}
- return "{0}:{1}".format(ip_addr, port)
-
-
-def _replace_rels_template(rels, template_identifier):
- """
- The magic. Replaces a template identifier {{...}} with the entrie(s) from the rels keys
- NOTE: There was a discussion over whether the CBS should treat {{}} as invalid. Mike asked that
- it resolve to the empty list. So, it does resolve it to empty list.
- """
- returnl = []
- for rel in rels:
- if template_identifier in rel and template_identifier != "":
- returnl.append(rel)
- # returnl now contains a list of DNS names (possible empty), now resolve them (or not if they are not regustered)
- return list(filter(lambda x: x is not None, map(_get_connection_info_from_consul, returnl)))
-
-
-def _replace_dmaap_template(dmaap, template_identifier):
- """
- This one liner could have been just put inline in the caller but maybe this will get more complex in future
- Talked to Mike, default value if key is not found in dmaap key should be {}
- """
- return {} if (template_identifier not in dmaap or template_identifier == "<<>>") else dmaap[template_identifier]
-
-
-def _replace_value(v, rels, dmaap):
- """
- Takes a value v that was some value in the templatized configuration, determines whether it needs replacement (either {{}} or <<>>), and if so, replaces it.
- Otherwise just returns v
-
- implementation notes:
- - the split below sees if we have v = x,y,z... so we can support {{x,y,z,....}}
- - the lambda is because we can't fold operators in Python, wanted fold(+, L) where + when applied to lists in python is list concatenation
- """
- if isinstance(v, six.string_types): # do not try to replace anything that is not a string
- match_on_rels = re.match(template_match_rels, v)
- if match_on_rels:
- # now holds just x,.. of {{x,...}}
- template_identifier = match_on_rels.groups()[0].strip()
- rtpartial = partial(_replace_rels_template, rels)
- return reduce(lambda a, b: a + b, map(rtpartial, template_identifier.split(",")), [])
- match_on_dmaap = re.match(template_match_dmaap, v)
- if match_on_dmaap:
- template_identifier = match_on_dmaap.groups()[0].strip()
- """
- Here is what Mike said:
- 1) want simple replacement of "<< >>" with dmaap key value
- 2) never need to support <<f1,f2>> whereas we do support {{sct1,sct2}}
- The consequence is that if you give the CBS a dmaap key like {"foo" : {...}} you are going to get back {...}, but rels always returns [...].
- So now component developers have to possible handle dicts and [], and we have to communicate that to them
- """
- return _replace_dmaap_template(dmaap, template_identifier)
- return v # was not a match or was not a string, return value as is
-
-
-def _recurse(config, rels, dmaap):
- """
- Recurse throug a configuration, or recursively a sub elemebt of it.
- If it's a dict: recurse over all the values
- If it's a list: recurse over all the values
- If it's a string: return the replacement
- If none of the above, just return the item.
- """
- if isinstance(config, list):
- return [_recurse(item, rels, dmaap) for item in config]
- if isinstance(config, dict):
- for key in config:
- config[key] = _recurse(config[key], rels, dmaap)
- return config
- if isinstance(config, six.string_types):
- return _replace_value(config, rels, dmaap)
- # not a dict, not a list, not a string, nothing to do.
- return config
-
-
-#########
-# PUBLIC API
-#########
-
-
-def resolve(service_component_name, raw_request, xer):
- """
- Return the bound config of service_component_name
-
- raw_request and xer are needed to form the correct metrics log
- """
- config, rels, dmaap = _get_config_rels_dmaap(service_component_name, raw_request, xer)
- return _recurse(config, rels, dmaap)
-
-
-def resolve_override(config, rels=[], dmaap={}):
- """
- Explicitly take in a config, rels, dmaap and try to resolve it.
- Useful for testing where you dont want to put the test values in consul
- """
- # use deepcopy to make sure that config is not touched
- return _recurse(copy.deepcopy(config), rels, dmaap)
-
-
-def resolve_all(service_component_name, raw_request, xer):
- """
- Return config, policies, and any other k such that service_component_name:k exists (other than :dmaap and :rels)
-
- raw_request and xer are needed to form the correct metrics log
- """
- allk = _consul_get_all_as_transaction(service_component_name, raw_request, xer)
- returnk = {}
-
- # replace the config with the resolved config
- returnk["config"] = resolve_override(allk[service_component_name],
- allk.get("{0}:rels".format(service_component_name), []),
- allk.get("{0}:dmaap".format(service_component_name), {}))
-
- # concatenate the items
- for k in allk:
- if "policies" in k:
- if "policies" not in returnk:
- returnk["policies"] = {}
- returnk["policies"]["event"] = {}
- returnk["policies"]["items"] = []
-
- if k.endswith(":policies/event"):
- returnk["policies"]["event"] = allk[k]
- elif ":policies/items" in k:
- returnk["policies"]["items"].append(allk[k])
- else:
- if not(k == service_component_name or k.endswith(":rels") or k.endswith(":dmaap")):
- # this would blow up if you had a key in consul without a : but this shouldnt happen
- suffix = k.split(":")[1]
- returnk[suffix] = allk[k]
-
- return returnk
-
-
-def get_key(key, service_component_name, raw_request, xer):
- """
- Try to fetch a key k from Consul of the form service_component_name:k
-
- raw_request and xer are needed to form the correct metrics log
- """
- if key == "policies":
- raise BadRequest(
- ":policies is a complex folder and should be retrieved using the service_component_all API")
-
- bts = utc()
- path = "v1/kv/{0}:{1}".format(service_component_name, key)
- response = requests.get("{0}/{1}".format(CONSUL, path))
- metrics(raw_request, bts, xer, "Consul", path, response.status_code, __name__, msg="Retrieving single Consul key {0} for {1}".format(key, service_component_name))
-
- try:
- response.raise_for_status()
- except requests.exceptions.HTTPError as exc:
- raise CantGetConfig(exc.response.status_code, exc.response.text)
- rest = json.loads(response.text)[0]
- return json.loads(base64.b64decode(rest["Value"]).decode("utf-8"))
diff --git a/app/app/config_binding_service/controller.py b/app/app/config_binding_service/controller.py
deleted file mode 100644
index c2eb21c..0000000
--- a/app/app/config_binding_service/controller.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# ============LICENSE_START=======================================================
-# Copyright (c) 2017-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=========================================================
-#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-
-import json
-import requests
-import connexion
-import uuid
-from flask import Response
-from config_binding_service import client, get_consul_uri
-from config_binding_service.logging import audit, utc, error, metrics
-
-
-def _get_helper(json_expecting_func, **kwargs):
- """
- Helper function used by several functions below
- """
- try:
- payload = json_expecting_func(**kwargs)
- response, status_code, mimetype = json.dumps(payload), 200, "application/json"
- except client.BadRequest as exc:
- response, status_code, mimetype = exc.response, exc.code, "text/plain"
- except client.CantGetConfig as exc:
- response, status_code, mimetype = exc.response, exc.code, "text/plain"
- except Exception:
- response, status_code, mimetype = "Unknown error", 500, "text/plain"
- return response, status_code, mimetype
-
-
-def _get_or_generate_xer(raw_request):
- """get or generate the transaction id"""
- xer = raw_request.headers.get("x-onap-requestid", None)
- if xer is None:
- # some components are still using the old name
- xer = raw_request.headers.get("x-ecomp-requestid", None)
- if xer is None:
- # the user did NOT supply a request id, generate one
- xer = str(uuid.uuid4())
- return xer
-
-
-def bind_all(service_component_name):
- """
- Get all the keys in Consul for this SCN, and bind the config
- """
- xer = _get_or_generate_xer(connexion.request)
- bts = utc()
- response, status_code, mimetype = _get_helper(client.resolve_all, service_component_name=service_component_name, raw_request=connexion.request, xer=xer)
- audit(connexion.request, bts, xer, status_code, __name__, "called for component {0}".format(service_component_name))
- # Even though some older components might be using the ecomp name, we return the proper one
- return Response(response=response, status=status_code, mimetype=mimetype, headers={"x-onap-requestid": xer})
-
-
-def bind_config_for_scn(service_component_name):
- """
- Bind just the config for this SCN
- """
- xer = _get_or_generate_xer(connexion.request)
- bts = utc()
- response, status_code, mimetype = _get_helper(client.resolve, service_component_name=service_component_name, raw_request=connexion.request, xer=xer)
- audit(connexion.request, bts, xer, status_code, __name__, "called for component {0}".format(service_component_name))
- return Response(response=response, status=status_code, mimetype=mimetype, headers={"x-onap-requestid": xer})
-
-
-def get_key(key, service_component_name):
- """
- Get a single key k of the form service_component_name:k from Consul.
- Should not be used and will return a BAD REQUEST for k=policies because it's a complex object
- """
- xer = _get_or_generate_xer(connexion.request)
- bts = utc()
- response, status_code, mimetype = _get_helper(client.get_key, key=key, service_component_name=service_component_name, raw_request=connexion.request, xer=xer)
- audit(connexion.request, bts, xer, status_code, __name__, "called for component {0}".format(service_component_name))
- return Response(response=response, status=status_code, mimetype=mimetype, headers={"x-onap-requestid": xer})
-
-
-def healthcheck():
- """
- CBS Healthcheck
- """
- xer = _get_or_generate_xer(connexion.request)
- path = "v1/catalog/service/config_binding_service"
- bts = utc()
- res = requests.get("{0}/{1}".format(get_consul_uri(), path))
- status = res.status_code
- if status == 200:
- msg = "CBS is alive and Consul connection OK"
- else:
- msg = "CBS is alive but cannot reach Consul"
- # treating this as a WARN because this could be a temporary network glitch. Also per EELF guidelines this is a 200 ecode (availability)
- error(connexion.request, xer, "WARN", 200, tgt_entity="Consul", tgt_path="/v1/catalog/service/config_binding_service", msg=msg)
- metrics(connexion.request, bts, xer, "Consul", path, res.status_code, __name__, msg="Checking Consul connectivity during CBS healthcheck, {0}".format(msg))
- audit(connexion.request, bts, xer, status, __name__, msg=msg)
- return Response(response=msg, status=status)
diff --git a/app/app/config_binding_service/logging.py b/app/app/config_binding_service/logging.py
deleted file mode 100644
index b6275a7..0000000
--- a/app/app/config_binding_service/logging.py
+++ /dev/null
@@ -1,204 +0,0 @@
-# ============LICENSE_START=======================================================
-# Copyright (c) 2017-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=========================================================
-#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-
-from logging import getLogger, Formatter
-from logging.handlers import RotatingFileHandler
-from os import makedirs
-import datetime
-
-
-_AUDIT_LOGGER = getLogger("defaultlogger")
-_ERROR_LOGGER = getLogger("defaultlogger")
-_METRICS_LOGGER = getLogger("defaultlogger")
-
-
-def _create_logger(name, logfile):
- """
- Create a RotatingFileHandler and a streamhandler for stdout
- https://docs.python.org/3/library/logging.handlers.html
- what's with the non-pythonic naming in these stdlib methods? Shameful.
- """
- logger = getLogger(name)
- file_handler = RotatingFileHandler(logfile,
- maxBytes=10000000, backupCount=2) # 10 meg with one backup..
- formatter = Formatter('%(message)s')
- file_handler.setFormatter(formatter)
- logger.setLevel("DEBUG")
- logger.addHandler(file_handler)
- return logger
-
-
-def create_loggers():
- """
- Public method to set the global logger, launched from Run
- This is *not* launched during unit testing, so unit tests do not create/write log files
- """
- makedirs("/opt/logs", exist_ok=True)
-
- # create the audit log
- aud_file = "/opt/logs/audit.log"
- open(aud_file, 'a').close() # this is like "touch"
- global _AUDIT_LOGGER
- _AUDIT_LOGGER = _create_logger("config_binding_service_audit", aud_file)
-
- # create the error log
- err_file = "/opt/logs/error.log"
- open(err_file, 'a').close() # this is like "touch"
- global _ERROR_LOGGER
- _ERROR_LOGGER = _create_logger("config_binding_service_error", err_file)
-
- # create the metrics log
- met_file = "/opt/logs/metrics.log"
- open(met_file, 'a').close() # this is like "touch"
- global _METRICS_LOGGER
- _METRICS_LOGGER = _create_logger("config_binding_service_metrics", met_file)
-
-
-def utc():
- """gets current time in utc"""
- return datetime.datetime.utcnow()
-
-
-def audit(raw_request, bts, xer, rcode, calling_mod, msg="n/a"):
- """
- write an EELF audit record per https://wiki.onap.org/download/attachments/1015849/ONAP%20application%20logging%20guidelines.pdf?api=v2
- %The audit fields implemented:
-
- 1 BeginTimestamp Implemented (bts)
- 2 EndTimestamp Auto Injected when this is called
- 3 RequestID Implemented (xer)
- 5 threadId n/a
- 7 serviceName Implemented (from Req)
- 9 StatusCode Auto injected based on rcode
- 10 ResponseCode Implemented (rcode)
- 13 Category log level - all audit records are INFO.
- 15 Server IP address Implemented (from Req)
- 16 ElapsedTime Auto Injected (milliseconds)
- 17 Server This is running in a Docker container so this is not applicable, my HOSTNAME is always "config_binding_service"
- 18 ClientIPaddress Implemented (from Req)
- 19 class name Implemented (mod), though docs say OOP, I am using the python module here
- 20 Unused ...implemented....
- 21-25 Custom n/a
- 26 detailMessage Implemented (msg)
-
- Not implemented
- 4 serviceInstanceID - ?
- 6 physical/virtual server name (Optional)
- 8 PartnerName - nothing in the request tells me this
- 11 Response Description - the CBS follows standard HTTP error codes so look them up
- 12 instanceUUID - Optional
- 14 Severity (Optional)
- """
- ets = utc()
-
- _AUDIT_LOGGER.info("{bts}|{ets}|{xer}||n/a||{path}||{status}|{rcode}|||INFO||{servip}|{et}|config_binding_service|{clientip}|{calling_mod}|||||||{msg}".format(
- bts=bts.isoformat(),
- ets=ets.isoformat(),
- xer=xer, rcode=rcode,
- path=raw_request.path.split("/")[1],
- status="COMPLETE" if rcode < 400 else "ERROR",
- servip=raw_request.host.split(":")[0],
- et=int((ets - bts).microseconds / 1000), # supposed to be in milleseconds
- clientip=raw_request.remote_addr,
- calling_mod=calling_mod, msg=msg
- ))
-
-
-def error(raw_request, xer, severity, ecode, tgt_entity="n/a", tgt_path="n/a", msg="n/a", adv_msg="n/a"):
- """
- write an EELF error record per
- the error fields implemented:
-
- 1 Timestamp Auto Injected when this is called
- 2 RequestID Implemented (xer)
- 3 ThreadID n/a
- 4 ServiceName Implemented (from Req)
- 6 TargetEntity Implemented (tgt_entity)
- 7 TargetServiceName Implemented (tgt_path)/
- 8 ErrorCategory Implemented (severity)
- 9. ErrorCode Implemented (ecode)
- 10 ErrorDescription Implemented (msg)
- 11. detailMessage Implemented (adv_msg)
-
- Not implemented:
- 5 PartnerName - nothing in the request tells me this
- """
- ets = utc()
-
- _ERROR_LOGGER.error("{ets}|{xer}|n/a|{path}||{tge}|{tgp}|{sev}|{ecode}|{msg}|{amsg}".format(
- ets=ets,
- xer=xer,
- path=raw_request.path.split("/")[1],
- tge=tgt_entity,
- tgp=tgt_path,
- sev=severity,
- ecode=ecode,
- msg=msg,
- amsg=adv_msg))
-
-
-def metrics(raw_request, bts, xer, target, target_path, rcode, calling_mod, msg="n/a"):
- """
- write an EELF metrics record per https://wiki.onap.org/download/attachments/1015849/ONAP%20application%20logging%20guidelines.pdf?api=v2
- %The metrics fields implemented:
-
- 1 BeginTimestamp Implemented (bts)
- 2 EndTimestamp Auto Injected when this is called
- 3 RequestID Implemented (xer)
- 5 threadId n/a
- 7 serviceName Implemented (from Req)
- 9 TargetEntity Implemented (target)
- 10 TargetServiceName Implemented (target_path)
- 11 StatusCode Implemented (based on rcode)
- 12 Response Code Implemented (rcode)
- 15 Category log level all metrics records are INFO.
- 17 Server IP address Implemented (from Req)
- 18 ElapsedTime Auto Injected (milliseconds)
- 19 Server This is running in a Docker container so this is not applicable, my HOSTNAME is always "config_binding_service"
- 20 ClientIPaddress Implemented (from Req)
- 21 class name Implemented (mod), though docs say OOP, I am using the python module here
- 22 Unused ...implemented....
- 24 TargetVirtualEntity n/a
- 25-28 Custom n/a
- 29 detailMessage Implemented (msg)
-
- Not implemented
- 4 serviceInstanceID - ?
- 6 physical/virtual server name (Optional)
- 8 PartnerName - nothing in the request tells me this
- 13 Response Description - the CBS follows standard HTTP error codes so look them up
- 14 instanceUUID - Optional
- 16 Severity (Optional)
- 23 ProcessKey - optional
- """
- ets = utc()
-
- _METRICS_LOGGER.info("{bts}|{ets}|{xer}||n/a||{path}||{tge}|{tgp}|{status}|{rcode}|||INFO||{servip}|{et}|config_binding_service|{clientip}|{calling_mod}|||n/a|||||{msg}".format(
- bts=bts.isoformat(),
- ets=ets.isoformat(),
- xer=xer,
- path=raw_request.path.split("/")[1],
- tge=target,
- tgp=target_path,
- status="COMPLETE" if rcode < 400 else "ERROR",
- rcode=rcode,
- servip=raw_request.host.split(":")[0],
- et=int((ets - bts).microseconds / 1000), # supposed to be in milleseconds
- clientip=raw_request.remote_addr,
- calling_mod=calling_mod, msg=msg
- ))
diff --git a/app/app/config_binding_service/openapi.yaml b/app/app/config_binding_service/openapi.yaml
deleted file mode 100644
index bc4dd49..0000000
--- a/app/app/config_binding_service/openapi.yaml
+++ /dev/null
@@ -1,112 +0,0 @@
-openapi: 3.0.0
-info:
- version: 2.3.0
- title: Config Binding Service
-paths:
- '/service_component/{service_component_name}':
- parameters:
- - name: service_component_name
- in: path
- description: >-
- Service Component Name. service_component_name must be a key in
- consul.
- required: true
- schema:
- type: string
- get:
- description: >-
- Binds the configuration for service_component_name and returns the bound
- configuration as a JSON
- operationId: config_binding_service.controller.bind_config_for_scn
- responses:
- '200':
- description: OK; the bound config is returned as an object
- content:
- '*/*':
- schema:
- type: object
- '404':
- description: there is no configuration in Consul for this component
- '/service_component_all/{service_component_name}':
- parameters:
- - name: service_component_name
- in: path
- description: >-
- Service Component Name. service_component_name must be a key in
- consul.
- required: true
- schema:
- type: string
- get:
- description: >-
- Binds the configuration for service_component_name and returns the bound
- configuration, policies, and any other keys that are in Consul
- operationId: config_binding_service.controller.bind_all
- responses:
- '200':
- description: >-
- OK; returns {config : ..., policies : ....., k : ...} for all other
- k in Consul
- content:
- '*/*':
- schema:
- type: object
- '404':
- description: there is no configuration in Consul for this component
- '/{key}/{service_component_name}':
- parameters:
- - name: key
- in: path
- description: >-
- this endpoint tries to pull service_component_name:key; key is the key
- after the colon
- required: true
- schema:
- type: string
- - name: service_component_name
- in: path
- description: Service Component Name.
- required: true
- schema:
- type: string
- get:
- description: >-
- this is an endpoint that fetches a generic service_component_name:key
- out of Consul. The idea is that we don't want to tie components to
- Consul directly in case we swap out the backend some day, so the CBS
- abstracts Consul from clients. The structuring and weird collision of
- this new API with the above is unfortunate but due to legacy concerns.
- operationId: config_binding_service.controller.get_key
- responses:
- '200':
- description: 'OK; returns service_component_name:key'
- content:
- '*/*':
- schema:
- type: object
- '400':
- description: >-
- bad request. Currently this is only returned on :policies, which is
- a complex object, and should be gotten through service_component_all
- content:
- '*/*':
- schema:
- type: string
- '404':
- description: key does not exist
- content:
- '*/*':
- schema:
- type: string
- /healthcheck:
- get:
- description: >-
- This is the health check endpoint. If this returns a 200, the server is
- alive and consul can be reached. If not a 200, either dead, or no
- connection to consul
- operationId: config_binding_service.controller.healthcheck
- responses:
- '200':
- description: Successful response
- '503':
- description: the config binding service cannot reach Consul
diff --git a/app/app/main.py b/app/app/main.py
deleted file mode 100755
index c7adaaf..0000000
--- a/app/app/main.py
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env python3
-
-# ============LICENSE_START=======================================================
-# Copyright (c) 2017-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.
-# ============LICENSE_END=========================================================
-#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-from config_binding_service.logging import create_loggers
-from config_binding_service import app
-
-if __name__ == "__main__":
- # Only for debugging while developing
- app.run(host='0.0.0.0', port=10000, debug=True)
-else:
- # Entrypoint in UWSGI
- create_loggers()
diff --git a/app/app/pom.xml b/app/app/pom.xml
deleted file mode 100644
index 3b634a6..0000000
--- a/app/app/pom.xml
+++ /dev/null
@@ -1,270 +0,0 @@
-<?xml version="1.0"?>
-<!--
-================================================================================
-Copyright (c) 2017-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.
-============LICENSE_END=========================================================
-
-ECOMP is a trademark and service mark of AT&T Intellectual Property.
--->
-<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>
-
- <parent>
- <groupId>org.onap.dcaegen2.platform.configbinding</groupId>
- <artifactId>app</artifactId>
- <version>2.3.0-SNAPSHOT</version>
- </parent>
- <!--- CHANGE THE FOLLOWING 3 OBJECTS for your own repo -->
- <groupId>org.onap.dcaegen2.platform.configbinding</groupId>
- <artifactId>app-app</artifactId>
- <name>dcaegen2-platform-configbinding-app-app</name>
- <version>2.3.0-SNAPSHOT</version>
- <url>http://maven.apache.org</url>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <sonar.sources>.</sonar.sources>
- <sonar.junit.reportsPath>xunit-results.xml</sonar.junit.reportsPath>
- <sonar.python.coverage.reportPath>coverage.xml</sonar.python.coverage.reportPath>
- <sonar.python.xunit.reportPath>xunit-results.xml</sonar.python.xunit.reportPath>
- <sonar.language>py</sonar.language>
- <sonar.pluginname>python</sonar.pluginname>
- <sonar.inclusions>config_binding_service/*.py</sonar.inclusions>
- <sonar.exclusions>tests/*,setup.py</sonar.exclusions>
- </properties>
- <build>
- <finalName>${project.artifactId}-${project.version}</finalName>
- <pluginManagement>
- <plugins>
- <!-- the following plugins are invoked from oparent, we do not need them -->
- <plugin>
- <groupId>org.sonatype.plugins</groupId>
- <artifactId>nexus-staging-maven-plugin</artifactId>
- <version>1.6.7</version>
- <configuration>
- <skipNexusStagingDeployMojo>true</skipNexusStagingDeployMojo>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-deploy-plugin</artifactId>
- <!-- This version supports the "deployAtEnd" parameter -->
- <version>2.8</version>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-enforcer-plugin</artifactId>
- <version>3.0.0-M1</version>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
- <!-- first disable the default Java plugins at various stages -->
- <!-- maven-resources-plugin is called during "*resource" phases by default behavior. it prepares the resources
- dir. we do not need it -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-resources-plugin</artifactId>
- <version>2.6</version>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
- <!-- maven-compiler-plugin is called during "compile" phases by default behavior. we do not need it -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>3.1</version>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
- <!-- maven-jar-plugin is called during "compile" phase by default behavior. we do not need it -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <version>2.4</version>
- <executions>
- <execution>
- <id>default-jar</id>
- <phase/>
- </execution>
- </executions>
- </plugin>
- <!-- maven-install-plugin is called during "install" phase by default behavior. it tries to copy stuff under
- target dir to ~/.m2. we do not need it -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-install-plugin</artifactId>
- <version>2.4</version>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
- <!-- maven-surefire-plugin is called during "test" phase by default behavior. it triggers junit test.
- we do not need it -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>2.12.4</version>
- <configuration>
- <skipTests>true</skipTests>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>exec-maven-plugin</artifactId>
- <version>1.2.1</version>
- <configuration>
- <executable>${session.executionRootDirectory}/mvn-phase-script.sh</executable>
- <environmentVariables>
- <!-- make mvn properties as env for our script -->
- <MVN_PROJECT_GROUPID>${project.groupId}</MVN_PROJECT_GROUPID>
- <MVN_PROJECT_ARTIFACTID>${project.artifactId}</MVN_PROJECT_ARTIFACTID>
- <MVN_PROJECT_VERSION>${project.version}</MVN_PROJECT_VERSION>
- <MVN_NEXUSPROXY>${onap.nexus.url}</MVN_NEXUSPROXY>
- <MVN_RAWREPO_BASEURL_UPLOAD>${onap.nexus.rawrepo.baseurl.upload}</MVN_RAWREPO_BASEURL_UPLOAD>
- <MVN_RAWREPO_BASEURL_DOWNLOAD>${onap.nexus.rawrepo.baseurl.download}</MVN_RAWREPO_BASEURL_DOWNLOAD>
- <MVN_RAWREPO_SERVERID>${onap.nexus.rawrepo.serverid}</MVN_RAWREPO_SERVERID>
- <MVN_DOCKERREGISTRY_DAILY>${onap.nexus.dockerregistry.daily}</MVN_DOCKERREGISTRY_DAILY>
- <MVN_DOCKERREGISTRY_RELEASE>${onap.nexus.dockerregistry.release}</MVN_DOCKERREGISTRY_RELEASE>
- </environmentVariables>
- </configuration>
- </plugin>
- </plugins>
- </pluginManagement>
- <plugins>
- <!-- plugin>
- <artifactId>maven-assembly-plugin</artifactId>
- <version>2.4.1</version>
- <configuration>
- <descriptors>
- <descriptor>assembly/dep.xml</descriptor>
- </descriptors>
- </configuration>
- <executions>
- <execution>
- <id>make-assembly</id>
- <phase>package</phase>
- <goals>
- <goal>single</goal>
- </goals>
- </execution>
- </executions>
- </plugin -->
- <!-- now we configure custom action (calling a script) at various lifecycle phases -->
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>exec-maven-plugin</artifactId>
- <version>1.2.1</version>
- <executions>
- <execution>
- <id>clean phase script</id>
- <phase>clean</phase>
- <goals>
- <goal>exec</goal>
- </goals>
- <configuration>
- <arguments>
- <argument>__</argument>
- <argument>clean</argument>
- </arguments>
- </configuration>
- </execution>
- <execution>
- <id>generate-sources script</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>exec</goal>
- </goals>
- <configuration>
- <arguments>
- <argument>__</argument>
- <argument>generate-sources</argument>
- </arguments>
- </configuration>
- </execution>
- <execution>
- <id>compile script</id>
- <phase>compile</phase>
- <goals>
- <goal>exec</goal>
- </goals>
- <configuration>
- <arguments>
- <argument>__</argument>
- <argument>compile</argument>
- </arguments>
- </configuration>
- </execution>
- <execution>
- <id>package script</id>
- <phase>package</phase>
- <goals>
- <goal>exec</goal>
- </goals>
- <configuration>
- <arguments>
- <argument>__</argument>
- <argument>package</argument>
- </arguments>
- </configuration>
- </execution>
- <execution>
- <id>test script</id>
- <phase>test</phase>
- <goals>
- <goal>exec</goal>
- </goals>
- <configuration>
- <arguments>
- <argument>__</argument>
- <argument>test</argument>
- </arguments>
- </configuration>
- </execution>
- <execution>
- <id>install script</id>
- <phase>install</phase>
- <goals>
- <goal>exec</goal>
- </goals>
- <configuration>
- <arguments>
- <argument>__</argument>
- <argument>install</argument>
- </arguments>
- </configuration>
- </execution>
- <execution>
- <id>deploy script</id>
- <phase>deploy</phase>
- <goals>
- <goal>exec</goal>
- </goals>
- <configuration>
- <arguments>
- <argument>__</argument>
- <argument>deploy</argument>
- </arguments>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-</project>
diff --git a/app/app/setup.py b/app/app/setup.py
deleted file mode 100644
index 38929c9..0000000
--- a/app/app/setup.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# ============LICENSE_START=======================================================
-# Copyright (c) 2017-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.
-# ============LICENSE_END=========================================================
-#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-
-from setuptools import setup, find_packages
-
-setup(
- name='config_binding_service',
- version='2.3.0',
- packages=find_packages(exclude=["tests.*", "tests"]),
- author="Tommy Carpenter",
- author_email="tommy@research.att.com",
- description='Service to fetch and bind configurations',
- url="https://gerrit.onap.org/r/#/admin/projects/dcaegen2/platform/configbinding",
- install_requires=["requests",
- "Flask",
- "six",
- "connexion[swagger-ui]"],
- package_data={'config_binding_service': ['openapi.yaml']}
-)
diff --git a/app/app/tests/__init__.py b/app/app/tests/__init__.py
deleted file mode 100644
index 1875bf6..0000000
--- a/app/app/tests/__init__.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# ================================================================================
-# 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=========================================================
-#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-
-
-# empty __init__.py so that pytest can add correct path to coverage report, -- per pytest
-# best practice guideline
diff --git a/app/app/tests/conftest.py b/app/app/tests/conftest.py
deleted file mode 100644
index c8f2a06..0000000
--- a/app/app/tests/conftest.py
+++ /dev/null
@@ -1,70 +0,0 @@
-import pytest
-from requests.exceptions import HTTPError
-from config_binding_service import get_consul_uri
-
-
-class FakeResponse():
- def __init__(self, status_code, text):
- self.text = text
- self.status_code = status_code
-
- def raise_for_status(self):
- if self.status_code >= 400:
- raise HTTPError(response=FakeResponse(404, ""))
-
-
-@pytest.fixture
-def expected_config():
- return {"deep": {"ALL YOUR SERVICE BELONG TO US": ['6.6.6.6:666', '7.7.7.7:777', '5.5.5.5:555', '5.5.5.5:555']},
- "doubledeep": {"sodeep": {"hello": "darkness"}}}
-
-
-@pytest.fixture
-def monkeyed_get_connection_info_from_consul():
- def _monkeyed_get_connection_info_from_consul(service_component_name):
- # shared monkeypatch. probably somewhat lazy because the function htis patches can be broken up.
- if service_component_name == "cdap":
- return '666.666.666.666:666'
- elif service_component_name == "testing_bravo.somedomain.com":
- return '7.7.7.7:777'
- elif service_component_name == "testing_alpha.somedomain.com":
- return '6.6.6.6:666'
- elif service_component_name == "testing_charlie.somedomain.com":
- return '5.5.5.5:555'
- elif service_component_name == "nonexistent_hope":
- return None # the real function returns None here
- elif service_component_name == "cdap_serv.dcae.ecomp.somedomain.com":
- broker_ip = '1.1.1.1'
- broker_port = 444
- return "http://{0}:{1}/application/{2}".format(broker_ip, broker_port, service_component_name)
- return _monkeyed_get_connection_info_from_consul
-
-
-@pytest.fixture
-def monkeyed_requests_get():
- def _monkeyed_requests_get(url):
- if url == "{0}/v1/kv/test_service_component_name.unknown.unknown.unknown.dcae.onap.org:dti".format(get_consul_uri()):
- return FakeResponse(status_code=200, text='[{"LockIndex":0,"Key":"test_service_component_name.unknown.unknown.unknown.dcae.onap.org:dti","Flags":0,"Value": "eyJteSIgOiAiZHRpIn0=","CreateIndex":4066524,"ModifyIndex":4066524}]')
- else:
- return FakeResponse(status_code=404, text="")
- return _monkeyed_requests_get
-
-
-@pytest.fixture
-def monkeyed_requests_put():
- def _monkeyed_requests_put(url, json):
- if url == "{0}/v1/txn".format(get_consul_uri()):
- key = json[0]["KV"]["Key"]
- if key == "test_service_component_name.unknown.unknown.unknown.dcae.onap.org":
- return FakeResponse(status_code=200, text='{"Results":[{"KV":{"LockIndex":0,"Key":"test_service_component_name.unknown.unknown.unknown.dcae.onap.org","Flags":0,"Value":"eyJteSIgOiAiYW1hemluZyBjb25maWcifQ==","CreateIndex":4051555,"ModifyIndex":4051555}},{"KV":{"LockIndex":0,"Key":"test_service_component_name.unknown.unknown.unknown.dcae.onap.org:dmaap","Flags":0,"Value":"eyJmb28iIDogImJhciJ9","CreateIndex":4051571,"ModifyIndex":4051571}},{"KV":{"LockIndex":0,"Key":"test_service_component_name.unknown.unknown.unknown.dcae.onap.org:dti","Flags":0,"Value":"eyJteSIgOiAiZHRpIn0=","CreateIndex":4066524,"ModifyIndex":4066524}},{"KV":{"LockIndex":0,"Key":"test_service_component_name.unknown.unknown.unknown.dcae.onap.org:policies/event","Flags":0,"Value":"eyJhY3Rpb24iOiAiZ2F0aGVyZWQiLCAidGltZXN0YW1wIjogIjIwMTgtMDItMTkgMTU6MzY6NDQuODc3MzgwIiwgInVwZGF0ZV9pZCI6ICJiYjczYzIwYS01ZmY4LTQ1MGYtODIyMy1kYTY3MjBhZGUyNjciLCAicG9saWNpZXNfY291bnQiOiAyfQ==","CreateIndex":4048564,"ModifyIndex":4048564}},{"KV":{"LockIndex":0,"Key":"test_service_component_name.unknown.unknown.unknown.dcae.onap.org:policies/items/DCAE_alex.Config_MS_alex_microservice","Flags":0,"Value":"eyJwb2xpY3lOYW1lIjogIkRDQUVfYWxleC5Db25maWdfTVNfYWxleF9taWNyb3NlcnZpY2UuMTMyLnhtbCIsICJwb2xpY3lDb25maWdNZXNzYWdlIjogIkNvbmZpZyBSZXRyaWV2ZWQhICIsICJyZXNwb25zZUF0dHJpYnV0ZXMiOiB7fSwgInBvbGljeUNvbmZpZ1N0YXR1cyI6ICJDT05GSUdfUkVUUklFVkVEIiwgIm1hdGNoaW5nQ29uZGl0aW9ucyI6IHsiT05BUE5hbWUiOiAiRENBRSIsICJOYW1lIjogIkRDQUUiLCAiQ29uZmlnTmFtZSI6ICJhbGV4X2NvbmZpZ19uYW1lIn0sICJjb25maWciOiB7InBvbGljeVNjb3BlIjogImFsZXhfcG9saWN5X3Njb3BlIiwgImNvbmZpZ05hbWUiOiAiYWxleF9jb25maWdfbmFtZSIsICJkZXNjcmlwdGlvbiI6ICJ0ZXN0IERDQUUgcG9saWN5LWhhbmRsZXIiLCAic2VydmljZSI6ICJhbGV4X3NlcnZpY2UiLCAicG9saWN5TmFtZSI6ICJhbGV4X3BvbGljeV9uYW1lIiwgInJpc2tMZXZlbCI6ICIzIiwgImtleTEiOiAidmFsdWUxIiwgInBvbGljeV9oZWxsbyI6ICJ3b3JsZCEiLCAiY29udGVudCI6IHsiZm9vIjogIm1pY3Jvc2VydmljZTMiLCAiZm9vX3VwZGF0ZWQiOiAiMjAxOC0wMS0zMFQxMzoyNTozMy4yMjJaIn0sICJyaXNrVHlwZSI6ICIxNzEyX0VURSIsICJndWFyZCI6ICJGYWxzZSIsICJ2ZXJzaW9uIjogIjAuMC4xIiwgImxvY2F0aW9uIjogIkNlbnRyYWwiLCAicG9saWN5X3VwZGF0ZWRfdHMiOiAiMjAxOC0wMi0xOVQxNTowOTo1NS4yMTdaIiwgInVwZGF0ZWRfcG9saWN5X2lkIjogIkRDQUVfYWxleC5Db25maWdfTVNfYWxleF9taWNyb3NlcnZpY2UiLCAicG9saWN5X3VwZGF0ZWRfdG9fdmVyIjogIjEzMiIsICJwcmlvcml0eSI6ICI0IiwgInBvbGljeV91cGRhdGVkX2Zyb21fdmVyIjogIjEzMSIsICJ0ZW1wbGF0ZVZlcnNpb24iOiAiMiIsICJ1dWlkIjogIjVlODdkN2M1LTBkYWYtNGI2Yi1hYjkyLTUzNjVjZjVkYjFlZiJ9LCAicHJvcGVydHkiOiBudWxsLCAidHlwZSI6ICJKU09OIiwgInBvbGljeVZlcnNpb24iOiAiMTMyIn0=","CreateIndex":4048564,"ModifyIndex":4065574}},{"KV":{"LockIndex":0,"Key":"test_service_component_name.unknown.unknown.unknown.dcae.onap.org:policies/items/DCAE_alex.Config_db_client_policy_id_value","Flags":0,"Value":"eyJwb2xpY3lOYW1lIjogIkRDQUVfYWxleC5Db25maWdfZGJfY2xpZW50X3BvbGljeV9pZF92YWx1ZS4xMzMueG1sIiwgInBvbGljeUNvbmZpZ01lc3NhZ2UiOiAiQ29uZmlnIFJldHJpZXZlZCEgIiwgInJlc3BvbnNlQXR0cmlidXRlcyI6IHt9LCAicG9saWN5Q29uZmlnU3RhdHVzIjogIkNPTkZJR19SRVRSSUVWRUQiLCAibWF0Y2hpbmdDb25kaXRpb25zIjogeyJPTkFQTmFtZSI6ICJEQ0FFIiwgIk5hbWUiOiAiRENBRSIsICJDb25maWdOYW1lIjogImFsZXhfY29uZmlnX25hbWUifSwgImNvbmZpZyI6IHsiZGJfY2xpZW50X3RzIjogIjIwMTctMTEtMjFUMTI6MTI6MTMuNjk2WiIsICJkYl9jbGllbnQiOiAiaXBzdW0iLCAicG9saWN5X2hlbGxvIjogIndvcmxkISIsICJwb2xpY3lfdXBkYXRlZF9mcm9tX3ZlciI6ICIxMzIiLCAidXBkYXRlZF9wb2xpY3lfaWQiOiAiRENBRV9hbGV4LkNvbmZpZ19kYl9jbGllbnRfcG9saWN5X2lkX3ZhbHVlIiwgInBvbGljeV91cGRhdGVkX3RzIjogIjIwMTgtMDItMTlUMTU6MDk6NTUuODEyWiIsICJwb2xpY3lfdXBkYXRlZF90b192ZXIiOiAiMTMzIn0sICJwcm9wZXJ0eSI6IG51bGwsICJ0eXBlIjogIkpTT04iLCAicG9saWN5VmVyc2lvbiI6ICIxMzMifQ==","CreateIndex":4048564,"ModifyIndex":4065570}},{"KV":{"LockIndex":0,"Key":"test_service_component_name.unknown.unknown.unknown.dcae.onap.org:rels","Flags":0,"Value":"WyJteS5hbWF6aW5nLnJlbGF0aW9uc2hpcCJd","CreateIndex":4051567,"ModifyIndex":4051567}}],"Errors":null,"Index":0,"LastContact":0,"KnownLeader":true}')
- elif key == "scn_exists":
- return FakeResponse(status_code=200, text='{"Results":[{"KV":{"LockIndex":0,"Key":"scn_exists","Flags":0,"Value":"eyJmb28zIiA6ICJiYXIzIn0=","CreateIndex":4067403,"ModifyIndex":4067403}},{"KV":{"LockIndex":0,"Key":"scn_exists:dmaap","Flags":0,"Value":"eyJmb280IiA6ICJiYXI0In0=","CreateIndex":4067410,"ModifyIndex":4067410}},{"KV":{"LockIndex":0,"Key":"scn_exists:rels","Flags":0,"Value":"WyJmb28iXQ==","CreateIndex":4067406,"ModifyIndex":4067406}},{"KV":{"LockIndex":0,"Key":"scn_exists_nord","Flags":0,"Value":"eyJmb281IiA6ICJiYXI1In0=","CreateIndex":4067340,"ModifyIndex":4067340}}],"Errors":null,"Index":0,"LastContact":0,"KnownLeader":true}')
- elif key == "scn_exists_nord":
- return FakeResponse(status_code=200, text='{"Results":[{"KV":{"LockIndex":0,"Key":"scn_exists_nord","Flags":0,"Value":"eyJmb281IiA6ICJiYXI1In0=","CreateIndex":4067340,"ModifyIndex":4067340}}],"Errors":null,"Index":0,"LastContact":0,"KnownLeader":true}')
- elif key == "test_resolve_scn":
- return FakeResponse(status_code=200, text='{"Results":[{"KV":{"LockIndex":0,"Key":"test_resolve_scn","Flags":0,"Value":"ewogICAgICAgICAgICAgICAgImRlZXAiIDogewogICAgICAgICAgICAgICAgICAgICJBTEwgWU9VUiBTRVJWSUNFIEJFTE9ORyBUTyBVUyIgOiAie3thbHBoYSxicmF2byxjaGFybGllfX0ifSwKICAgICAgICAgICAgICAgICJkb3VibGVkZWVwIiA6ICB7CiAgICAgICAgICAgICAgICAgICAgInNvZGVlcCIgOiB7ImhlbGxvIiA6ICI8PFdITz8+PiJ9fQogICAgICAgICAgICAgfQo=","CreateIndex":4068002,"ModifyIndex":4068002}},{"KV":{"LockIndex":0,"Key":"test_resolve_scn:dmaap","Flags":0,"Value":"eyJXSE8/IiA6ICJkYXJrbmVzcyJ9","CreateIndex":4068013,"ModifyIndex":4068013}},{"KV":{"LockIndex":0,"Key":"test_resolve_scn:rels","Flags":0,"Value":"WyJ0ZXN0aW5nX2FscGhhLnNvbWVkb21haW4uY29tIiwgInRlc3RpbmdfYnJhdm8uc29tZWRvbWFpbi5jb20iLCAidGVzdGluZ19jaGFybGllLnNvbWVkb21haW4uY29tIiwgInRlc3RpbmdfY2hhcmxpZS5zb21lZG9tYWluLmNvbSJd","CreateIndex":4068010,"ModifyIndex":4068010}}],"Errors":null,"Index":0,"LastContact":0,"KnownLeader":true}')
- elif key == "cbs_test_messed_up":
- return FakeResponse(status_code=200, text='{"Results":[{"KV":{"LockIndex":0,"Key":"cbs_test_messed_up","Flags":0,"Value":"eyJmb28iIDogImJhciJ9","CreateIndex":4864032,"ModifyIndex":4864052}},{"KV":{"LockIndex":0,"Key":"cbs_test_messed_up:badkey","Flags":0,"Value":"eyJub3QgYSBqc29ubm5uIFJFS1RUVFQ=","CreateIndex":4864075,"ModifyIndex":4864075}}],"Errors":null,"Index":0,"LastContact":0,"KnownLeader":true}')
- elif key == "scn_NOTexists":
- return FakeResponse(status_code=404, text="")
- return _monkeyed_requests_put
diff --git a/app/app/tests/test_api.py b/app/app/tests/test_api.py
deleted file mode 100644
index 118a2a0..0000000
--- a/app/app/tests/test_api.py
+++ /dev/null
@@ -1,103 +0,0 @@
-# ============LICENSE_START=======================================================
-# Copyright (c) 2017-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.
-# ============LICENSE_END=========================================================
-#
-# ECOMP is a trademark and service mark of AT&T Intellectual Property.
-import json
-import pytest
-import os
-import tempfile
-from config_binding_service import app
-
-
-TEST_NAME = "test_service_component_name.unknown.unknown.unknown.dcae.onap.org"
-
-
-# http://flask.pocoo.org/docs/1.0/testing/
-@pytest.fixture
-def cbsclient():
- db_fd, app.app.config['DATABASE'] = tempfile.mkstemp()
- app.app.config['TESTING'] = True
- testclient = app.app.test_client()
-
- yield testclient
-
- os.close(db_fd)
- os.unlink(app.app.config['DATABASE'])
-
-
-def test_get(monkeypatch, cbsclient, monkeyed_requests_put):
- monkeypatch.setattr('requests.put', monkeyed_requests_put)
-
- res = cbsclient.get('/service_component/scn_exists',
- headers={"x-onap-requestid": 123456789})
- assert(json.loads(res.data) == {"foo3": "bar3"})
- assert(res.status_code == 200)
- assert(res.headers["x-onap-requestid"] == "123456789")
-
- res = cbsclient.get('/service_component/scn_NOTexists',
- headers={"x-onap-requestid": 123456789})
- assert(res.status_code == 404)
- assert(res.headers["x-onap-requestid"] == "123456789")
-
- res = cbsclient.get('/service_component/asdfasdf',
- headers={"x-onap-requestid": 123456789})
- assert(res.status_code == 500)
- assert(res.headers["x-onap-requestid"] == "123456789")
-
-
-def test_generic(monkeypatch, cbsclient, monkeyed_requests_get, monkeyed_requests_put):
- monkeypatch.setattr('requests.put', monkeyed_requests_put)
- monkeypatch.setattr('requests.get', monkeyed_requests_get)
-
- res = cbsclient.get('/dti/{0}'.format(TEST_NAME))
- assert json.loads(res.data) == {"my": "dti"}
- assert res.json == {"my": "dti"}
- assert res.status_code == 200
- assert "x-onap-requestid" in res.headers
-
- res = cbsclient.get('/nokeyforyou/{0}'.format(TEST_NAME))
- assert res.status_code == 404
- assert "x-onap-requestid" in res.headers
-
- res = cbsclient.get('/policies/{0}'.format(TEST_NAME))
- assert res.status_code == 400
- assert "x-onap-requestid" in res.headers
-
-
-def test_resolve_all(monkeypatch, cbsclient, monkeyed_requests_put, monkeyed_get_connection_info_from_consul, expected_config):
- monkeypatch.setattr('requests.put', monkeyed_requests_put)
- monkeypatch.setattr('config_binding_service.client._get_connection_info_from_consul', monkeyed_get_connection_info_from_consul)
- withstuff = {'config': {'my': 'amazing config'},
- 'dti': {'my': 'dti'},
- 'policies': {'items': [{'policyName': 'DCAE_alex.Config_MS_alex_microservice.132.xml', 'policyConfigMessage': 'Config Retrieved! ', 'responseAttributes': {}, 'policyConfigStatus': 'CONFIG_RETRIEVED', 'matchingConditions': {'ONAPName': 'DCAE', 'Name': 'DCAE', 'ConfigName': 'alex_config_name'}, 'config': {'policyScope': 'alex_policy_scope', 'configName': 'alex_config_name', 'description': 'test DCAE policy-handler', 'service': 'alex_service', 'policyName': 'alex_policy_name', 'riskLevel': '3', 'key1': 'value1', 'policy_hello': 'world!', 'content': {'foo': 'microservice3', 'foo_updated': '2018-01-30T13:25:33.222Z'}, 'riskType': '1712_ETE', 'guard': 'False', 'version': '0.0.1', 'location': 'Central', 'policy_updated_ts': '2018-02-19T15:09:55.217Z', 'updated_policy_id': 'DCAE_alex.Config_MS_alex_microservice', 'policy_updated_to_ver': '132', 'priority': '4', 'policy_updated_from_ver': '131', 'templateVersion': '2', 'uuid': '5e87d7c5-0daf-4b6b-ab92-5365cf5db1ef'}, 'property': None, 'type': 'JSON', 'policyVersion': '132'}, {'policyName': 'DCAE_alex.Config_db_client_policy_id_value.133.xml', 'policyConfigMessage': 'Config Retrieved! ', 'responseAttributes': {}, 'policyConfigStatus': 'CONFIG_RETRIEVED', 'matchingConditions': {'ONAPName': 'DCAE', 'Name': 'DCAE', 'ConfigName': 'alex_config_name'}, 'config': {'db_client_ts': '2017-11-21T12:12:13.696Z', 'db_client': 'ipsum', 'policy_hello': 'world!', 'policy_updated_from_ver': '132', 'updated_policy_id': 'DCAE_alex.Config_db_client_policy_id_value', 'policy_updated_ts': '2018-02-19T15:09:55.812Z', 'policy_updated_to_ver': '133'}, 'property': None, 'type': 'JSON', 'policyVersion': '133'}], 'event': {'action': 'gathered', 'timestamp': '2018-02-19 15:36:44.877380', 'update_id': 'bb73c20a-5ff8-450f-8223-da6720ade267', 'policies_count': 2}}}
-
- assert cbsclient.get('service_component_all/{0}'.format(TEST_NAME)).json == withstuff
-
- assert cbsclient.get('service_component_all/test_resolve_scn').json == {"config": expected_config}
-
- res = cbsclient.get('/service_component_all/{0}'.format(TEST_NAME))
- assert json.loads(res.data) == withstuff
- assert res.json == withstuff
- assert res.status_code == 200
- assert "x-onap-requestid" in res.headers
-
- res = cbsclient.get('/service_component_all/test_resolve_scn')
- assert res.status_code == 200
- assert res.json == {"config": expected_config}
-
- res = cbsclient.get('/service_component_all/scn_NOTexists')
- assert res.status_code == 404
- assert "x-onap-requestid" in res.headers
diff --git a/app/app/tests/test_client.py b/app/app/tests/test_client.py
deleted file mode 100644
index 96c3467..0000000
--- a/app/app/tests/test_client.py
+++ /dev/null
@@ -1,206 +0,0 @@
-# ============LICENSE_START=======================================================
-# Copyright (c) 2017-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.
-# ============LICENSE_END=========================================================
-#
-
-from config_binding_service import client
-import pytest
-
-
-# pytest doesnt support objects in conftest
-class FakeReq(object):
- """used to fake the logging params"""
- def __init__(self):
- self.path = "/unittest in {0}".format(__name__)
- self.host = "localhost"
- self.remote_addr = "6.6.6.6"
-
-
-# pytest doesnt support objects in conftest
-class FakeConnexion(object):
- def __init__(self, headers, path, host, remote_addr):
- self.headers = headers
- self.path = path
- self.host = host
- self.remote_addr = remote_addr
-
-
-def test_consul_get_all_as_transaction(monkeypatch, monkeyed_requests_put):
- """tests _consul_get_all_as_transaction"""
- monkeypatch.setattr('requests.put', monkeyed_requests_put)
- allk = client._consul_get_all_as_transaction(
- "test_service_component_name.unknown.unknown.unknown.dcae.onap.org", FakeReq(), "unit test xer")
- assert allk == {
- 'test_service_component_name.unknown.unknown.unknown.dcae.onap.org': {'my': 'amazing config'},
- 'test_service_component_name.unknown.unknown.unknown.dcae.onap.org:dti': {'my': 'dti'},
- 'test_service_component_name.unknown.unknown.unknown.dcae.onap.org:dmaap': {'foo': 'bar'},
- 'test_service_component_name.unknown.unknown.unknown.dcae.onap.org:policies/event': {'action': 'gathered', 'timestamp': '2018-02-19 15:36:44.877380', 'update_id': 'bb73c20a-5ff8-450f-8223-da6720ade267', 'policies_count': 2},
- 'test_service_component_name.unknown.unknown.unknown.dcae.onap.org:policies/items/DCAE_alex.Config_MS_alex_microservice': {'policyName': 'DCAE_alex.Config_MS_alex_microservice.132.xml', 'policyConfigMessage': 'Config Retrieved! ', 'responseAttributes': {}, 'policyConfigStatus': 'CONFIG_RETRIEVED', 'matchingConditions': {'ONAPName': 'DCAE', 'Name': 'DCAE', 'ConfigName': 'alex_config_name'}, 'config': {'policyScope': 'alex_policy_scope', 'configName': 'alex_config_name', 'description': 'test DCAE policy-handler', 'service': 'alex_service', 'policyName': 'alex_policy_name', 'riskLevel': '3', 'key1': 'value1', 'policy_hello': 'world!', 'content': {'foo': 'microservice3', 'foo_updated': '2018-01-30T13:25:33.222Z'}, 'riskType': '1712_ETE', 'guard': 'False', 'version': '0.0.1', 'location': 'Central', 'policy_updated_ts': '2018-02-19T15:09:55.217Z', 'updated_policy_id': 'DCAE_alex.Config_MS_alex_microservice', 'policy_updated_to_ver': '132', 'priority': '4', 'policy_updated_from_ver': '131', 'templateVersion': '2', 'uuid': '5e87d7c5-0daf-4b6b-ab92-5365cf5db1ef'}, 'property': None, 'type': 'JSON', 'policyVersion': '132'},
- 'test_service_component_name.unknown.unknown.unknown.dcae.onap.org:policies/items/DCAE_alex.Config_db_client_policy_id_value': {'policyName': 'DCAE_alex.Config_db_client_policy_id_value.133.xml', 'policyConfigMessage': 'Config Retrieved! ', 'responseAttributes': {}, 'policyConfigStatus': 'CONFIG_RETRIEVED', 'matchingConditions': {'ONAPName': 'DCAE', 'Name': 'DCAE', 'ConfigName': 'alex_config_name'}, 'config': {'db_client_ts': '2017-11-21T12:12:13.696Z', 'db_client': 'ipsum', 'policy_hello': 'world!', 'policy_updated_from_ver': '132', 'updated_policy_id': 'DCAE_alex.Config_db_client_policy_id_value', 'policy_updated_ts': '2018-02-19T15:09:55.812Z', 'policy_updated_to_ver': '133'}, 'property': None, 'type': 'JSON', 'policyVersion': '133'},
- 'test_service_component_name.unknown.unknown.unknown.dcae.onap.org:rels': ['my.amazing.relationship']
- }
-
- allk = client._consul_get_all_as_transaction("cbs_test_messed_up", FakeReq(), "unit test xer")
- assert allk == {'cbs_test_messed_up': {'foo': 'bar'},
- 'cbs_test_messed_up:badkey': 'INVALID JSON'}
-
-
-def test_get_config_rels_dmaap(monkeypatch, monkeyed_requests_put):
- monkeypatch.setattr('requests.put', monkeyed_requests_put)
- assert ({"foo3": "bar3"}, ["foo"], {"foo4": "bar4"}) == client._get_config_rels_dmaap("scn_exists", FakeReq(), "unit test xer")
- assert ({"foo5": "bar5"}, [], {}) == client._get_config_rels_dmaap("scn_exists_nord", FakeReq(), "unit test xer")
-
-
-def test_bad_config_http():
- test_config = {'yeahhhhh': "{{}}"}
- test_rels = ["testing_bravo.somedomain.com"]
- assert {'yeahhhhh': []} == client.resolve_override(test_config, test_rels)
-
-
-def test_bad_config_dmaap():
- test_config = {'darkness': "<<>>"}
- test_dmaap = {"WHO?": "darkness"}
- assert {'darkness': {}} == client.resolve_override(test_config, test_dmaap)
-
-
-def test_config_with_list(monkeypatch, monkeyed_get_connection_info_from_consul):
- monkeypatch.setattr('config_binding_service.client._get_connection_info_from_consul',
- monkeyed_get_connection_info_from_consul)
- test_config_1 = {"dcae_target_type": [
- "vhss-ems", "pcrf-oam"], "downstream-laika": "{{ laika }}", "some-param": "Lorem ipsum dolor sit amet"}
- test_rels_1 = ["3df5292249ae4a949f173063617cea8d_docker-snmp-polling-firstnet-m"]
- test_bind_1 = client.resolve_override(test_config_1, test_rels_1, {})
- assert(test_bind_1 == {'dcae_target_type': [
- 'vhss-ems', 'pcrf-oam'], 'downstream-laika': [], 'some-param': 'Lorem ipsum dolor sit amet'})
-
- test_config_2 = {"foo": ["{{cdap}}", "notouching", "<<yo>>"]}
- test_rels_2 = ["cdap"]
- test_dmaap_2 = {"yo": "im here"}
- test_bind_2 = client.resolve_override(test_config_2, test_rels_2, test_dmaap_2)
- assert(test_bind_2 == {"foo": [['666.666.666.666:666'], "notouching", "im here"]})
-
-
-def test_cdap(monkeypatch, monkeyed_get_connection_info_from_consul):
- # user override to test CDAP functionality
- monkeypatch.setattr('config_binding_service.client._get_connection_info_from_consul',
- monkeyed_get_connection_info_from_consul)
- test_rels = ["testing_alpha.somedomain.com", "testing_bravo.somedomain.com",
- "testing_charlie.somedomain.com", "testing_charlie.somedomain.com", "cdap"]
- test_config = {"streams_publishes": "{{alpha}}",
- # should be dumped
- "services_calls": [{"somekey": "{{charlie}}"}],
- "cdap_to_manage": {'some_nested_thing': "{{cdap}}"}} # no dumps
- test_bind_1 = client.resolve_override(test_config, test_rels)
- assert test_bind_1 == {'services_calls': [{"somekey": ["5.5.5.5:555", "5.5.5.5:555"]}], 'streams_publishes': [
- "6.6.6.6:666"], 'cdap_to_manage': {'some_nested_thing': ['666.666.666.666:666']}}
- assert test_bind_1['services_calls'] == [{"somekey": ["5.5.5.5:555", "5.5.5.5:555"]}]
- assert test_bind_1['streams_publishes'] == ["6.6.6.6:666"]
-
-
-def test_multiple_service_types(monkeypatch, monkeyed_get_connection_info_from_consul):
- # test {{x,y,z}}
- monkeypatch.setattr('config_binding_service.client._get_connection_info_from_consul',
- monkeyed_get_connection_info_from_consul)
-
- # test 1: they all resovle
- test_rels = ["testing_alpha.somedomain.com", "testing_bravo.somedomain.com",
- "testing_charlie.somedomain.com", "testing_charlie.somedomain.com"]
- config = {"ALL YOUR SERVICE BELONG TO US": "{{alpha,bravo,charlie}}"}
- test_bind_1 = client.resolve_override(config, test_rels)
- assert(test_bind_1 == {"ALL YOUR SERVICE BELONG TO US": [
- '6.6.6.6:666', '7.7.7.7:777', '5.5.5.5:555', '5.5.5.5:555']})
-
- # test 2: two resolve, one is missing from rels key
- config2 = {"two there one not exist": "{{alpha,bravo,notexist}}"}
- test_bind_2 = client.resolve_override(config2, test_rels)
- assert(test_bind_2 == {"two there one not exist": [
- '6.6.6.6:666', '7.7.7.7:777']})
-
- # test 3: two resolve, one is in rels key but not registered
- config3 = {"two there one unregistered": "{{alpha,bravo,unregistered}}"}
- test_rels3 = ["testing_alpha.somedomain.com",
- "testing_bravo.somedomain.com", "unregistered.somedomain.com"]
- test_bind_3 = client.resolve_override(config3, test_rels3)
- assert(test_bind_3 == {"two there one unregistered": [
- '6.6.6.6:666', '7.7.7.7:777']})
-
-
-def test_dmaap(monkeypatch):
- # test resolving dmaap key
- config = {"TODAY IS YOUR LUCKY DAY": "<<XXX>>"}
- # does not match
- test_bind = client.resolve_override(
- config, dmaap={"XX": "ABSOLVEME"}) # XX != XXX
- assert(test_bind == {"TODAY IS YOUR LUCKY DAY": {}})
- # matches
- test_bind_2 = client.resolve_override(config, dmaap={"XXX": "ABSOLVEME"})
- assert(test_bind_2 == {"TODAY IS YOUR LUCKY DAY": "ABSOLVEME"})
-
-
-def test_config(monkeypatch, monkeyed_get_connection_info_from_consul):
- # test config override
- monkeypatch.setattr('config_binding_service.client._get_connection_info_from_consul',
- monkeyed_get_connection_info_from_consul)
- test_config = {"autoderegisterafter": "10m", "cdap_to_manage": {
- 'some_nested_thing': "{{cdap}}"}, "bindingttw": 5, "hcinterval": "5s"}
- test_rels = ["cdap"]
- test_bind_1 = client.resolve_override(test_config, test_rels)
- assert test_bind_1 == {'autoderegisterafter': '10m', 'cdap_to_manage': {
- 'some_nested_thing': ['666.666.666.666:666']}, 'bindingttw': 5, 'hcinterval': '5s'}
-
-
-def test_non_existent(monkeypatch, monkeyed_get_connection_info_from_consul):
- # test a valid config-rels but the key is not in Consul
- monkeypatch.setattr('config_binding_service.client._get_connection_info_from_consul',
- monkeyed_get_connection_info_from_consul)
- test_config = {"you shall not be fufilled": "{{nonexistent_hope}}"}
- # hopefully not registered in Consul..
- test_rels = ["nonexistent_hope.rework-central.ecomp.somedomain.com"]
- test_bind_1 = client.resolve_override(test_config, test_rels, {})
- assert(test_bind_1 == {"you shall not be fufilled": []})
-
-
-def test_broker_redirect(monkeypatch, monkeyed_get_connection_info_from_consul):
- # test the broker redirect
- monkeypatch.setattr('config_binding_service.client._get_connection_info_from_consul',
- monkeyed_get_connection_info_from_consul)
- test_config = {"gimmie_dat_cdap": "{{cdap_serv}}"}
- test_rels = ["cdap_serv.dcae.ecomp.somedomain.com"]
- assert {"gimmie_dat_cdap": ['http://1.1.1.1:444/application/cdap_serv.dcae.ecomp.somedomain.com']
- } == client.resolve_override(test_config, test_rels)
-
-
-def test_both(monkeypatch, monkeyed_get_connection_info_from_consul, expected_config):
- # test rels and http
- monkeypatch.setattr('config_binding_service.client._get_connection_info_from_consul',
- monkeyed_get_connection_info_from_consul)
- test_rels = ["testing_alpha.somedomain.com", "testing_bravo.somedomain.com",
- "testing_charlie.somedomain.com", "testing_charlie.somedomain.com"]
- test_dmaap = {"WHO?": "darkness"}
- config = {"deep": {"ALL YOUR SERVICE BELONG TO US": "{{alpha,bravo,charlie}}"},
- "doubledeep": {"sodeep": {"hello": "<<WHO?>>"}}}
- test_bind_1 = client.resolve_override(config, test_rels, test_dmaap)
- assert(test_bind_1 == expected_config)
-
-
-def test_failures(monkeypatch, monkeyed_requests_put, monkeyed_requests_get):
- monkeypatch.setattr('requests.put', monkeyed_requests_put)
- monkeypatch.setattr('requests.get', monkeyed_requests_get)
- monkeypatch.setattr('connexion.request', FakeConnexion({"x-onap-requestid": 123456789}, "/service_component", "mytestingmachine", "myremoteclient"))
- assert(client.resolve("scn_exists", FakeReq(), "unit test xer") == {"foo3": "bar3"})
- with pytest.raises(client.CantGetConfig):
- client.resolve("scn_NOTexists", FakeReq(), "unit test xer")
- with pytest.raises(client.CantGetConfig):
- client.get_key("nokeyforyou", "test_service_component_name.unknown.unknown.unknown.dcae.onap.org", FakeReq(), "unit test xer")
diff --git a/app/app/tox.ini b/app/app/tox.ini
deleted file mode 100644
index 40fa3b3..0000000
--- a/app/app/tox.ini
+++ /dev/null
@@ -1,26 +0,0 @@
-# content of: tox.ini , put in same dir as setup.py
-[tox]
-envlist = py36,flake8
-
-[testenv]
-deps=
- pytest
- coverage
- pytest-cov
-setenv =
- CONSUL_HOST = 8.8.8.8
- HOSTNAME = config_binding_service
- PYTHONPATH={toxinidir}
-commands=
- pytest --junitxml xunit-results.xml --cov config_binding_service --cov-report xml --cov-report term --cov-fail-under=70
- coverage xml -i
-
-[testenv:flake8]
-basepython = python3.6
-skip_install = true
-deps = flake8
-commands = flake8 setup.py config_binding_service tests
-
-[flake8]
-ignore = E501,W605
-
diff --git a/app/pom.xml b/app/pom.xml
deleted file mode 100644
index 3e9e65f..0000000
--- a/app/pom.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0"?>
-<!--
-================================================================================
-Copyright (c) 2017-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.
-============LICENSE_END=========================================================
-
-ECOMP is a trademark and service mark of AT&T Intellectual Property.
--->
-<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>
- <parent>
- <groupId>org.onap.dcaegen2.platform</groupId>
- <artifactId>configbinding</artifactId>
- <version>2.3.0-SNAPSHOT</version>
- </parent>
-
- <!--- CHANGE THE FOLLOWING 3 OBJECTS for your own repo -->
- <groupId>org.onap.dcaegen2.platform.configbinding</groupId>
- <artifactId>app</artifactId>
- <name>dcaegen2-platform-configbinding-app</name>
- <version>2.3.0-SNAPSHOT</version>
- <url>http://maven.apache.org</url>
-
- <packaging>pom</packaging>
- <modules>
- <module>app</module>
- </modules>
-
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <!-- customize the SONARQUBE URL -->
- <sonar.host.url>http://localhost:9000</sonar.host.url>
- <!-- taken care of in the children -->
- </properties>
- <build>
- <finalName>${project.artifactId}-${project.version}</finalName>
- <pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>exec-maven-plugin</artifactId>
- <version>1.2.1</version>
- <configuration>
- <executable>${session.executionRootDirectory}/mvn-phase-script.sh</executable>
- <environmentVariables>
- <!-- make mvn properties as env for our script -->
- <!-- make mvn properties as env for our script -->
- <MVN_PROJECT_GROUPID>${project.groupId}</MVN_PROJECT_GROUPID>
- <MVN_PROJECT_ARTIFACTID>${project.artifactId}</MVN_PROJECT_ARTIFACTID>
- <MVN_PROJECT_VERSION>${project.version}</MVN_PROJECT_VERSION>
- <MVN_NEXUSPROXY>${onap.nexus.url}</MVN_NEXUSPROXY>
- <MVN_RAWREPO_BASEURL_UPLOAD>${onap.nexus.rawrepo.baseurl.upload}</MVN_RAWREPO_BASEURL_UPLOAD>
- <MVN_RAWREPO_BASEURL_DOWNLOAD>${onap.nexus.rawrepo.baseurl.download}</MVN_RAWREPO_BASEURL_DOWNLOAD>
- <MVN_RAWREPO_SERVERID>${onap.nexus.rawrepo.serverid}</MVN_RAWREPO_SERVERID>
- <MVN_DOCKERREGISTRY_SNAPSHOT>${onap.nexus.dockerregistry.snapshot}</MVN_DOCKERREGISTRY_SNAPSHOT>
- <MVN_DOCKERREGISTRY_RELEASE>${onap.nexus.dockerregistry.release}</MVN_DOCKERREGISTRY_RELEASE>
- <MVN_DOCKERREGISTRY_SNAPSHOT_SERVERID>${onap.nexus.dockerregistry.snapshot.serverid}</MVN_DOCKERREGISTRY_SNAPSHOT_SERVERID>
- <MVN_DOCKERREGISTRY_RELEASE_SERVERID>${onap.nexus.dockerregistry.release.serverid}</MVN_DOCKERREGISTRY_RELEASE_SERVERID>
- <MVN_PYPISERVER_BASEURL>${onap.nexus.pypiserver.baseurl}</MVN_PYPISERVER_BASEURL>
- <MVN_PYPISERVER_SERVERID>${onap.nexus.pypiserver.serverid}</MVN_PYPISERVER_SERVERID>
- </environmentVariables>
- </configuration>
- </plugin>
- </plugins>
- </pluginManagement>
- </build>
-
-</project>
diff --git a/app/uwsgi.ini b/app/uwsgi.ini
deleted file mode 100644
index f514897..0000000
--- a/app/uwsgi.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[uwsgi]
-module = app.main
-callable = app