diff options
author | Tommy Carpenter <tommy@research.att.com> | 2018-02-20 07:47:25 -0500 |
---|---|---|
committer | Tommy Carpenter <tommy@research.att.com> | 2018-02-20 14:40:20 -0500 |
commit | e0117d81950cb8fdb5e56858d11fbfab6f3766a2 (patch) | |
tree | ba13f3f43ff73bfde959201fcb4c31cddec58e48 /config_binding_service | |
parent | cddb7244e2853737644f06043056526437ecb7fe (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.py | 105 | ||||
-rw-r--r-- | config_binding_service/controller.py | 19 | ||||
-rw-r--r-- | config_binding_service/swagger/swagger.yaml | 35 |
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" |