def __init__(self): self._thread = threading.Thread(target=self.run, name=LAYER_NAME) self._thread.daemon = True self.started = False self.__create_server() log.debug("Created RESTful API object with url_prefix: %s" % self.flask)
def initialize(self): log.debug("Initializing REST-API Sublayer...") self.__server.flask.before_request(self.incoming_logger) self.__server.flask.after_request(self.outcoming_logger) # Add <prefix>/version rule by default AdminView().register_rules(app=self.__server.flask) # Add custom exception handling self.__server.flask.register_error_handler(Exception, self.unhandled_exception)
def register_routes(self, app): """ :type app: :class:`Flask` """ for view in self.VIEWS: rule = self.__get_rule(view=view) app.add_url_rule(rule=rule, endpoint=self.__get_endpoint(view=view), view_func=view.as_view(name=view.name, mgr=self)) log.debug("Registered rule: %s" % rule)
def _register_entry_points(self, component): for meth in filter(lambda n: n.startswith(self.ENTRY_POINT_PREFIX), dir(component)): layer_name = component._core_name rpc_name = self.pythonify_rpc_name( meth[len(self.ENTRY_POINT_PREFIX):]) self.__entry_point_cache[(layer_name, rpc_name)] = getattr(component, meth) log.debug("Registered RPC call handlers: %s" % map(lambda e: e[1], self.__entry_point_cache.iterkeys()))
def dispatch_request(self, service_id): log.debug("Detected service id: %s" % service_id) mapping_info = self.proceed(service_id=service_id) if isinstance(mapping_info, basestring): return Response(response=mapping_info, status=httplib.BAD_REQUEST) MessageDumper().dump_to_file(data=json.dumps(mapping_info, indent=4), unique="ESCAPE-%s-status" % self.mgr.LAYER_NAME) log.debug("Sending collected mapping info...") return Response(response=json.dumps(mapping_info), status=httplib.OK, content_type="application/json")
def register_rules(cls, app): rule = "/%s/admin/version" % cls.prefix app.add_url_rule(rule="/%s/admin/version" % cls.prefix, endpoint="admin/version", view_func=cls.version) log.debug("Registered rule: %s" % rule) for r in cls.RULE_TEMPLATE: rule = r % cls.prefix app.add_url_rule(rule=rule, endpoint=rule, view_func=cls.as_view(name=cls.name)) log.debug("Registered rule: %s" % rule)
def register_component(self, component): component_name = component._core_name mgr_klass = CONFIG.get_rest_api_resource_class(layer=component_name) if mgr_klass is None: log.error("REST-API configuration is missing for component: %s" % component_name) return mgr = mgr_klass(layer_api=self) mgr.register_routes(app=self.__server.flask) self._register_entry_points(component=component) self.mgrs[mgr.LAYER_NAME] = mgr log.debug("Register component: %s into %s" % (component_name, self.__server))
def dispatch_request(self): if self.MESSAGE_ID_NAME in request.args: message_id = request.args[self.MESSAGE_ID_NAME] elif self.MESSAGE_ID_NAME in request.headers: message_id = request.headers[self.MESSAGE_ID_NAME] else: return Response("No message-id was given!", status=httplib.BAD_REQUEST) log.debug("Detected message-id: %s" % message_id) code, result = self.proceed(message_id=message_id) log.debug("Responded status code: %s, data: %s" % (code, result)) MessageDumper().dump_to_file(data=repr((code, result)), unique="ESCAPE-%s-status" % self.mgr.LAYER_NAME) return Response(result, status=code, headers={"message-id": message_id})
def dispatch_request(self): if not request.data: log.error("No data received!") return Response("Request data is missing!", httplib.BAD_REQUEST) # Get message-id MessageDumper().dump_to_file(data=request.data, unique="ESCAPE-%s-mappings" % self.mgr.LAYER_NAME) mappings = Mappings.parse_from_text(text=request.data) mappings = self.proceed(mappings=mappings) if not mappings: log.error("Calculated mapping data is missing!") return Response(status=httplib.INTERNAL_SERVER_ERROR) log.debug("Sending collected mapping info...") data = mappings.xml() MessageDumper().dump_to_file(data=data, unique="ESCAPE-%s-mappings-response" % self.mgr.LAYER_NAME) return Response(data, status=httplib.OK, content_type="application/xml")
def dispatch_request(self): """ :return: """ log.info("Received edit-config deploy request...") if not request.data: log.error("No data received!") return Response("Request data is missing!", httplib.BAD_REQUEST) # Get message-id unique = "ESCAPE-%s-edit-config" % self.mgr.LAYER_NAME # Trailing stats.init_request_measurement(request_id=unique) MessageDumper().dump_to_file(data=request.data, unique=unique) # Parsing log.debug("Parsing request (body_size: %s)..." % len(request.data)) if CONFIG.get_rest_api_config(self.mgr.LAYER_NAME)['unify_interface']: req = Virtualizer.parse_from_text(text=request.data) else: req = NFFG.parse(raw_data=request.data) if req.mode: log.info("Detected mapping mode in request body: %s" % req.mode) else: if request.method == 'POST': req.mode = req.MODE_ADD log.debug('Add mapping mode: %s based on HTTP verb: %s' % (req.mode, request.method)) elif request.method == 'PUT': req.mode = NFFG.MODE_DEL log.debug('Add mapping mode: %s based on HTTP verb: %s' % (req.mode, request.method)) else: log.info('No mode parameter has been defined in body!') log.debug("Request parsing ended...") # Scheduling params = request.args.to_dict(flat=True) msg_id = self.get_message_id() log.info("Acquired message-id: %s" % msg_id) params[self.MESSAGE_ID_NAME] = msg_id entry_point = self.mgr.layer_api.get_entry_point( layer=self.mgr.LAYER_NAME, rpc=self.name) self.mgr.scheduler.schedule_request(id=msg_id, layer=self.mgr.LAYER_NAME, hook=entry_point, data=req, params=params) return Response(status=httplib.ACCEPTED, headers={"message-id": msg_id})
def outcoming_logger(response): log.debug(">>> HTTP request: [%s] %s - %s ended!" % (request.method, request.url, response.status)) return response
def incoming_logger(): log.debug(">>> Got HTTP %s request: %s --> %s, body: %s" % (request.method, request.remote_addr, request.url, len(request.data)))
def shutdown(self): log.debug("Shutdown REST server...") self.__werkzeug.shutdown()