From 1988ea6de8369baea6e42f62acde867940b1cb74 Mon Sep 17 00:00:00 2001 From: Zhangmei Li Date: Thu, 25 Oct 2018 21:10:32 +0800 Subject: [PATCH] Support for custom Authenticator implement: #132 Change-Id: Ib31a99ebc6d9c2ec3169d066ff179860b9cc6e25 --- .../api/filter/AuthenticationFilter.java | 66 +++------- .../hugegraph/api/filter/ExceptionFilter.java | 21 +-- .../hugegraph/auth/HugeAuthenticator.java | 122 ++++++++++++++++++ .../hugegraph/auth/HugeGraphAuthProxy.java | 48 ++++--- .../hugegraph/auth/StandardAuthenticator.java | 95 ++++++-------- .../baidu/hugegraph/config/ServerOptions.java | 11 +- .../baidu/hugegraph/core/GraphManager.java | 24 +++- .../com/baidu/hugegraph/GremlinGraph.java | 41 ++++++ .../java/com/baidu/hugegraph/HugeGraph.java | 9 +- 9 files changed, 288 insertions(+), 149 deletions(-) create mode 100644 hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeAuthenticator.java create mode 100644 hugegraph-core/src/main/java/com/baidu/hugegraph/GremlinGraph.java diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/filter/AuthenticationFilter.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/filter/AuthenticationFilter.java index acf7a64682..345f0fcfb6 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/filter/AuthenticationFilter.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/filter/AuthenticationFilter.java @@ -37,11 +37,14 @@ import javax.ws.rs.ext.Provider; import javax.xml.bind.DatatypeConverter; +import org.apache.tinkerpop.gremlin.server.auth.AuthenticationException; import org.glassfish.grizzly.utils.Charsets; +import com.baidu.hugegraph.auth.HugeAuthenticator.User; import com.baidu.hugegraph.auth.StandardAuthenticator; import com.baidu.hugegraph.core.GraphManager; import com.baidu.hugegraph.util.E; +import com.google.common.collect.ImmutableMap; @Provider @PreMatching @@ -64,16 +67,15 @@ protected User authenticate(ContainerRequestContext context) { if (!manager.requireAuthentication()) { // Return anonymous user with admin role if disable authentication - final String username = StandardAuthenticator.USER_ANONYMOUS; - final String role = StandardAuthenticator.ROLE_ADMIN; - return new User(username, role); + return User.ANONYMOUS; } // Extract authentication credentials String auth = context.getHeaderString(HttpHeaders.AUTHORIZATION); if (auth == null) { throw new NotAuthorizedException( - "Authentication credentials are required"); + "Authentication credentials are required", + "Missing authentication credentials"); } if (!auth.startsWith("Basic ")) { throw new BadRequestException( @@ -94,12 +96,15 @@ protected User authenticate(ContainerRequestContext context) { assert username != null && password != null; // Validate the extracted credentials - final String role = manager.authenticate(username, password); - if (!StandardAuthenticator.verifyRole(role)) { - throw new NotAuthorizedException("Invalid username or password"); + try { + return manager.authenticate(ImmutableMap.of( + StandardAuthenticator.KEY_USERNAME, username, + StandardAuthenticator.KEY_PASSWORD, password)); + } catch (AuthenticationException e) { + String msg = String.format("Authentication failed for user '%s'", + username); + throw new NotAuthorizedException(msg, e.getMessage()); } - - return new User(username, role); } public static class Authorizer implements SecurityContext { @@ -117,11 +122,11 @@ public Authorizer(final User user, final UriInfo uri) { } public String username() { - return this.user.username; + return this.user.username(); } - public String userrole() { - return this.user.role; + public String role() { + return this.user.role(); } @Override @@ -140,7 +145,7 @@ public boolean isUserInRole(String role) { E.checkState(owner.length == 2, "Bad role format: '%s'", role); role = this.getPathParameter(owner[1]); } - return role.equals(this.user.role); + return role.equals(this.user.role()); } @Override @@ -164,7 +169,7 @@ private final class UserPrincipal implements Principal { @Override public String getName() { - return Authorizer.this.user.role; + return Authorizer.this.user.role(); } @Override @@ -183,37 +188,4 @@ public boolean equals(Object obj) { } } } - - protected static class User { - - private String username; - private String role; - - public User(String username, String role) { - this.username = username; - this.role = role; - } - - @Override - public int hashCode() { - return this.username.hashCode() ^ this.role.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj == null || !(obj instanceof User)) { - return false; - } - - User other = (User) obj; - return this.username.equals(other.username) && - this.role.equals(other.role); - } - - @Override - public String toString() { - return String.format("User{username=%s,role=%s}", - this.username, this.role); - } - } } diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/filter/ExceptionFilter.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/filter/ExceptionFilter.java index 72d8061902..87eaff37e7 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/filter/ExceptionFilter.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/filter/ExceptionFilter.java @@ -27,6 +27,7 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.Provider; @@ -114,17 +115,18 @@ public static class WebApplicationExceptionMapper @Override public Response toResponse(WebApplicationException exception) { - Response response = exception.getResponse(); if (response.hasEntity()) { return response; } - + MultivaluedMap headers = response.getHeaders(); boolean trace = this.trace(response.getStatus()); - return Response.status(response.getStatus()) - .type(MediaType.APPLICATION_JSON) - .entity(formatException(exception, trace)) - .build(); + response = Response.status(response.getStatus()) + .type(MediaType.APPLICATION_JSON) + .entity(formatException(exception, trace)) + .build(); + response.getHeaders().putAll(headers); + return response; } private boolean trace(int status) { @@ -150,15 +152,16 @@ public static String formatException(Exception exception) { } public static String formatException(Exception exception, boolean trace) { + String clazz = exception.getClass().toString(); String msg = exception.getMessage() != null ? exception.getMessage() : ""; String cause = exception.getCause() != null ? exception.getCause().toString() : ""; JsonObjectBuilder json = Json.createObjectBuilder() - .add("exception", exception.getClass().toString()) - .add("message", msg) - .add("cause", cause); + .add("exception", clazz) + .add("message", msg) + .add("cause", cause); if (trace) { JsonArrayBuilder traces = Json.createArrayBuilder(); diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeAuthenticator.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeAuthenticator.java new file mode 100644 index 0000000000..cf311c5eab --- /dev/null +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeAuthenticator.java @@ -0,0 +1,122 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * 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 com.baidu.hugegraph.auth; + +import java.util.Map; + +import org.apache.tinkerpop.gremlin.server.auth.AuthenticatedUser; +import org.apache.tinkerpop.gremlin.server.auth.AuthenticationException; +import org.apache.tinkerpop.gremlin.server.auth.Authenticator; + +import com.baidu.hugegraph.HugeException; +import com.baidu.hugegraph.config.HugeConfig; +import com.baidu.hugegraph.config.ServerOptions; + +public interface HugeAuthenticator extends Authenticator { + + public static final String ROLE_NONE = ""; + public static final String ROLE_ADMIN = "admin"; + public static final String ROLE_USER = "user"; + public static final String ROLE_OWNER = "$owner"; + public static final String ROLE_DYNAMIC = "$dynamic"; + + public void setup(HugeConfig config); + + @Override + public User authenticate(final Map credentials) + throws AuthenticationException; + + @Override + public default boolean requireAuthentication() { + return true; + } + + public static class User extends AuthenticatedUser { + + protected static final String USER_ADMIN = ROLE_ADMIN; + protected static final String USER_ANONY = ANONYMOUS_USERNAME; + + public static final User ADMIN = new User(USER_ADMIN, ROLE_ADMIN); + public static final User ANONYMOUS = new User(USER_ANONY, ROLE_ADMIN); + + private final String role; + + public User(String username, String role) { + super(username); + this.role = role; + } + + public String username() { + return this.getName(); + } + + public String role() { + return this.role; + } + + @Override + public boolean isAnonymous() { + return this == ANONYMOUS || this == ANONYMOUS_USER; + } + + @Override + public int hashCode() { + return this.username().hashCode() ^ this.role().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof User)) { + return false; + } + + User other = (User) obj; + return this.username().equals(other.username()) && + this.role().equals(other.role()); + } + + @Override + public String toString() { + return String.format("User{username=%s,role=%s}", + this.username(), this.role()); + } + } + + public static HugeAuthenticator loadAuthenticator(HugeConfig conf) { + String authenticatorClass = conf.get(ServerOptions.AUTHENTICATOR); + ClassLoader cl = conf.getClass().getClassLoader(); + + HugeAuthenticator authenticator; + try { + authenticator = (HugeAuthenticator) cl.loadClass(authenticatorClass) + .newInstance(); + } catch (Exception e) { + throw new HugeException("Failed to load authenticator: '%s'", + authenticatorClass, e); + } + + authenticator.setup(conf); + + return authenticator; + } +} diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeGraphAuthProxy.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeGraphAuthProxy.java index 9000ed1eb6..7236534fd4 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeGraphAuthProxy.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/HugeGraphAuthProxy.java @@ -36,17 +36,17 @@ import org.apache.tinkerpop.gremlin.structure.io.Io; import org.slf4j.Logger; +import com.baidu.hugegraph.GremlinGraph; import com.baidu.hugegraph.HugeException; import com.baidu.hugegraph.HugeGraph; import com.baidu.hugegraph.config.HugeConfig; import com.baidu.hugegraph.exception.NotSupportException; import com.baidu.hugegraph.schema.SchemaManager; import com.baidu.hugegraph.structure.HugeFeatures; -import com.baidu.hugegraph.task.HugeTaskScheduler; import com.baidu.hugegraph.util.E; import com.baidu.hugegraph.util.Log; -public class HugeGraphAuthProxy implements Graph { +public class HugeGraphAuthProxy implements GremlinGraph { private static final Logger LOG = Log.logger(HugeGraph.class); @@ -111,7 +111,7 @@ public Transaction tx() { @Override public void close() throws HugeException { - this.verifyPermission("admin"); + this.verifyPermission(ROLE_ADMIN); this.hugegraph.close(); } @@ -148,41 +148,48 @@ public HugeGraph hugegraph() { return this.hugegraph; } + @Override + public String name() { + this.verifyPermission(); + return this.hugegraph.name(); + } + + @Override public SchemaManager schema() { this.verifyPermission(); return this.hugegraph.schema(); } + @Override public String backend() { this.verifyPermission(); return this.hugegraph.backend(); } + @Override public void initBackend() { this.verifyPermission(ROLE_ADMIN); this.hugegraph.initBackend(); } + @Override public void clearBackend() { this.verifyPermission(ROLE_ADMIN); this.hugegraph.clearBackend(); } + @Override public void restoring(boolean restoring) { this.verifyPermission(ROLE_ADMIN); this.hugegraph.restoring(restoring); } + @Override public boolean restoring() { this.verifyPermission(ROLE_ADMIN); return this.hugegraph.restoring(); } - public HugeTaskScheduler taskScheduler() { - this.verifyPermission(); - return this.hugegraph.taskScheduler(); - } - private void verifyPermission() { /* * The owner role should match the graph name @@ -197,7 +204,7 @@ private void verifyPermission(String permission) { E.checkState(context != null, "Missing authentication context " + "when accessing a Graph with permission control"); - String role = context.role(); + String role = context.user().role(); if (!role.equals(ROLE_ADMIN) && !role.equals(permission)) { throw new ForbiddenException("Permission denied"); } @@ -232,26 +239,17 @@ public static void resetContext() { public static class Context { - private final String username; - private final String role; + private static final Context ADMIN = + new Context(HugeAuthenticator.User.ADMIN); - public Context(String username, String role) { - this.username = username; - this.role = role; - } - - public String username() { - return this.username; - } + private final HugeAuthenticator.User user; - public String role() { - return this.role; + public Context(HugeAuthenticator.User user) { + this.user = user; } - private static final Context ADMIN; - - static { - ADMIN = new Context("admin", ROLE_ADMIN); + public HugeAuthenticator.User user() { + return this.user; } public static Context admin() { diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/StandardAuthenticator.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/StandardAuthenticator.java index 6ff59a31c8..6661bc5809 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/StandardAuthenticator.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/auth/StandardAuthenticator.java @@ -19,15 +19,12 @@ package com.baidu.hugegraph.auth; -import static org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialGraphTokens.PROPERTY_PASSWORD; -import static org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialGraphTokens.PROPERTY_USERNAME; - import java.util.HashMap; import java.util.Map; -import org.apache.tinkerpop.gremlin.server.auth.AuthenticatedUser; +import org.apache.commons.lang.NotImplementedException; +import org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialGraphTokens; import org.apache.tinkerpop.gremlin.server.auth.AuthenticationException; -import org.apache.tinkerpop.gremlin.server.auth.SimpleAuthenticator; import com.baidu.hugegraph.auth.HugeGraphAuthProxy.Context; import com.baidu.hugegraph.config.HugeConfig; @@ -35,31 +32,25 @@ import com.baidu.hugegraph.config.ServerOptions; import com.baidu.hugegraph.util.E; -public class StandardAuthenticator extends SimpleAuthenticator { - - public static final String ROLE_NONE = ""; - public static final String ROLE_ADMIN = "admin"; - public static final String ROLE_USER = "user"; - public static final String ROLE_OWNER = "$owner"; - public static final String ROLE_DYNAMIC = "$dynamic"; +public class StandardAuthenticator implements HugeAuthenticator { - public static final String USER_ADMIN = ROLE_ADMIN; - public static final String USER_ANONYMOUS = - AuthenticatedUser.ANONYMOUS_USERNAME; + public static final String KEY_USERNAME = + CredentialGraphTokens.PROPERTY_USERNAME; + public static final String KEY_PASSWORD = + CredentialGraphTokens.PROPERTY_PASSWORD; - private boolean requireAuth; private final Map tokens; - public StandardAuthenticator(HugeConfig config) { - this(); - this.load(config); - } - public StandardAuthenticator() { - this.requireAuth = true; this.tokens = new HashMap<>(); } + @Override + public void setup(HugeConfig config) { + this.tokens.put(User.USER_ADMIN, config.get(ServerOptions.ADMIN_TOKEN)); + this.tokens.putAll(config.getMap(ServerOptions.USER_TOKENS)); + } + @Override public void setup(final Map config) { E.checkState(config != null, @@ -68,33 +59,33 @@ public void setup(final Map config) { E.checkState(path != null, "Credentials configuration missing key 'tokens'"); OptionSpace.register("tokens", ServerOptions.instance()); - this.load(new HugeConfig(path)); - } - - @Override - public boolean requireAuthentication() { - return this.requireAuth; + this.setup(new HugeConfig(path)); } - /** - * This authentication method is for Gremlin Server - */ @Override - public AuthenticatedUser authenticate(final Map credentials) - throws AuthenticationException { - if (!this.requireAuthentication()) { - return AuthenticatedUser.ANONYMOUS_USER; - } - String username = credentials.get(PROPERTY_USERNAME); - String password = credentials.get(PROPERTY_PASSWORD); - - // Currently we just use config tokens to authenticate - String role = this.authenticate(username, password); - if (!verifyRole(role)) { - throw new AuthenticationException("Invalid username or password"); + public User authenticate(final Map credentials) + throws AuthenticationException { + User user = User.ANONYMOUS; + if (this.requireAuthentication()) { + String username = credentials.get(KEY_USERNAME); + String password = credentials.get(KEY_PASSWORD); + + // Currently we just use config tokens to authenticate + String role = this.authenticate(username, password); + if (!verifyRole(role)) { + // Throw if not certified + String message = "Incorrect username or password"; + throw new AuthenticationException(message); + } + user = new User(username, role); } + /* + * Set authentication context + * TODO: unset context after finishing a request + */ + HugeGraphAuthProxy.setContext(new Context(user)); - return new AuthenticatedUser(username); + return user; } /** @@ -103,7 +94,7 @@ public AuthenticatedUser authenticate(final Map credentials) * @param password * @return String No permission if return ROLE_NONE else return a role */ - public String authenticate(final String username, final String password) { + protected String authenticate(String username, String password) { E.checkArgumentNotNull(username, "The username can't be null"); E.checkArgumentNotNull(password, "The password can't be null"); @@ -115,20 +106,12 @@ public String authenticate(final String username, final String password) { role = ROLE_NONE; } - /* - * Set authentication context - * TODO: unset context after finishing a request, - * now must set context to update last context even if not authorized. - */ - HugeGraphAuthProxy.setContext(new Context(username, role)); - return role; } - private void load(HugeConfig config) { - this.requireAuth = config.get(ServerOptions.REQUIRE_AUTH); - this.tokens.put(USER_ADMIN, config.get(ServerOptions.ADMIN_TOKEN)); - this.tokens.putAll(config.getMap(ServerOptions.USER_TOKENS)); + @Override + public SaslNegotiator newSaslNegotiator() { + throw new NotImplementedException("SaslNegotiator is unsupported"); } public static final boolean verifyRole(String role) { diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/config/ServerOptions.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/config/ServerOptions.java index 94a845cb57..91d3053d1f 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/config/ServerOptions.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/config/ServerOptions.java @@ -106,12 +106,13 @@ public static synchronized ServerOptions instance() { false ); - public static final ConfigOption REQUIRE_AUTH = + public static final ConfigOption AUTHENTICATOR = new ConfigOption<>( - "auth.require_authentication", - "Whether to enable authentication.", - disallowEmpty(), - false + "auth.authenticator", + "The class path of authenticator implemention. " + + "e.g., com.baidu.hugegraph.auth.StandardAuthenticator", + null, + "" ); public static final ConfigOption ADMIN_TOKEN = diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/core/GraphManager.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/core/GraphManager.java index 2b39c45ff6..3ba914cabc 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/core/GraphManager.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/core/GraphManager.java @@ -27,6 +27,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import org.apache.tinkerpop.gremlin.server.auth.AuthenticationException; import org.apache.tinkerpop.gremlin.server.util.MetricManager; import org.apache.tinkerpop.gremlin.structure.Graph; import org.apache.tinkerpop.gremlin.structure.Transaction; @@ -35,9 +36,9 @@ import org.slf4j.Logger; import com.baidu.hugegraph.HugeGraph; +import com.baidu.hugegraph.auth.HugeAuthenticator; import com.baidu.hugegraph.auth.HugeFactoryAuthProxy; import com.baidu.hugegraph.auth.HugeGraphAuthProxy; -import com.baidu.hugegraph.auth.StandardAuthenticator; import com.baidu.hugegraph.backend.cache.Cache; import com.baidu.hugegraph.backend.cache.CacheManager; import com.baidu.hugegraph.backend.store.BackendStoreInfo; @@ -50,6 +51,7 @@ import com.baidu.hugegraph.serializer.JsonSerializer; import com.baidu.hugegraph.serializer.Serializer; import com.baidu.hugegraph.server.RestServer; +import com.baidu.hugegraph.util.E; import com.baidu.hugegraph.util.Log; import com.codahale.metrics.MetricRegistry; @@ -58,11 +60,16 @@ public final class GraphManager { private static final Logger LOG = Log.logger(RestServer.class); private final Map graphs; - private final StandardAuthenticator authenticator; + private final HugeAuthenticator authenticator; public GraphManager(HugeConfig conf) { this.graphs = new ConcurrentHashMap<>(); - this.authenticator = new StandardAuthenticator(conf); + + if (conf.get(ServerOptions.AUTHENTICATOR).isEmpty()) { + this.authenticator = null; + } else { + this.authenticator = HugeAuthenticator.loadAuthenticator(conf); + } this.loadGraphs(conf.getMap(ServerOptions.GRAPHS)); this.checkBackendVersionOrExit(); @@ -154,11 +161,16 @@ private void closeTx(final Set graphSourceNamesToCloseTxOn, } public boolean requireAuthentication() { + if (this.authenticator == null) { + return false; + } return this.authenticator.requireAuthentication(); } - public String authenticate(String username, String password) { - return this.authenticator.authenticate(username, password); + public HugeAuthenticator.User authenticate(Map credentials) + throws AuthenticationException { + E.checkState(this.authenticator != null, "Unconfigured authenticator"); + return this.authenticator.authenticate(credentials); } private void loadGraph(String name, String path) { @@ -166,7 +178,7 @@ private void loadGraph(String name, String path) { this.graphs.put(name, graph); LOG.info("Graph '{}' was successfully configured via '{}'", name, path); - if (this.authenticator.requireAuthentication() && + if (this.requireAuthentication() && !(graph instanceof HugeGraphAuthProxy)) { LOG.warn("You may need to support access control for '{}' with {}", path, HugeFactoryAuthProxy.GRAPH_FACTORY); diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/GremlinGraph.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/GremlinGraph.java new file mode 100644 index 0000000000..beca257d1f --- /dev/null +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/GremlinGraph.java @@ -0,0 +1,41 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * 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 com.baidu.hugegraph; + +import org.apache.tinkerpop.gremlin.structure.Graph; + +import com.baidu.hugegraph.schema.SchemaManager; + +/** + * Graph interface for Gremlin operations + */ +public interface GremlinGraph extends Graph { + + public String name(); + + public SchemaManager schema(); + + public String backend(); + public void initBackend(); + public void clearBackend(); + + public void restoring(boolean restoring); + public boolean restoring(); +} diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/HugeGraph.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/HugeGraph.java index cefe6ca613..de8a79691f 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/HugeGraph.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/HugeGraph.java @@ -76,7 +76,7 @@ * HugeGraph is the entrance of the graph system, you can modify or query * the schema/vertex/edge data through this class. */ -public class HugeGraph implements Graph { +public class HugeGraph implements GremlinGraph { private static final Logger LOG = Log.logger(HugeGraph.class); @@ -145,10 +145,12 @@ public HugeGraph(HugeConfig configuration) { this.variables = null; } + @Override public String name() { return this.name; } + @Override public String backend() { return this.storeProvider.type(); } @@ -161,10 +163,12 @@ public boolean closed() { return this.closed && this.tx.closed(); } + @Override public boolean restoring() { return this.restoring; } + @Override public void restoring(boolean restoring) { this.restoring = restoring; } @@ -181,6 +185,7 @@ public RateLimiter rateLimiter() { return this.rateLimiter; } + @Override public void initBackend() { this.loadSchemaStore().open(this.configuration); this.loadSystemStore().open(this.configuration); @@ -195,6 +200,7 @@ public void initBackend() { } } + @Override public void clearBackend() { this.loadSchemaStore().open(this.configuration); this.loadSystemStore().open(this.configuration); @@ -267,6 +273,7 @@ public GraphTransaction graphTransaction() { return this.tx.graphTransaction(); } + @Override public SchemaManager schema() { return new SchemaManager(this.schemaTransaction()); }