def process(self, request): mds_request_headers = httputil.HTTPHeaders() if "Authorization" in request.headers: mds_request_headers["Authorization"] = request.headers[ "Authorization"] traceid = getattr(request, "traceid", None) if traceid is not None: mds_request_headers["X-Request-Id"] = traceid key = request.headers["X-Srw-Key"] name, event = extract_app_and_event(request) self.proxy.setup_tracing(request, name) timeout = self.proxy.get_timeout(name, event) name = self.proxy.resolve_group_to_version(name) if self.is_stid_request(request): url = "%s/gate/dist-info/%s?primary-only" % ( self.dist_info_endpoint, key) request.logger.debug( "fetching endpoints via mulcagate dist-info - %s", url) srw_request = HTTPRequest(url, method="GET", headers=mds_request_headers, allow_ipv6=True, request_timeout=timeout) else: url = "%s/dist-info-%s/%s" % (self.mds_dist_info_endpoint, request.headers["X-Srw-Namespace"], key) request.logger.debug("fetching endpoints via mds dist-info - %s", url) srw_request = HTTPRequest(url, method="GET", headers=mds_request_headers, allow_ipv6=True, request_timeout=timeout) endpoints = yield self.fetch_mds_endpoints(request, srw_request) locator = Locator(endpoints=endpoints) app = Service(name, locator=locator, timeout=RESOLVE_TIMEOUT) request.logger.info("connecting to app %s", name) app = yield self.reelect_app(request, app) # TODO: attempts should be configurable yield self.proxy.process(request, name, app, event, pack_httprequest(request), self.reelect_app, 4, timeout)
def process(self, request): name, event = extract_app_and_event(request) timeout = self.proxy.get_timeout(name, event) # as MDS proxy bypasses the mechanism of routing groups # the proxy is responsible to provide this feature name = self.proxy.resolve_group_to_version(name) headers = request.headers namespace = headers["X-Srw-Namespace"] key = headers["X-Srw-Key"] mds_request_headers = httputil.HTTPHeaders() if "Authorization" in request.headers: mds_request_headers["Authorization"] = request.headers["Authorization"] traceid = getattr(request, "traceid", None) if traceid is not None: mds_request_headers["X-Request-Id"] = traceid srw_request = HTTPRequest("%s/exec-%s/%s/%s/stid/%s?timeout=%d" % (self.srw_host, namespace, name, event, key, timeout), method="POST", headers=mds_request_headers, body=msgpack.packb(pack_httprequest(request)), allow_ipv6=True, request_timeout=timeout) try: # NOTE: we can do it in a streaming way resp = yield self.srw_httpclient.fetch(srw_request) code, reply_headers, body = decode_chunked_encoded_reply(resp) fill_response_in(request, code, httplib.responses.get(code, httplib.OK), body, reply_headers) except HTTPError as err: if err.code == 404: raise PluginNoSuchApplication("worker was not found") if err.code == 500: raise PluginApplicationError(42, 42, "worker replied with error") if err.code == 401: fill_response_in(request, err.code, httplib.responses.get(err.code, httplib.OK), err.response.body, err.response.headers) return raise err
def process(self, request): mds_request_headers = httputil.HTTPHeaders() if "Authorization" in request.headers: mds_request_headers["Authorization"] = request.headers["Authorization"] traceid = getattr(request, "traceid", None) if traceid is not None: mds_request_headers["X-Request-Id"] = traceid key = request.headers["X-Srw-Key"] name, event = extract_app_and_event(request) timeout = self.proxy.get_timeout(name, event) name = self.proxy.resolve_group_to_version(name) if self.is_stid_request(request): url = "%s/gate/dist-info/%s?primary-only" % (self.dist_info_endpoint, key) request.logger.debug("fetching endpoints via mulcagate dist-info - %s", url) srw_request = HTTPRequest( url, method="GET", headers=mds_request_headers, allow_ipv6=True, request_timeout=timeout) else: url = "%s/dist-info-%s/%s" % (self.mds_dist_info_endpoint, request.headers["X-Srw-Namespace"], key) request.logger.debug("fetching endpoints via mds dist-info - %s", url) srw_request = HTTPRequest( url, method="GET", headers=mds_request_headers, allow_ipv6=True, request_timeout=timeout) endpoints = yield self.fetch_mds_endpoints(request, srw_request) locator = Locator(endpoints=endpoints) app = Service(name, locator=locator, timeout=RESOLVE_TIMEOUT) request.logger.info("connecting to app %s", name) app = yield self.reelect_app(request, app) yield self.proxy.process(request, name, app, event, pack_httprequest(request), self.reelect_app, timeout)
def __call__(self, request): for plugin in self.plugins: if plugin.match(request): request.logger.info('processed by %s plugin', plugin.name()) try: yield plugin.process(request) except PluginNoSuchApplication as err: fill_response_in(request, NO_SUCH_APP, "No such application", str(err), proxy_error_headers()) except PluginApplicationError: message = "application error" fill_response_in(request, httplib.INTERNAL_SERVER_ERROR, httplib.responses[httplib.INTERNAL_SERVER_ERROR], message, proxy_error_headers()) except ProxyInvalidRequest: if request.path == "/ping": self.ping(request) else: fill_response_in(request, httplib.NOT_FOUND, httplib.responses[httplib.NOT_FOUND], "Invalid url", proxy_error_headers()) except Exception as err: request.logger.exception('plugin %s returned error: %s', plugin.name(), err) message = "unknown error" fill_response_in(request, httplib.INTERNAL_SERVER_ERROR, httplib.responses[httplib.INTERNAL_SERVER_ERROR], message, proxy_error_headers()) return try: name, event = extract_app_and_event(request) except ProxyInvalidRequest: if request.path == "/ping": self.ping(request) else: fill_response_in(request, httplib.NOT_FOUND, httplib.responses[httplib.NOT_FOUND], "Invalid url", proxy_error_headers()) return self.setup_tracing(request, name) if self.sticky_header in request.headers: seed = request.headers.get(self.sticky_header) seed_value = header_to_seed(seed) request.logger.info('sticky_header has been found: name %s, value %s, seed %d', name, seed, seed_value) name = self.resolve_group_to_version(name, seed_value) app = yield self.get_service(name, request) if app is None: message = "current application %s is unavailable" % name fill_response_in(request, NO_SUCH_APP, "No Such Application", message, proxy_error_headers(name)) return try: # TODO: attempts should be configurable yield self.process(request, name, app, event, pack_httprequest(request), self.reelect_app, 2) except Exception as err: request.logger.exception("error during processing request %s", err) fill_response_in(request, httplib.INTERNAL_SERVER_ERROR, httplib.responses[httplib.INTERNAL_SERVER_ERROR], "UID %s: %s" % (request.traceid, str(err)), proxy_error_headers(name)) request.logger.info("exit from process")
def __call__(self, request): for plugin in self.plugins: if plugin.match(request): request.logger.info('processed by %s plugin', plugin.name()) try: yield plugin.process(request) except PluginNoSuchApplication as err: fill_response_in(request, NO_SUCH_APP, "No such application", str(err), proxy_error_headers()) except PluginApplicationError: message = "application error" fill_response_in( request, httplib.INTERNAL_SERVER_ERROR, httplib.responses[httplib.INTERNAL_SERVER_ERROR], message, proxy_error_headers()) except ProxyInvalidRequest: if request.path == "/ping": self.ping(request) else: fill_response_in(request, httplib.NOT_FOUND, httplib.responses[httplib.NOT_FOUND], "Invalid url", proxy_error_headers()) except Exception as err: request.logger.exception('plugin %s returned error: %s', plugin.name(), err) message = "unknown error" fill_response_in( request, httplib.INTERNAL_SERVER_ERROR, httplib.responses[httplib.INTERNAL_SERVER_ERROR], message, proxy_error_headers()) return try: name, event = extract_app_and_event(request) except ProxyInvalidRequest: if request.path == "/ping": self.ping(request) else: fill_response_in(request, httplib.NOT_FOUND, httplib.responses[httplib.NOT_FOUND], "Invalid url", proxy_error_headers()) return if getattr(request, "traceid", None) is not None: tracing_chance = self.sampled_apps.get(name, self.default_tracing_chance) rolled_dice = random.uniform(0, 100) request.logger.debug("tracing_chance %f, rolled dice %f", tracing_chance, rolled_dice) if tracing_chance < rolled_dice: request.logger.info('stop tracing the request') request.logger = NULLLOGGER request.traceid = None if self.sticky_header in request.headers: seed = request.headers.get(self.sticky_header) seed_value = header_to_seed(seed) request.logger.info( 'sticky_header has been found: name %s, value %s, seed %d', name, seed, seed_value) name = self.resolve_group_to_version(name, seed_value) app = yield self.get_service(name, request) if app is None: message = "current application %s is unavailable" % name fill_response_in(request, NO_SUCH_APP, "No Such Application", message, proxy_error_headers(name)) return try: yield self.process(request, name, app, event, pack_httprequest(request), self.reelect_app) except Exception as err: request.logger.exception("error during processing request %s", err) fill_response_in(request, httplib.INTERNAL_SERVER_ERROR, httplib.responses[httplib.INTERNAL_SERVER_ERROR], "UID %s: %s" % (request.traceid, str(err)), proxy_error_headers(name)) request.logger.info("exit from process")
def __call__(self, request): for plugin in self.plugins: if plugin.match(request): request.logger.info('processed by %s plugin', plugin.name()) try: yield plugin.process(request) except PluginNoSuchApplication as err: fill_response_in(request, NO_SUCH_APP, "No such application", str(err), proxy_error_headers()) except PluginApplicationError: message = "application error" fill_response_in( request, httplib.INTERNAL_SERVER_ERROR, httplib.responses[httplib.INTERNAL_SERVER_ERROR], message, proxy_error_headers()) except ProxyInvalidRequest: if request.path == "/ping": self.ping(request) else: fill_response_in(request, httplib.NOT_FOUND, httplib.responses[httplib.NOT_FOUND], "Invalid url", proxy_error_headers()) except Exception as err: request.logger.exception('plugin %s returned error: %s', plugin.name(), err) message = "unknown error" fill_response_in( request, httplib.INTERNAL_SERVER_ERROR, httplib.responses[httplib.INTERNAL_SERVER_ERROR], message, proxy_error_headers()) return try: name, event = extract_app_and_event(request) except ProxyInvalidRequest: if request.path == "/ping": self.ping(request) else: fill_response_in(request, httplib.NOT_FOUND, httplib.responses[httplib.NOT_FOUND], "Invalid url", proxy_error_headers()) return self.setup_tracing(request, name) if self.sticky_header in request.headers: seed = request.headers.get(self.sticky_header) seed_value = header_to_seed(seed) request.logger.info( 'sticky_header has been found: name %s, value %s, seed %d', name, seed, seed_value) name = self.resolve_group_to_version(name, seed_value) app = yield self.get_service(name, request) if app is None: message = "current application %s is unavailable" % name fill_response_in(request, NO_SUCH_APP, "No Such Application", message, proxy_error_headers(name)) return try: # TODO: attempts should be configurable yield self.process(request, name, app, event, pack_httprequest(request), self.reelect_app, 2) except Exception as err: request.logger.exception("error during processing request %s", err) fill_response_in(request, httplib.INTERNAL_SERVER_ERROR, httplib.responses[httplib.INTERNAL_SERVER_ERROR], "UID %s: %s" % (request.traceid, str(err)), proxy_error_headers(name)) request.logger.info("exit from process")
def __call__(self, request): for plugin in self.plugins: if plugin.match(request): request.logger.info('processed by %s plugin', plugin.name()) try: yield plugin.process(request) except PluginNoSuchApplication as err: fill_response_in(request, NO_SUCH_APP, "No such application", str(err), proxy_error_headers()) except PluginApplicationError: message = "application error" fill_response_in(request, httplib.INTERNAL_SERVER_ERROR, httplib.responses[httplib.INTERNAL_SERVER_ERROR], message, proxy_error_headers()) except ProxyInvalidRequest: if request.path == "/ping": self.ping(request) else: fill_response_in(request, httplib.NOT_FOUND, httplib.responses[httplib.NOT_FOUND], "Invalid url", proxy_error_headers()) except Exception as err: request.logger.exception('plugin %s returned error: %s', plugin.name(), err) message = "unknown error" fill_response_in(request, httplib.INTERNAL_SERVER_ERROR, httplib.responses[httplib.INTERNAL_SERVER_ERROR], message, proxy_error_headers()) return try: name, event = extract_app_and_event(request) except ProxyInvalidRequest: if request.path == "/ping": self.ping(request) else: fill_response_in(request, httplib.NOT_FOUND, httplib.responses[httplib.NOT_FOUND], "Invalid url", proxy_error_headers()) return if getattr(request, "traceid", None) is not None: tracing_chance = self.sampled_apps.get(name, self.default_tracing_chance) rolled_dice = random.uniform(0, 100) request.logger.debug("tracing_chance %f, rolled dice %f", tracing_chance, rolled_dice) if tracing_chance < rolled_dice: request.logger.info('stop tracing the request') request.logger = NULLLOGGER request.traceid = None if self.sticky_header in request.headers: seed = request.headers.get(self.sticky_header) seed_value = header_to_seed(seed) request.logger.info('sticky_header has been found: name %s, value %s, seed %d', name, seed, seed_value) name = self.resolve_group_to_version(name, seed_value) app = yield self.get_service(name, request) if app is None: message = "current application %s is unavailable" % name fill_response_in(request, NO_SUCH_APP, "No Such Application", message, proxy_error_headers(name)) return try: yield self.process(request, name, app, event, pack_httprequest(request), self.reelect_app) except Exception as err: request.logger.exception("error during processing request %s", err) fill_response_in(request, httplib.INTERNAL_SERVER_ERROR, httplib.responses[httplib.INTERNAL_SERVER_ERROR], "UID %s: %s" % (request.traceid, str(err)), proxy_error_headers(name)) request.logger.info("exit from process")