alex_sh | 9d980ce | 2017-08-23 17:30:56 -0400 | [diff] [blame] | 1 | # ================================================================================ |
Alex Shatov | d80b5d5 | 2018-02-05 13:01:14 -0500 | [diff] [blame] | 2 | # Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. |
alex_sh | 9d980ce | 2017-08-23 17:30:56 -0400 | [diff] [blame] | 3 | # ================================================================================ |
| 4 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | # you may not use this file except in compliance with the License. |
| 6 | # You may obtain a copy of the License at |
| 7 | # |
| 8 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | # |
| 10 | # Unless required by applicable law or agreed to in writing, software |
| 11 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | # See the License for the specific language governing permissions and |
| 14 | # limitations under the License. |
| 15 | # ============LICENSE_END========================================================= |
| 16 | # |
| 17 | # ECOMP is a trademark and service mark of AT&T Intellectual Property. |
| 18 | |
Alex Shatov | f53e5e7 | 2018-01-11 11:15:56 -0500 | [diff] [blame] | 19 | """web-service for policy_handler""" |
| 20 | |
alex_sh | 9d980ce | 2017-08-23 17:30:56 -0400 | [diff] [blame] | 21 | import logging |
| 22 | import json |
| 23 | from datetime import datetime |
| 24 | import cherrypy |
| 25 | |
| 26 | from .config import Config |
| 27 | from .onap.audit import Audit |
| 28 | from .policy_rest import PolicyRest |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 29 | from .policy_receiver import PolicyReceiver |
alex_sh | 9d980ce | 2017-08-23 17:30:56 -0400 | [diff] [blame] | 30 | |
| 31 | class PolicyWeb(object): |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 32 | """run REST API of policy-handler""" |
| 33 | logger = logging.getLogger("policy_handler.policy_web") |
alex_sh | 9d980ce | 2017-08-23 17:30:56 -0400 | [diff] [blame] | 34 | |
| 35 | @staticmethod |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 36 | def run_forever(audit): |
| 37 | """run the web-server of the policy-handler forever""" |
| 38 | PolicyWeb.logger.info("policy_handler web-service at port(%d)...", Config.wservice_port) |
| 39 | cherrypy.config.update({"server.socket_host": "0.0.0.0", |
| 40 | 'server.socket_port': Config.wservice_port}) |
| 41 | cherrypy.tree.mount(_PolicyWeb(), '/') |
| 42 | audit.info("running policy_handler web-service at port({0})".format(Config.wservice_port)) |
| 43 | cherrypy.engine.start() |
alex_sh | 9d980ce | 2017-08-23 17:30:56 -0400 | [diff] [blame] | 44 | |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 45 | class _PolicyWeb(object): |
| 46 | """REST API of policy-handler""" |
| 47 | |
| 48 | @staticmethod |
| 49 | def _get_request_info(request): |
| 50 | """returns info about the http request""" |
| 51 | return "{0} {1}{2}".format(request.method, request.script_name, request.path_info) |
| 52 | |
alex_sh | 9d980ce | 2017-08-23 17:30:56 -0400 | [diff] [blame] | 53 | @cherrypy.expose |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 54 | @cherrypy.popargs('policy_id') |
| 55 | @cherrypy.tools.json_out() |
| 56 | def policy_latest(self, policy_id): |
| 57 | """retireves the latest policy identified by policy_id""" |
| 58 | req_info = _PolicyWeb._get_request_info(cherrypy.request) |
Alex Shatov | 50bed53 | 2018-04-27 11:53:55 -0400 | [diff] [blame^] | 59 | audit = Audit(job_name="get_latest_policy", |
| 60 | req_message=req_info, headers=cherrypy.request.headers) |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 61 | PolicyWeb.logger.info("%s policy_id=%s headers=%s", \ |
| 62 | req_info, policy_id, json.dumps(cherrypy.request.headers)) |
| 63 | |
Alex Shatov | 2322ef8 | 2018-01-25 17:40:39 -0500 | [diff] [blame] | 64 | latest_policy = PolicyRest.get_latest_policy((audit, policy_id, None, None)) or {} |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 65 | |
Alex Shatov | 2322ef8 | 2018-01-25 17:40:39 -0500 | [diff] [blame] | 66 | PolicyWeb.logger.info("res %s policy_id=%s latest_policy=%s", |
| 67 | req_info, policy_id, json.dumps(latest_policy)) |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 68 | |
Alex Shatov | 2322ef8 | 2018-01-25 17:40:39 -0500 | [diff] [blame] | 69 | success, http_status_code, _ = audit.audit_done(result=json.dumps(latest_policy)) |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 70 | if not success: |
Alex Shatov | 2322ef8 | 2018-01-25 17:40:39 -0500 | [diff] [blame] | 71 | cherrypy.response.status = http_status_code |
| 72 | |
| 73 | return latest_policy |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 74 | |
| 75 | def _get_all_policies_latest(self): |
| 76 | """retireves all the latest policies on GET /policies_latest""" |
| 77 | req_info = _PolicyWeb._get_request_info(cherrypy.request) |
Alex Shatov | 50bed53 | 2018-04-27 11:53:55 -0400 | [diff] [blame^] | 78 | audit = Audit(job_name="get_all_policies_latest", |
| 79 | req_message=req_info, headers=cherrypy.request.headers) |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 80 | |
| 81 | PolicyWeb.logger.info("%s", req_info) |
| 82 | |
Alex Shatov | ac779d3 | 2018-02-01 14:16:56 -0500 | [diff] [blame] | 83 | result = PolicyRest.get_latest_policies(audit) |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 84 | |
Alex Shatov | ac779d3 | 2018-02-01 14:16:56 -0500 | [diff] [blame] | 85 | PolicyWeb.logger.info("result %s: %s", req_info, json.dumps(result)) |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 86 | |
Alex Shatov | ac779d3 | 2018-02-01 14:16:56 -0500 | [diff] [blame] | 87 | success, http_status_code, _ = audit.audit_done(result=json.dumps(result)) |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 88 | if not success: |
Alex Shatov | 2322ef8 | 2018-01-25 17:40:39 -0500 | [diff] [blame] | 89 | cherrypy.response.status = http_status_code |
| 90 | |
Alex Shatov | ac779d3 | 2018-02-01 14:16:56 -0500 | [diff] [blame] | 91 | return result |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 92 | |
| 93 | @cherrypy.expose |
| 94 | @cherrypy.tools.json_out() |
| 95 | @cherrypy.tools.json_in() |
| 96 | def policies_latest(self): |
| 97 | """ |
| 98 | on :GET: retrieves all the latest policies from policy-engine that are |
| 99 | in the scope of the policy-handler. |
| 100 | |
| 101 | on :POST: expects to receive the params that mimic the /getConfig of policy-engine |
| 102 | and retrieves the matching policies from policy-engine and picks the latest on each policy. |
| 103 | |
| 104 | sample request - policies filter |
| 105 | |
| 106 | { |
| 107 | "configAttributes": { "key1":"value1" }, |
| 108 | "configName": "alex_config_name", |
Alex Shatov | b9b955c | 2018-03-08 13:12:23 -0500 | [diff] [blame] | 109 | "onapName": "DCAE", |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 110 | "policyName": "DCAE_alex.Config_alex_.*", |
| 111 | "unique": false |
| 112 | } |
| 113 | |
| 114 | sample response |
| 115 | |
| 116 | { |
| 117 | "DCAE_alex.Config_alex_priority": { |
| 118 | "policy_body": { |
| 119 | "policyName": "DCAE_alex.Config_alex_priority.3.xml", |
| 120 | "policyConfigMessage": "Config Retrieved! ", |
| 121 | "responseAttributes": {}, |
| 122 | "policyConfigStatus": "CONFIG_RETRIEVED", |
| 123 | "type": "JSON", |
| 124 | "matchingConditions": { |
| 125 | "priority": "10", |
| 126 | "key1": "value1", |
Alex Shatov | b9b955c | 2018-03-08 13:12:23 -0500 | [diff] [blame] | 127 | "ONAPName": "DCAE", |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 128 | "ConfigName": "alex_config_name" |
| 129 | }, |
| 130 | "property": null, |
| 131 | "config": { |
| 132 | "foo": "bar", |
Alex Shatov | 2322ef8 | 2018-01-25 17:40:39 -0500 | [diff] [blame] | 133 | "foo_updated": "2018-10-06T16:54:31.696Z" |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 134 | }, |
| 135 | "policyVersion": "3" |
| 136 | }, |
| 137 | "policy_id": "DCAE_alex.Config_alex_priority" |
| 138 | } |
| 139 | } |
| 140 | """ |
| 141 | if cherrypy.request.method == "GET": |
| 142 | return self._get_all_policies_latest() |
| 143 | |
| 144 | if cherrypy.request.method != "POST": |
| 145 | raise cherrypy.HTTPError(404, "unexpected method {0}".format(cherrypy.request.method)) |
| 146 | |
| 147 | policy_filter = cherrypy.request.json or {} |
| 148 | str_policy_filter = json.dumps(policy_filter) |
| 149 | |
| 150 | req_info = _PolicyWeb._get_request_info(cherrypy.request) |
Alex Shatov | 50bed53 | 2018-04-27 11:53:55 -0400 | [diff] [blame^] | 151 | audit = Audit(job_name="get_latest_policies", |
| 152 | req_message="{0}: {1}".format(req_info, str_policy_filter), \ |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 153 | headers=cherrypy.request.headers) |
| 154 | PolicyWeb.logger.info("%s: policy_filter=%s headers=%s", \ |
| 155 | req_info, str_policy_filter, json.dumps(cherrypy.request.headers)) |
| 156 | |
Alex Shatov | ac779d3 | 2018-02-01 14:16:56 -0500 | [diff] [blame] | 157 | result = PolicyRest.get_latest_policies(audit, policy_filter=policy_filter) or {} |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 158 | |
Alex Shatov | ac779d3 | 2018-02-01 14:16:56 -0500 | [diff] [blame] | 159 | PolicyWeb.logger.info("result %s: policy_filter=%s result=%s", \ |
| 160 | req_info, str_policy_filter, json.dumps(result)) |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 161 | |
Alex Shatov | ac779d3 | 2018-02-01 14:16:56 -0500 | [diff] [blame] | 162 | success, http_status_code, _ = audit.audit_done(result=json.dumps(result)) |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 163 | if not success: |
Alex Shatov | 2322ef8 | 2018-01-25 17:40:39 -0500 | [diff] [blame] | 164 | cherrypy.response.status = http_status_code |
| 165 | |
Alex Shatov | ac779d3 | 2018-02-01 14:16:56 -0500 | [diff] [blame] | 166 | return result |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 167 | |
| 168 | @cherrypy.expose |
| 169 | @cherrypy.tools.json_out() |
| 170 | def catch_up(self): |
| 171 | """catch up with all DCAE policies""" |
| 172 | started = str(datetime.now()) |
| 173 | req_info = _PolicyWeb._get_request_info(cherrypy.request) |
Alex Shatov | 50bed53 | 2018-04-27 11:53:55 -0400 | [diff] [blame^] | 174 | audit = Audit(job_name="catch_up", req_message=req_info, headers=cherrypy.request.headers) |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 175 | |
| 176 | PolicyWeb.logger.info("%s", req_info) |
| 177 | PolicyReceiver.catch_up(audit) |
| 178 | |
| 179 | res = {"catch-up requested": started} |
| 180 | PolicyWeb.logger.info("requested %s: %s", req_info, json.dumps(res)) |
| 181 | audit.info_requested(started) |
| 182 | return res |
| 183 | |
| 184 | @cherrypy.expose |
| 185 | def shutdown(self): |
| 186 | """Shutdown the policy-handler""" |
| 187 | req_info = _PolicyWeb._get_request_info(cherrypy.request) |
Alex Shatov | 50bed53 | 2018-04-27 11:53:55 -0400 | [diff] [blame^] | 188 | audit = Audit(job_name="shutdown", req_message=req_info, headers=cherrypy.request.headers) |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 189 | |
| 190 | PolicyWeb.logger.info("%s: --- stopping REST API of policy-handler ---", req_info) |
| 191 | |
alex_sh | 9d980ce | 2017-08-23 17:30:56 -0400 | [diff] [blame] | 192 | cherrypy.engine.exit() |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 193 | |
| 194 | PolicyReceiver.shutdown(audit) |
| 195 | |
| 196 | health = json.dumps(Audit.health()) |
| 197 | audit.info("policy_handler health: {0}".format(health)) |
| 198 | PolicyWeb.logger.info("policy_handler health: %s", health) |
| 199 | PolicyWeb.logger.info("%s: --------- the end -----------", req_info) |
alex_sh | 9d980ce | 2017-08-23 17:30:56 -0400 | [diff] [blame] | 200 | res = str(datetime.now()) |
| 201 | audit.info_requested(res) |
| 202 | return "goodbye! shutdown requested {0}".format(res) |
| 203 | |
alex_sh | 9d980ce | 2017-08-23 17:30:56 -0400 | [diff] [blame] | 204 | @cherrypy.expose |
| 205 | @cherrypy.tools.json_out() |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 206 | def healthcheck(self): |
| 207 | """returns the healthcheck results""" |
| 208 | req_info = _PolicyWeb._get_request_info(cherrypy.request) |
Alex Shatov | 50bed53 | 2018-04-27 11:53:55 -0400 | [diff] [blame^] | 209 | audit = Audit(job_name="healthcheck", |
| 210 | req_message=req_info, headers=cherrypy.request.headers) |
Alex Shatov | 1369bea | 2018-01-10 11:00:50 -0500 | [diff] [blame] | 211 | |
| 212 | PolicyWeb.logger.info("%s", req_info) |
| 213 | |
| 214 | res = Audit.health() |
| 215 | |
| 216 | PolicyWeb.logger.info("healthcheck %s: res=%s", req_info, json.dumps(res)) |
| 217 | |
alex_sh | 9d980ce | 2017-08-23 17:30:56 -0400 | [diff] [blame] | 218 | audit.audit_done(result=json.dumps(res)) |
| 219 | return res |