Esempio n. 1
0
    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)
Esempio n. 2
0
    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
Esempio n. 3
0
    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)
Esempio n. 4
0
    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")
Esempio n. 5
0
    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")
Esempio n. 6
0
    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")
Esempio n. 7
0
    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")