You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hugegraph.apache.org by va...@apache.org on 2023/03/01 09:20:00 UTC
[incubator-hugegraph] 01/01: fix: 401
This is an automated email from the ASF dual-hosted git repository.
vaughn pushed a commit to branch zy_dev
in repository https://gitbox.apache.org/repos/asf/incubator-hugegraph.git
commit 5d065c8e2f42117c3f8cf770ebe76d3d3c0e4786
Author: vaughn <va...@apache.org>
AuthorDate: Wed Mar 1 15:37:05 2023 +0800
fix: 401
---
.../hugegraph/api/filter/RedirectFilter.java | 72 +++++++++++++++++++++-
.../org/apache/hugegraph/api/job/GremlinAPI.java | 1 +
.../org/apache/hugegraph/api/job/RebuildAPI.java | 3 +
.../org/apache/hugegraph/api/raft/RaftAPI.java | 3 +
.../election/StandardStateMachineCallback.java | 9 ++-
5 files changed, 81 insertions(+), 7 deletions(-)
diff --git a/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/RedirectFilter.java b/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/RedirectFilter.java
index e6c7e2d98..92f5e0864 100644
--- a/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/RedirectFilter.java
+++ b/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/RedirectFilter.java
@@ -22,20 +22,43 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
import jakarta.ws.rs.NameBinding;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.Invocation;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerRequestFilter;
+import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.Response;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.URIBuilder;
import org.apache.hugegraph.election.GlobalMasterInfo;
import org.apache.hugegraph.util.Log;
+import org.glassfish.jersey.message.internal.HeaderUtils;
import org.slf4j.Logger;
public class RedirectFilter implements ContainerRequestFilter {
private static final Logger LOG = Log.logger(RedirectFilter.class);
+ public static final String X_HG_REDIRECT = "x-hg-redirect";
+
+ private static volatile Client client = null;
+
+ 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 requestContext) throws IOException {
@@ -44,6 +67,11 @@ public class RedirectFilter implements ContainerRequestFilter {
return;
}
+ String redirectTag = requestContext.getHeaderString(X_HG_REDIRECT);
+ if (StringUtils.isNotEmpty(redirectTag)) {
+ return;
+ }
+
String url = "";
synchronized (instance) {
if (instance.isMaster() || StringUtils.isEmpty(instance.url())) {
@@ -54,7 +82,7 @@ public class RedirectFilter implements ContainerRequestFilter {
URI redirectUri = null;
try {
- URIBuilder redirectURIBuilder = new URIBuilder(requestContext.getUriInfo().getAbsolutePath());
+ URIBuilder redirectURIBuilder = new URIBuilder(requestContext.getUriInfo().getRequestUri());
String[] host = url.split(":");
redirectURIBuilder.setHost(host[0]);
if (host.length == 2 && StringUtils.isNotEmpty(host[1].trim())) {
@@ -66,7 +94,47 @@ public class RedirectFilter implements ContainerRequestFilter {
LOG.error("Redirect request exception occurred", e);
return;
}
- requestContext.abortWith(Response.temporaryRedirect(redirectUri).build());
+ this.initClientIfNeeded();
+ Response response = this.forwardRequest(requestContext, redirectUri);
+ requestContext.abortWith(response);
+ }
+
+ private Response forwardRequest(ContainerRequestContext requestContext, URI redirectUri) {
+ 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 = null;
+ if (MUST_BE_NULL.contains(requestContext.getMethod())) {
+ response = builder.method(requestContext.getMethod());
+ } else {
+ response = builder.method(requestContext.getMethod(),
+ Entity.json(requestContext.getEntityStream()));
+ }
+ return response;
+ }
+
+ private void initClientIfNeeded() {
+ if (client != null) {
+ return;
+ }
+
+ synchronized (RedirectFilter.class) {
+ if (client != null) {
+ return;
+ }
+
+ client = ClientBuilder.newClient();
+ }
}
@NameBinding
diff --git a/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/GremlinAPI.java b/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/GremlinAPI.java
index 62e791367..aacfc2bb9 100644
--- a/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/GremlinAPI.java
+++ b/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/GremlinAPI.java
@@ -74,6 +74,7 @@ public class GremlinAPI extends API {
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON_WITH_CHARSET)
@RolesAllowed({"admin", "$owner=$graph $action=gremlin_execute"})
+ @RedirectFilter.RedirectMasterRole
public Map<String, Id> post(@Context GraphManager manager,
@PathParam("graph") String graph,
GremlinRequest request) {
diff --git a/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/RebuildAPI.java b/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/RebuildAPI.java
index 0fe87ee0f..7d00d63f0 100644
--- a/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/RebuildAPI.java
+++ b/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/RebuildAPI.java
@@ -53,6 +53,7 @@ public class RebuildAPI extends API {
@Status(Status.ACCEPTED)
@Produces(APPLICATION_JSON_WITH_CHARSET)
@RolesAllowed({"admin", "$owner=$graph $action=index_write"})
+ @RedirectFilter.RedirectMasterRole
public Map<String, Id> vertexLabelRebuild(@Context GraphManager manager,
@PathParam("graph") String graph,
@PathParam("name") String name) {
@@ -69,6 +70,7 @@ public class RebuildAPI extends API {
@Status(Status.ACCEPTED)
@Produces(APPLICATION_JSON_WITH_CHARSET)
@RolesAllowed({"admin", "$owner=$graph $action=index_write"})
+ @RedirectFilter.RedirectMasterRole
public Map<String, Id> edgeLabelRebuild(@Context GraphManager manager,
@PathParam("graph") String graph,
@PathParam("name") String name) {
@@ -85,6 +87,7 @@ public class RebuildAPI extends API {
@Status(Status.ACCEPTED)
@Produces(APPLICATION_JSON_WITH_CHARSET)
@RolesAllowed({"admin", "$owner=$graph $action=index_write"})
+ @RedirectFilter.RedirectMasterRole
public Map<String, Id> indexLabelRebuild(@Context GraphManager manager,
@PathParam("graph") String graph,
@PathParam("name") String name) {
diff --git a/hugegraph-api/src/main/java/org/apache/hugegraph/api/raft/RaftAPI.java b/hugegraph-api/src/main/java/org/apache/hugegraph/api/raft/RaftAPI.java
index 44d5b6587..dcf6cbb0d 100644
--- a/hugegraph-api/src/main/java/org/apache/hugegraph/api/raft/RaftAPI.java
+++ b/hugegraph-api/src/main/java/org/apache/hugegraph/api/raft/RaftAPI.java
@@ -34,6 +34,7 @@ import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.Context;
+import org.apache.hugegraph.api.filter.RedirectFilter;
import org.apache.hugegraph.core.GraphManager;
import org.slf4j.Logger;
@@ -151,6 +152,7 @@ public class RaftAPI extends API {
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON_WITH_CHARSET)
@RolesAllowed({"admin"})
+ @RedirectFilter.RedirectMasterRole
public Map<String, Id> addPeer(@Context GraphManager manager,
@PathParam("graph") String graph,
@QueryParam("group") @DefaultValue("default")
@@ -180,6 +182,7 @@ public class RaftAPI extends API {
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON_WITH_CHARSET)
@RolesAllowed({"admin"})
+ @RedirectFilter.RedirectMasterRole
public Map<String, Id> removePeer(@Context GraphManager manager,
@PathParam("graph") String graph,
@QueryParam("group")
diff --git a/hugegraph-core/src/main/java/org/apache/hugegraph/election/StandardStateMachineCallback.java b/hugegraph-core/src/main/java/org/apache/hugegraph/election/StandardStateMachineCallback.java
index d72172c8d..edca35880 100644
--- a/hugegraph-core/src/main/java/org/apache/hugegraph/election/StandardStateMachineCallback.java
+++ b/hugegraph-core/src/main/java/org/apache/hugegraph/election/StandardStateMachineCallback.java
@@ -41,9 +41,9 @@ public class StandardStateMachineCallback implements StateMachineCallback {
public void onAsRoleMaster(StateMachineContext context) {
if (!isMaster) {
this.taskManager.onAsRoleMaster();
- this.initGlobalMasterInfo(context);
LOG.info("Server {} change to master role", context.config().node());
}
+ this.initGlobalMasterInfo(context);
this.isMaster = true;
}
@@ -51,10 +51,9 @@ public class StandardStateMachineCallback implements StateMachineCallback {
public void onAsRoleWorker(StateMachineContext context) {
if (isMaster) {
this.taskManager.onAsRoleWorker();
- this.initGlobalMasterInfo(context);
LOG.info("Server {} change to worker role", context.config().node());
}
-
+ this.initGlobalMasterInfo(context);
this.isMaster = false;
}
@@ -66,9 +65,9 @@ public class StandardStateMachineCallback implements StateMachineCallback {
public void unknown(StateMachineContext context) {
if (isMaster) {
this.taskManager.onAsRoleWorker();
- this.initGlobalMasterInfo(context);
LOG.info("Server {} change to worker role", context.config().node());
}
+ this.initGlobalMasterInfo(context);
isMaster = false;
}
@@ -77,9 +76,9 @@ public class StandardStateMachineCallback implements StateMachineCallback {
public void onAsRoleAbdication(StateMachineContext context) {
if (isMaster) {
this.taskManager.onAsRoleWorker();
- this.initGlobalMasterInfo(context);
LOG.info("Server {} change to worker role", context.config().node());
}
+ this.initGlobalMasterInfo(context);
isMaster = false;
}