diff --git a/community/kernel/src/main/java/org/neo4j/graphdb/factory/GraphDatabaseSettings.java b/community/kernel/src/main/java/org/neo4j/graphdb/factory/GraphDatabaseSettings.java index 7097348d7cbae..d39b13e51bb79 100644 --- a/community/kernel/src/main/java/org/neo4j/graphdb/factory/GraphDatabaseSettings.java +++ b/community/kernel/src/main/java/org/neo4j/graphdb/factory/GraphDatabaseSettings.java @@ -567,6 +567,11 @@ public enum LabelIndex public static final Setting procedure_unrestricted = setting( "dbms.security.procedures.unrestricted", Settings.STRING, "" ); + @Description("If dbms.killQueries give a verbose output, with information about whitch querys where not found." ) + public static final Setting kill_query_verbose = + setting( "dbms.procedures.kill_query_verbose", BOOLEAN, FALSE ); + + @Description( "Whether or not to release the exclusive schema lock is while building uniqueness constraints index" ) @Internal public static final Setting release_schema_lock_while_building_constraint = setting( diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/EnterpriseBuiltInDbmsProcedures.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/EnterpriseBuiltInDbmsProcedures.java index b2fad7c82d0ab..6c3142889e8a3 100644 --- a/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/EnterpriseBuiltInDbmsProcedures.java +++ b/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/EnterpriseBuiltInDbmsProcedures.java @@ -31,6 +31,7 @@ import org.neo4j.function.UncaughtCheckedException; import org.neo4j.graphdb.DependencyResolver; +import org.neo4j.graphdb.factory.GraphDatabaseSettings; import org.neo4j.graphdb.security.AuthorizationViolationException; import org.neo4j.helpers.collection.Pair; import org.neo4j.kernel.api.KernelTransaction; @@ -44,6 +45,7 @@ import org.neo4j.kernel.api.proc.UserFunctionSignature; import org.neo4j.kernel.api.query.ExecutingQuery; import org.neo4j.kernel.api.security.SecurityContext; +import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.impl.api.KernelTransactions; import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge; import org.neo4j.kernel.impl.proc.Procedures; @@ -322,7 +324,8 @@ public Stream killQuery( @Name( "id" ) String idText ) Set> querys = getActiveTransactions( tx -> executingQueriesWithId( queryId, tx ) ).collect( toSet() ); - if ( querys.isEmpty() ) + Config configs = resolver.resolveDependency( Config.class ); + if ( configs.get( GraphDatabaseSettings.kill_query_verbose ) && querys.isEmpty() ) { return Stream.builder() .add( new QueryFailedTerminationResult( fromExternalString( idText ) ) ).build(); @@ -350,8 +353,9 @@ public Stream killQueries( @Name( "ids" ) List i Set terminatedQuerys = getActiveTransactions( tx -> executingQueriesWithIds( queryIds, tx ) ).map( catchThrown( InvalidArgumentsException.class, this::killQueryTransaction ) ).collect( toSet() ); + Config configs = resolver.resolveDependency( Config.class ); - if ( terminatedQuerys.size() != idTexts.size() ) + if ( configs.get( GraphDatabaseSettings.kill_query_verbose ) && terminatedQuerys.size() != idTexts.size() ) { for ( String id : idTexts ) { diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/BuiltInProceduresInteractionTestBase.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/BuiltInProceduresInteractionTestBase.java index 68e6f116f5d53..60cf4c15e04f4 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/BuiltInProceduresInteractionTestBase.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/BuiltInProceduresInteractionTestBase.java @@ -418,43 +418,6 @@ public void queryWaitingForLocksShouldBeKilledBeforeLocksAreReleased() throws Th tx1.closeAndAssertSuccess(); } - @Test - public void shouldGiveNiceMessageAtFailWhenTryingToKill() throws Throwable - { - String query = "CALL dbms.killQuery('query-9999999999')"; - Map expected = new HashMap<>(); - expected.put( "queryId", "query-9999999999" ); - expected.put( "username", "n/a" ); - expected.put( "message", "No Query found with this id" ); - assertSuccess( adminSubject, query, r -> assertThat(r.next(), equalTo( expected ))); - } - - @Test - public void shouldGiveNiceMessageAtFailWhenTryingToKillMoreThenOne() throws Throwable - { - //Given - String query = "CALL dbms.killQueries(['query-9999999999', 'query-9999999989'])"; - - //Expect - Set> expected = new HashSet<>(); - Map firstResultExpected = new HashMap<>(); - firstResultExpected.put( "queryId", "query-9999999989" ); - firstResultExpected.put( "username", "n/a" ); - firstResultExpected.put( "message", "No Query found with this id" ); - Map secoundResultExpected = new HashMap<>(); - secoundResultExpected.put( "queryId", "query-9999999999" ); - secoundResultExpected.put( "username", "n/a" ); - secoundResultExpected.put( "message", "No Query found with this id" ); - expected.add( firstResultExpected ); - expected.add( secoundResultExpected ); - - //Then - assertSuccess( adminSubject, query, r -> { - Set> actual = r.stream().collect( toSet() ); - assertThat( actual, equalTo( expected ) ); - } ); - } - @Test public void shouldKillQueryAsAdmin() throws Throwable { diff --git a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ConfiguredProceduresTestBase.java b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ConfiguredProceduresTestBase.java index b6be179827dfd..dd5bf94672e74 100644 --- a/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ConfiguredProceduresTestBase.java +++ b/enterprise/security/src/test/java/org/neo4j/server/security/enterprise/auth/ConfiguredProceduresTestBase.java @@ -19,9 +19,11 @@ */ package org.neo4j.server.security.enterprise.auth; +import org.junit.Assert; import org.junit.Test; import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -37,9 +39,12 @@ import org.neo4j.server.security.enterprise.configuration.SecuritySettings; import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toSet; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertFalse; import static org.mockito.internal.util.collections.Sets.newSet; import static org.neo4j.helpers.collection.MapUtil.genericMap; @@ -306,6 +311,54 @@ public void shouldShowAllowedRolesWhenListingFunctions() throws Throwable assertListProceduresHasRoles( readSubject, expected, call ); } + @Test + public void shouldGiveNiceMessageAtFailWhenTryingToKill() throws Throwable + { + configuredSetup( stringMap( GraphDatabaseSettings.kill_query_verbose.name() , "true" ) ); + + String query = "CALL dbms.killQuery('query-9999999999')"; + Map expected = new HashMap<>(); + expected.put( "queryId", "query-9999999999" ); + expected.put( "username", "n/a" ); + expected.put( "message", "No Query found with this id" ); + assertSuccess( adminSubject, query, r -> Assert.assertThat(r.next(), equalTo( expected ))); + } + + @Test + public void shouldNotGiveNiceMessageAtFailWhenTryingToKillWhenConfigured() throws Throwable + { + super.setUp(); + String query = "CALL dbms.killQuery('query-9999999999')"; + assertSuccess( adminSubject, query, r -> Assert.assertThat(r.hasNext(), is(false))); + } + + @Test + public void shouldGiveNiceMessageAtFailWhenTryingToKillMoreThenOne() throws Throwable + { + //Given + configuredSetup( stringMap( GraphDatabaseSettings.kill_query_verbose.name() , "true" ) ); + String query = "CALL dbms.killQueries(['query-9999999999', 'query-9999999989'])"; + + //Expect + Set> expected = new HashSet<>(); + Map firstResultExpected = new HashMap<>(); + firstResultExpected.put( "queryId", "query-9999999989" ); + firstResultExpected.put( "username", "n/a" ); + firstResultExpected.put( "message", "No Query found with this id" ); + Map secoundResultExpected = new HashMap<>(); + secoundResultExpected.put( "queryId", "query-9999999999" ); + secoundResultExpected.put( "username", "n/a" ); + secoundResultExpected.put( "message", "No Query found with this id" ); + expected.add( firstResultExpected ); + expected.add( secoundResultExpected ); + + //Then + assertSuccess( adminSubject, query, r -> { + Set> actual = r.stream().collect( toSet() ); + Assert.assertThat( actual, equalTo( expected ) ); + } ); + } + private void assertListProceduresHasRoles( S subject, Map> expected, String call ) { assertSuccess( subject, call, itr ->