aboutsummaryrefslogtreecommitdiffstats
path: root/config_binding_service
diff options
context:
space:
mode:
authorTommy Carpenter <tommy@research.att.com>2018-02-20 07:47:25 -0500
committerTommy Carpenter <tommy@research.att.com>2018-02-20 14:40:20 -0500
commite0117d81950cb8fdb5e56858d11fbfab6f3766a2 (patch)
treeba13f3f43ff73bfde959201fcb4c31cddec58e48 /config_binding_service
parentcddb7244e2853737644f06043056526437ecb7fe (diff)
Implement the new api service_component_all
Change-Id: I50cc54f65023d61e1a085fdd2b13654553f7b7ad Issue-ID: DCAEGEN2-348 Signed-off-by: Tommy Carpenter <tommy@research.att.com>
Diffstat (limited to 'config_binding_service')
-rw-r--r--config_binding_service/client.py105
-rw-r--r--config_binding_service/controller.py19
-rw-r--r--config_binding_service/swagger/swagger.yaml35
3 files changed, 78 insertions, 81 deletions
diff --git a/config_binding_service/client.py b/config_binding_service/client.py
index a78a993..957b4be 100644
--- a/config_binding_service/client.py
+++ b/config_binding_service/client.py
@@ -41,31 +41,45 @@ class CantGetConfig(Exception):
###
# Private Functions
###
-def _consul_get_key(key):
+def _consul_get_all_as_transaction(service_component_name):
"""
- Try to fetch a key from Consul.
- No error checking here, let caller deal with it
+ Use Consul's transaction API to get all keys of the form service_component_name:*
+ Return a dict with all the values decoded
"""
- _logger.info("Fetching {0}".format(key))
- response = requests.get("{0}/v1/kv/{1}".format(CONSUL, key))
- response.raise_for_status()
- D = json.loads(response.text)[0]
- return json.loads(base64.b64decode(D["Value"]).decode("utf-8"))
+ payload = [
+ {
+ "KV": {
+ "Verb": "get-tree",
+ "Key": service_component_name,
+ }
+ }]
+
+ response = requests.put("{0}/v1/txn".format(CONSUL),
+ json = payload)
-def _get_config_rels_dmaap(service_component_name):
- #this one is critical, if we hit an error, blow up and raise to the caller
- config = _consul_get_key(service_component_name) #not ok if no config
-
- rels = []
- dmaap = {}
- try: #Not all nodes have relationships, so catch the error here and return [] if so
- rels = _consul_get_key("{0}:rel".format(service_component_name))
- except requests.exceptions.HTTPError: #ok if no rels key, might just have dmaap key
- pass
try:
- dmaap = _consul_get_key("{0}:dmaap".format(service_component_name))
- except requests.exceptions.HTTPError: #ok if no dmaap key
- pass
+ response.raise_for_status()
+ except requests.exceptions.HTTPError as e:
+ raise CantGetConfig(e.response.status_code, e.response.text)
+
+ res = json.loads(response.text)['Results']
+
+ new_res = {}
+ for r in res:
+ key = r["KV"]["Key"]
+ val = r["KV"]["Value"]
+ new_res[key] = json.loads(base64.b64decode(r["KV"]["Value"]).decode("utf-8"))
+
+ if service_component_name not in new_res:
+ raise CantGetConfig(404, "")
+
+ return new_res
+
+def _get_config_rels_dmaap(service_component_name):
+ allk = _consul_get_all_as_transaction(service_component_name)
+ 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):
@@ -172,11 +186,7 @@ def resolve(service_component_name):
"""
Return the bound config of service_component_name
"""
- try:
- config, rels, dmaap = _get_config_rels_dmaap(service_component_name)
- except requests.exceptions.HTTPError as e:
- raise CantGetConfig(e.response.status_code, e.response.text)
- _logger.info("Fetching {0}: config={1}, rels={2}".format(service_component_name, json.dumps(config), rels))
+ config, rels, dmaap = _get_config_rels_dmaap(service_component_name)
return _recurse(config, rels, dmaap)
def resolve_override(config, rels=[], dmaap={}):
@@ -187,18 +197,33 @@ def resolve_override(config, rels=[], dmaap={}):
#use deepcopy to make sure that config is not touched
return _recurse(copy.deepcopy(config), rels, dmaap)
-def resolve_DTI(service_component_name):
- try:
- config = _consul_get_key("{}:dti".format(service_component_name))
- except requests.exceptions.HTTPError as e:
- #might be a 404, or could be not even able to reach consul (503?), bubble up the requests error
- raise CantGetConfig(e.response.status_code, e.response.text)
- return config
+def resolve_all(service_component_name):
+ """
+ Return config, DTI, and policies, and any other key (other than :dmaap and :rels)
+ """
+ allk = _consul_get_all_as_transaction(service_component_name)
+ returnk = {}
+
+ #replace the config with the resolved config
+ returnk["config"] = resolve(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])
+ elif k == service_component_name or k.endswith(":rels") or k.endswith(":dmaap"):
+ pass
+ else:
+ suffix = k.split(":")[1] #this would blow up if you had a key in consul without a : but this shouldnt happen
+ returnk[suffix] = allk[k]
+
+ return returnk
-def resolve_policies(service_component_name):
- try:
- config = _consul_get_key("{}:policies".format(service_component_name))
- except requests.exceptions.HTTPError as e:
- #might be a 404, or could be not even able to reach consul (503?), bubble up the requests error
- raise CantGetConfig(e.response.status_code, e.response.text)
- return config
diff --git a/config_binding_service/controller.py b/config_binding_service/controller.py
index 1841bed..4ece194 100644
--- a/config_binding_service/controller.py
+++ b/config_binding_service/controller.py
@@ -23,10 +23,10 @@ import json
_logger = get_logger(__name__)
-def dtievents(service_component_name):
+def bind_all(service_component_name):
try:
- dti = client.resolve_DTI(service_component_name)
- return Response(response=json.dumps(dti),
+ allk = client.resolve_all(service_component_name)
+ return Response(response=json.dumps(allk),
status=200,
mimetype="application/json")
except client.CantGetConfig as e:
@@ -37,19 +37,6 @@ def dtievents(service_component_name):
return Response(response="Unknown error: please report",
status=500)
-def policies(service_component_name):
- try:
- dti = client.resolve_policies(service_component_name)
- return Response(response=json.dumps(dti),
- status=200,
- mimetype="application/json")
- except client.CantGetConfig as e:
- return Response(status=e.code,
- response=e.response)
- except Exception as e:
- _logger.error(e)
- return Response(response="Unknown error: please report",
- status=500)
def bind_config_for_scn(service_component_name):
try:
bound = client.resolve(service_component_name)
diff --git a/config_binding_service/swagger/swagger.yaml b/config_binding_service/swagger/swagger.yaml
index ce6cf7d..ac7098f 100644
--- a/config_binding_service/swagger/swagger.yaml
+++ b/config_binding_service/swagger/swagger.yaml
@@ -20,14 +20,14 @@
---
swagger: "2.0"
info:
- version: "1.3.1"
+ version: "2.0.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 and service_component_name:rels must be keys in consul."
+ description: "Service Component Name. service_component_name must be a key in consul."
required: true
type: "string"
get:
@@ -40,40 +40,25 @@ paths:
type: object
404:
description: there is no configuration in Consul for this component
- /dti/{service_component_name}:
- parameters:
- - name: "service_component_name"
- in: "path"
- description: "Service Component Name. service_component_name:dti must be a key in consul."
- required: true
- type: "string"
- get:
- description: "Returns as JSON the value for service_component_name:dti"
- operationId: "config_binding_service.controller.dtievents"
- responses:
- 200:
- description: OK; the KV value is returned as an object
- schema:
- type: object
- 404:
- description: there is no configuration in Consul for this component's DTI events
- /policies/{service_component_name}:
+
+ /service_component_all/{service_component_name}:
parameters:
- name: "service_component_name"
in: "path"
- description: "Service Component Name. service_component_name:policies must be a key in consul."
+ description: "Service Component Name. service_component_name must be a key in consul."
required: true
type: "string"
get:
- description: "Returns as JSON the value for service_component_name:policies"
- operationId: "config_binding_service.controller.policies"
+ 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; the KV value is returned as an object
+ description: "OK; returns {config : ..., policies : ....., k : ...} for all other k in Consul"
schema:
type: object
404:
- description: there is no configuration in Consul for this component's policies
+ description: there is no configuration in Consul for this component
+
/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"