class RedirectFilter implements ContainerRequestFilter {

    private static final Logger LOG = Log.logger(RedirectFilter.class);

    private static final String X_HG_REDIRECT = "x-hg-redirect";

    private static volatile Client client = null;

    @Context
    private IterableProvider<GraphManager> managerProvider;

    private static final Set<String> MUST_BE_NULL = new HashSet<>();

    static {
        MUST_BE_NULL.add("DELETE");
        MUST_BE_NULL.add("GET");
        MUST_BE_NULL.add("HEAD");
        MUST_BE_NULL.add("TRACE");
    }

    @Override
    public void filter(ContainerRequestContext context) throws IOException {
        ServiceHandle<GraphManager> handle = this.managerProvider.getHandle();
        E.checkState(handle != null, "Context GraphManager is absent");
        GraphManager manager = handle.getService();
        E.checkState(manager != null, "Context GraphManager is absent");

        String redirectTag = context.getHeaderString(X_HG_REDIRECT);
        if (StringUtils.isNotEmpty(redirectTag)) {
            return;
        }

        GlobalMasterInfo globalNodeInfo = manager.globalNodeRoleInfo();
        if (globalNodeInfo == null || !globalNodeInfo.supportElection()) {
            return;
        }
        GlobalMasterInfo.NodeInfo masterInfo = globalNodeInfo.masterInfo();
        if (masterInfo == null || masterInfo.isMaster() ||
            StringUtils.isEmpty(masterInfo.nodeUrl())) {
            return;
        }
        String url = masterInfo.nodeUrl();

        URI redirectUri;
        try {
            URIBuilder redirectURIBuilder = new URIBuilder(context.getUriInfo().getRequestUri());
            URI masterURI = URI.create(url);
            redirectURIBuilder.setHost(masterURI.getHost());
            redirectURIBuilder.setPort(masterURI.getPort());
            redirectURIBuilder.setScheme(masterURI.getScheme());

            redirectUri = redirectURIBuilder.build();
        } catch (URISyntaxException e) {
            LOG.error("Redirect request exception occurred", e);
            return;
        }
        this.initClientIfNeeded();
        Response response = this.forwardRequest(context, redirectUri);
        context.abortWith(response);
    }

    private Response forwardRequest(ContainerRequestContext requestContext, URI redirectUri) {<FILL_FUNCTION_BODY>}

    private void initClientIfNeeded() {
        if (client != null) {
            return;
        }

        synchronized (RedirectFilter.class) {
            if (client != null) {
                return;
            }
            client = ClientBuilder.newClient();
        }
    }

    @NameBinding
    @Retention(RetentionPolicy.RUNTIME)
    public @interface RedirectMasterRole {

    }
}

        MultivaluedMap<String, String> headers = requestContext.getHeaders();
        MultivaluedMap<String, Object> newHeaders = HeaderUtils.createOutbound();
        if (headers != null) {
            for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
                for (String value : entry.getValue()) {
                    newHeaders.add(entry.getKey(), value);
                }
            }
        }
        newHeaders.add(X_HG_REDIRECT, new Date().getTime());
        Invocation.Builder builder = client.target(redirectUri)
                                           .request()
                                           .headers(newHeaders);
        Response response;
        if (MUST_BE_NULL.contains(requestContext.getMethod())) {
            response = builder.method(requestContext.getMethod());
        } else {
            response = builder.method(requestContext.getMethod(),
                                      Entity.json(requestContext.getEntityStream()));
        }
        return response;
    
<no_super_class>