Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(api): support ignore graphspaces segment in url #2612

Merged
merged 12 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.hugegraph.api.filter;

import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.stream.Collectors;

import org.apache.hugegraph.config.HugeConfig;
import org.apache.hugegraph.config.ServerOptions;
import org.apache.hugegraph.util.Log;
import org.slf4j.Logger;

import jakarta.inject.Singleton;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerRequestFilter;
import jakarta.ws.rs.container.PreMatching;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.UriBuilder;
import jakarta.ws.rs.ext.Provider;

/**
* TODO: Change the adaptor logic to keep compatibility with the non-"GraphSpace" version after we
* support "GraphSpace"
*/
@Provider
@Singleton
@PreMatching
public class GraphSpaceFilter implements ContainerRequestFilter {

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

private static final String GRAPHSPACES_PATH = "graphspaces/";

@Context
private jakarta.inject.Provider<HugeConfig> configProvider;

/**
* Filters incoming HTTP requests to modify the request URI if it matches certain criteria.
* <p>
* This filter checks if the request URI starts with the {@link #GRAPHSPACES_PATH} path
* segment. If it does,
* the filter removes the {@link #GRAPHSPACES_PATH} segment along with the following segment
* and then reconstructs
* the remaining URI. The modified URI is set back into the request context. This is useful for
* supporting legacy paths or adapting to new API structures.
* </p>
*
* <p><b>Example:</b></p>
* <pre>
* URI baseUri = URI.create("http://localhost:8080/");
* URI requestUri = URI.create("http://localhost:8080/graphspaces/DEFAULT/graphs");
*
* // Before filter:
* context.getUriInfo().getRequestUri(); // returns http://localhost:8080/graphspaces/DEFAULT/graphs
*
* // After filter:
* context.getUriInfo().getRequestUri(); // returns http://localhost:8080/graphs
* </pre>
*
* @param context The {@link ContainerRequestContext} which provides access to the request
* details.
* @throws IOException If an input or output exception occurs.
*/
@Override
public void filter(ContainerRequestContext context) throws IOException {
VGalaxies marked this conversation as resolved.
Show resolved Hide resolved
HugeConfig config = configProvider.get();
if (!config.get(ServerOptions.REST_SERVER_ENABLE_GRAPHSPACES_FILTER)) {
return;

Check warning on line 85 in hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/GraphSpaceFilter.java

View check run for this annotation

Codecov / codecov/patch

hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/GraphSpaceFilter.java#L85

Added line #L85 was not covered by tests
}

// Step 1: Get relativePath
URI baseUri = context.getUriInfo().getBaseUri();
URI requestUri = context.getUriInfo().getRequestUri();
URI relativePath = baseUri.relativize(requestUri);

String relativePathStr = relativePath.getPath();
// TODO: remember remove the logic after we support "GraphSpace"
if (!relativePathStr.startsWith(GRAPHSPACES_PATH)) {
return;
}

// Step 2: Extract the next substring after {@link #GRAPHSPACES_PATH}
String[] parts = relativePathStr.split("/");
if (parts.length <= 1) {
return;

Check warning on line 102 in hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/GraphSpaceFilter.java

View check run for this annotation

Codecov / codecov/patch

hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/GraphSpaceFilter.java#L102

Added line #L102 was not covered by tests
}

String ignoredPart = Arrays.stream(parts)
.limit(2) // Ignore the first two segments
.collect(Collectors.joining("/"));

// Reconstruct the remaining path
String newPath = Arrays.stream(parts)
.skip(2) // Skip the first two segments
.collect(Collectors.joining("/"));

// Step 3: Modify RequestUri and log the ignored part
URI newUri = UriBuilder.fromUri(baseUri)
.path(newPath)
.replaceQuery(requestUri.getRawQuery())
.build();
context.setRequestUri(newUri);

// Log the ignored part
if (LOG.isDebugEnabled()) {
LOG.debug("Ignored graphspaces segment: {}", ignoredPart);

Check warning on line 123 in hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/GraphSpaceFilter.java

View check run for this annotation

Codecov / codecov/patch

hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/GraphSpaceFilter.java#L123

Added line #L123 was not covered by tests
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ public static synchronized ServerOptions instance() {
"http://127.0.0.1:8080"
);

public static final ConfigOption<Boolean> REST_SERVER_ENABLE_GRAPHSPACES_FILTER =
new ConfigOption<>(
"restserver.enable_graphspaces_filter",
"Whether to enable graphspaces url filter.",
disallowEmpty(),
false
);

public static final ConfigOption<String> SERVER_ID =
new ConfigOption<>(
"server.id",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# bind url
# could use '0.0.0.0' or specified (real)IP to expose external network access
restserver.url=http://127.0.0.1:8080
#restserver.enable_graphspaces_filter=false
# gremlin server url, need to be consistent with host and port in gremlin-server.yaml
#gremlinserver.url=http://127.0.0.1:8182

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ fi
# config rest-server
sed -i 's/#auth.authenticator=/auth.authenticator=org.apache.hugegraph.auth.StandardAuthenticator/' $REST_SERVER_CONF
sed -i 's/#auth.admin_token=/auth.admin_token=pa/' $REST_SERVER_CONF
sed -i 's/#restserver.enable_graphspaces_filter=false/restserver.enable_graphspaces_filter=true/' $REST_SERVER_CONF

# config hugegraph.properties
sed -i 's/gremlin.graph=.*/gremlin.graph=org.apache.hugegraph.auth.HugeFactoryAuthProxy/' $CONF
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.apache.hugegraph.api;

import org.apache.hugegraph.api.graphspaces.GraphSpaceApiTestSuite;
import org.apache.hugegraph.api.traversers.TraversersApiTestSuite;
import org.apache.hugegraph.dist.RegisterUtil;
import org.junit.BeforeClass;
Expand All @@ -40,7 +41,8 @@
ProjectApiTest.class,
TraversersApiTestSuite.class,
CypherApiTest.class,
ArthasApiTest.class
ArthasApiTest.class,
GraphSpaceApiTestSuite.class
})
public class ApiTestSuite {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@

public class BaseApiTest {

private static final String BASE_URL = "http://127.0.0.1:8080";
protected static final String BASE_URL = "http://127.0.0.1:8080";
private static final String GRAPH = "hugegraph";
private static final String USERNAME = "admin";
private static final String PASSWORD = "pa";
Expand All @@ -71,7 +71,7 @@ public class BaseApiTest {

protected static final String TRAVERSERS_API = URL_PREFIX + "/traversers";

private static RestClient client;
protected static RestClient client;

private static final ObjectMapper MAPPER = new ObjectMapper();

Expand All @@ -84,6 +84,7 @@ public static void init() {
@AfterClass
public static void clear() throws Exception {
client.close();
client = null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No special meaning, just set the client member variable to null to indicate that the closed client should not be used anymore.

}

@After
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.hugegraph.api.graphspaces;

import org.junit.runner.RunWith;
import org.junit.runners.Suite;

@RunWith(Suite.class)
@Suite.SuiteClasses({
GraphSpacePropertyKeyApiTest.class,
GraphSpaceVertexLabelApiTest.class,
GraphSpaceEdgeLabelApiTest.class,
GraphSpaceIndexLabelApiTest.class,
GraphSpaceEdgeApiTest.class,
GraphSpaceVertexApiTest.class
})
public class GraphSpaceApiTestSuite {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.hugegraph.api.graphspaces;

import java.util.Objects;

import org.apache.hugegraph.api.BaseApiTest;
import org.apache.hugegraph.api.EdgeApiTest;
import org.junit.BeforeClass;

public class GraphSpaceEdgeApiTest extends EdgeApiTest {

@BeforeClass
public static void init() {
if (Objects.nonNull(client)) {
client.close();
}
client = new RestClient(String.join("/", BASE_URL, "graphspaces", "DEFAULT"));
BaseApiTest.clearData();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.hugegraph.api.graphspaces;

import java.util.Objects;

import org.apache.hugegraph.api.BaseApiTest;
import org.apache.hugegraph.api.EdgeLabelApiTest;
import org.junit.BeforeClass;

public class GraphSpaceEdgeLabelApiTest extends EdgeLabelApiTest {

@BeforeClass
public static void init() {
if (Objects.nonNull(client)) {
client.close();
}
client = new RestClient(String.join("/", BASE_URL, "graphspaces", "DEFAULT"));
BaseApiTest.clearData();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.hugegraph.api.graphspaces;

import java.util.Objects;

import org.apache.hugegraph.api.BaseApiTest;
import org.apache.hugegraph.api.IndexLabelApiTest;
import org.junit.BeforeClass;

public class GraphSpaceIndexLabelApiTest extends IndexLabelApiTest {

@BeforeClass
public static void init() {
if (Objects.nonNull(client)) {
client.close();
}
client = new RestClient(String.join("/", BASE_URL, "graphspaces", "DEFAULT"));
BaseApiTest.clearData();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.hugegraph.api.graphspaces;

import java.util.Objects;

import org.apache.hugegraph.api.BaseApiTest;
import org.apache.hugegraph.api.PropertyKeyApiTest;
import org.junit.BeforeClass;

public class GraphSpacePropertyKeyApiTest extends PropertyKeyApiTest {

@BeforeClass
public static void init() {
if (Objects.nonNull(client)) {
client.close();
}
client = new RestClient(String.join("/", BASE_URL, "graphspaces", "DEFAULT"));
BaseApiTest.clearData();
}
}
Loading
Loading