Search code examples
javagremlintinkerpop

Is there a false function in tinkerpop gremlin?


We have one photo sharing service in which one can allow or deny other set of users to view or not. We exposed this service as an API /view?caller=userId&photoId=photoId. We're using AWS Neptune Graph database service to maintain this authorization and using tinkerpop java library.

For the code maintainability, we fetch possible paths from other class methods and call canUserView method from the outside.

Public class Authorizer {
    List<Role> roles;
    
    public Authorizer(List<Role> roles) {
        this.roles = roles;
    }
    
    public boolean canUserView(User user, String photoId) {
        return graph.V(user.getId()).hasLabel("user").or(getPossibleTraversals(user)).hasId("photoId")
    }

    private GraphTraversal<Object, Vertex>[] getPossibleTraversals(User user) {
        List<GraphTraversal<Vertex, Vertex>> traversals = roles.getTraversal(user).map(traversal -> traversal).collect(Collectors.toList())
        return traversals.toArray(GraphTraversal[]::new);
    }
}

and in the role class getTraversal for the code performance, based on the user information I supply the required traversal or I can supply the failure traversal.

Now the question is how to supply the failure traversal here. For now we assume some unavailable vertex Id for failure traversal. The code is like the below.

public class Role {

    public GraphTraversal<Object, Vertex> getTraversal(User user) {
        if(user.satisfies(this)) {
            return __.V("assumedUnavailableVertexId").hasLabel("absolutelynotpossible"); //This ID and label assumed
        } else {
            return actualTraversal();   //This will construct the possible traversals
        }
    }
}

How to return the failure traversal for the if case in Role? Is there any way to remove this assumption ?


Solution

  • I have often seen something as simple as constant('Not allowed') used when a traversal needs to return an indication that there was an error/issue.

    In this case (if you need clean generic checking from the compiler etc) you would need to start with something like Traversal <Object,Object> as different paths through your code can potentially now return different types of Traversal.