From 619f4849dabfe8a3976e95bdb3efd41b527ac22b Mon Sep 17 00:00:00 2001 From: Stefan Plantikow Date: Fri, 26 Aug 2016 15:21:06 +0200 Subject: [PATCH] Add first (ignored in the commit) acceptance test for listing queries --- .../enterprise/auth/AuthProcedures.java | 41 ++++++++++ .../auth/AuthProceduresTestLogic.java | 81 ++++++++++++++++++- .../auth/ThreadedTransactionCreate.java | 7 +- 3 files changed, 124 insertions(+), 5 deletions(-) diff --git a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/AuthProcedures.java b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/AuthProcedures.java index e4c5a9f8a7eef..26541cf2a409e 100644 --- a/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/AuthProcedures.java +++ b/enterprise/security/src/main/java/org/neo4j/server/security/enterprise/auth/AuthProcedures.java @@ -19,9 +19,12 @@ */ package org.neo4j.server.security.enterprise.auth; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; + import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -255,6 +258,20 @@ public Stream listTransactions() ); } + @Procedure( name = "dbms.listQueries", mode = DBMS ) + public Stream listQueries() + throws InvalidArgumentsException, IOException + { + throw new NotImplementedException(); + } + + @Procedure( name = "dbms.listQueriesForUser", mode = DBMS ) + public Stream listQueriesForUser( @Name( "username") String username ) + throws InvalidArgumentsException, IOException + { + throw new NotImplementedException(); + } + @Procedure( name = "dbms.security.terminateTransactionsForUser", mode = DBMS ) public Stream terminateTransactionsForUser( @Name( "username" ) String username ) throws InvalidArgumentsException, IOException @@ -423,6 +440,30 @@ public static class TransactionResult } } + public static class QueryStatusResult + { + public final long queryId; + + public final String username; + public final String query; + public final Map parameters; + public final long startTime; + + // TODO: Metadata + + + public QueryStatusResult( long queryId, + String username, String query, Map parameters, + long startTime ) + { + this.queryId = queryId; + this.username = username; + this.query = query; + this.parameters = parameters; + this.startTime = startTime; + } + } + public static class TransactionTerminationResult { public final String username; diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/AuthProceduresTestLogic.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/AuthProceduresTestLogic.java index 748dcdaff65ce..22ce79957534c 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/AuthProceduresTestLogic.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/AuthProceduresTestLogic.java @@ -19,9 +19,12 @@ */ package org.neo4j.server.security.enterprise.auth; +import org.hamcrest.Matcher; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; +import java.util.Collections; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.stream.Stream; @@ -37,6 +40,10 @@ import static java.lang.String.format; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.anyOf; +import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.isA; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; @@ -143,8 +150,8 @@ public void shouldListTransactions() throws Throwable ThreadedTransactionCreate write1 = new ThreadedTransactionCreate<>( neo, latch ); ThreadedTransactionCreate write2 = new ThreadedTransactionCreate<>( neo, latch ); - write1.execute( threading, writeSubject ); - write2.execute( threading, writeSubject ); + String q1 = write1.execute( threading, writeSubject ); + String q2 = write2.execute( threading, writeSubject ); latch.startAndWaitForAllToStart(); assertSuccess( adminSubject, "CALL dbms.security.listTransactions()", @@ -181,6 +188,49 @@ public void shouldListRestrictedTransaction() } } + @Ignore + @Test + public void shouldListQueries() throws Throwable + { + DoubleLatch latch = new DoubleLatch( 3 ); + ThreadedTransactionCreate write1 = new ThreadedTransactionCreate<>( neo, latch ); + ThreadedTransactionCreate write2 = new ThreadedTransactionCreate<>( neo, latch ); + + String q1 = write1.execute( threading, writeSubject ); + String q2 = write2.execute( threading, writeSubject ); + latch.startAndWaitForAllToStart(); + + assertSuccess( adminSubject, "CALL dbms.listQueries()", r -> + r.forEachRemaining( m -> + { + // TODO: Make sure each matches exactly once + Matcher> matcher1 = + allOf( hasQuery( q1 ), + hasUsername( "writeSubject" ), + hasQueryId(), + hasStartTimeAfter( 0L ), + hasNoParameters() ); + + Matcher> matcher2 = + allOf( hasQuery( q2 ), + hasUsername( "writeSubject" ), + hasQueryId(), + hasStartTimeAfter( 0L ), + hasNoParameters() ); + + assertThat( m, anyOf( matcher1, matcher2 ) ); + } + ) ); + + + write1.finish(); + write2.finish(); + latch.finishAndWaitForAllToFinish(); + + write1.closeAndAssertSuccess(); + write2.closeAndAssertSuccess(); + } + //---------- terminate transactions for user ----------- @Test @@ -1263,4 +1313,31 @@ private TransportConnection startBoltSession( String username, String password ) return connection; } + //---------- matchers----------- + + private Matcher> hasQuery( String query ) + { + return (Matcher>) (Matcher) hasEntry( "query", query ); + } + + private Matcher> hasUsername( String name ) + { + return (Matcher>) (Matcher) hasEntry( "userName", name ); + } + + private Matcher> hasQueryId() + { + return (Matcher>) (Matcher) hasEntry( "queryId", isA( Long.class ) ); + } + + private Matcher> hasStartTimeAfter( long base ) + { + // TODO + return (Matcher>) (Matcher) hasEntry( "startTime", isA( Long.class ) ); + } + + private Matcher> hasNoParameters() + { + return (Matcher>) (Matcher) hasEntry( "parameters", Collections.emptySet() ); + } } diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ThreadedTransactionCreate.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ThreadedTransactionCreate.java index 41e64528c38d1..8ad85b154c784 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ThreadedTransactionCreate.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ThreadedTransactionCreate.java @@ -45,8 +45,9 @@ public class ThreadedTransactionCreate this.latch = latch; } - void execute( ThreadingRule threading, S subject ) + String execute( ThreadingRule threading, S subject ) { + final String query = "CREATE (:Test { name: '" + neo.nameOf( subject ) + "-node'})"; NamedFunction startTransaction = new NamedFunction( "start-transaction" ) { @@ -57,8 +58,7 @@ public Throwable apply( S subject ) { try ( InternalTransaction tx = neo.startTransactionAsUser( subject ) ) { - neo.getGraph() - .execute( "CREATE (:Test { name: '" + neo.nameOf( subject ) + "-node'})" ); + neo.getGraph().execute( query ); latch.startAndWaitForAllToStart(); latch.waitForAllToFinish(); tx.success(); @@ -73,6 +73,7 @@ public Throwable apply( S subject ) }; done = threading.execute( startTransaction, subject ); + return query; } @SuppressWarnings( "ThrowableResultOfMethodCallIgnored" )