0

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 boolean canUserView(User user, String photoId) {
    return graph.V(user.getId()).hasLabel("user").or(getPossibleTraversals(user)).hasNext();
}

private GraphTraversal<Object, Vertex>[] getPossibleTraversals(User user) {
    List<GraphTraversal<Vertex, Vertex>> traversals = collectTraversalsFromExternal();
    return traversals.toArray(GraphTraversal[]::new);
}

collectTraversalsFromExternal() queries our other datastore and based on result, we form the query. In every or traversal at the end we inject unique constant value to identify the traversal.

We were using .union() earlier to get the result and the constant value. But due to performance issues using .or() condition now.

This might be a dumb question. Is it possible to get reference which traversal was true ?

ashoksl
  • 383
  • 6
  • 17

1 Answers1

1

Using the air routes data set, here is one way you can achieve what you are looking for.

The or will filter out all airports not in either Texas or Georgia. After that the choose step returns a constant indicating which or path was taken. You can of course do something more interesting that return a constant value in your query.

gremlin> g.V(1,3,12).values('region')
==>US-GA
==>US-TX
==>US-NY

gremlin> g.V(1,3,12).
......1>   or(has('region','US-GA'),
......2>      has('region', 'US-TX')).
......3>   choose(has('region','US-GA'),constant(1),constant(2))      

==>1
==>2  
Kelvin Lawrence
  • 14,674
  • 2
  • 16
  • 38
  • Thank you. Makes sense. I'll try this out and update here – ashoksl May 15 '21 at 10:44
  • Thanks. Please do let me know. – Kelvin Lawrence May 17 '21 at 13:46
  • In my case, there is a possibility of at least 10 or traversals. So I need to chain them on the else case something like nested .choose step. ```.choose(has('region','US-GA'),constant(1), choose(has('region', 'US-TX'), constant(2), ... constant(10)))``` – ashoksl May 17 '21 at 14:46
  • You can use an `option` step with `choose` which makes it more like a `switch` and `case` statement in Java or C – Kelvin Lawrence May 17 '21 at 15:44
  • option step is kinda new to me. ```g.V().has("code", "JFK").choose(has("code")) .option(has("code", "JFK"), constant("John F Kennedy Airport")) .option(has("code", "AUS"), constant("Austin Texas")) ``` This is working as expected in TinkerGraph . I'll try something like this. Thank you. – ashoksl May 18 '21 at 07:29