diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/proc/ReflectiveProcedureCompiler.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/proc/ReflectiveProcedureCompiler.java index ede42e92d3e9a..34c48b42cd550 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/proc/ReflectiveProcedureCompiler.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/proc/ReflectiveProcedureCompiler.java @@ -62,6 +62,7 @@ import static java.util.Collections.emptyIterator; import static java.util.Collections.emptyList; +import static org.neo4j.graphdb.factory.GraphDatabaseSettings.procedure_unrestricted; import static org.neo4j.helpers.collection.Iterators.asRawIterator; /** @@ -266,9 +267,7 @@ private CallableProcedure compileProcedure( Class procDefinition, MethodHandl } catch ( ComponentInjectionException e ) { - description = Optional.of( procName.toString() + - " is not available due to having restricted access rights, check configuration." ); - log.warn( description.get() ); + description = describeAndLogLoadFailure( procName ); ProcedureSignature signature = new ProcedureSignature( procName, inputSignature, outputMapper.signature(), Mode.DEFAULT, Optional.empty(), new String[0], description, warning ); @@ -282,6 +281,17 @@ private CallableProcedure compileProcedure( Class procDefinition, MethodHandl return new ReflectiveProcedure( signature, constructor, procedureMethod, outputMapper, setters ); } + private Optional describeAndLogLoadFailure( QualifiedName name ) + { + String nameStr = name.toString(); + Optional description = Optional.of( + nameStr + " is unavailable because it is sandboxed and has dependencies outside of the sandbox. " + + "Sandboxing is controlled by the " + procedure_unrestricted.name() + " setting. " + + "Only unrestrict procedures you can trust with access to database internals." ); + log.warn( description.get() ); + return description; + } + private CallableUserFunction compileFunction( Class procDefinition, MethodHandle constructor, Method method, QualifiedName procName ) throws ProcedureException, IllegalAccessException @@ -312,9 +322,7 @@ private CallableUserFunction compileFunction( Class procDefinition, MethodHan } catch ( ComponentInjectionException e ) { - description = Optional.of( procName.toString() + - " is not available due to having restricted access rights, check configuration." ); - log.warn( description.get() ); + description = describeAndLogLoadFailure( procName ); UserFunctionSignature signature = new UserFunctionSignature( procName, inputSignature, valueConverter.type(), deprecated, config.rolesFor( procName.toString() ), description ); @@ -427,9 +435,7 @@ private CallableUserAggregationFunction compileAggregationFunction( Class def } catch ( ComponentInjectionException e ) { - description = Optional.of( funcName.toString() + - " is not available due to having restricted access rights, check configuration." ); - log.warn( description.get() ); + description = describeAndLogLoadFailure( funcName ); UserFunctionSignature signature = new UserFunctionSignature( funcName, inputSignature, valueConverter.type(), deprecated, config.rolesFor( funcName.toString() ), description ); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/proc/ProcedureJarLoaderTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/proc/ProcedureJarLoaderTest.java index 25b0edc13f3a1..04fc9b6facccd 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/proc/ProcedureJarLoaderTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/proc/ProcedureJarLoaderTest.java @@ -51,14 +51,15 @@ import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; -import static org.neo4j.graphdb.factory.GraphDatabaseSettings.procedure_unrestricted; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.neo4j.graphdb.factory.GraphDatabaseSettings.procedure_unrestricted; import static org.neo4j.helpers.collection.Iterators.asList; import static org.neo4j.helpers.collection.MapUtil.genericMap; import static org.neo4j.kernel.api.proc.Neo4jTypes.NTInteger; import static org.neo4j.kernel.api.proc.ProcedureSignature.procedureSignature; import static org.neo4j.kernel.api.proc.UserFunctionSignature.functionSignature; +import static org.neo4j.kernel.impl.proc.ResourceInjectionTest.notAvailableMessage; @SuppressWarnings( "WeakerAccess" ) public class ProcedureJarLoaderTest @@ -223,12 +224,8 @@ public void shouldGiveHelpfulLogOnUnsafeRestrictedProcedure() throws Throwable jarloader.loadProcedures( jar ); // Then - verify( log ) - .warn( "org.neo4j.kernel.impl.proc.unsafeProcedure is not available " + - "due to having restricted access rights, check configuration." ); - verify( log ) - .warn( "org.neo4j.kernel.impl.proc.unsafeFunction" + - " is not available due to having restricted access rights, check configuration." ); + verify( log ).warn( notAvailableMessage( "org.neo4j.kernel.impl.proc.unsafeProcedure" ) ); + verify( log ).warn( notAvailableMessage( "org.neo4j.kernel.impl.proc.unsafeFunction" ) ); } @Test diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/proc/ResourceInjectionTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/proc/ResourceInjectionTest.java index f13a5a1bf1f98..1b64687525fff 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/proc/ResourceInjectionTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/proc/ResourceInjectionTest.java @@ -19,6 +19,7 @@ */ package org.neo4j.kernel.impl.proc; +import org.hamcrest.Matcher; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -46,8 +47,10 @@ import static java.util.Collections.singletonList; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.Matchers.allOf; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; +import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -61,6 +64,16 @@ public class ResourceInjectionTest private Log log = mock(Log.class); + public static String notAvailableMessage( String procName ) + { + return argThat( notAvailableMessageMatcher( procName ) ); + } + + private static Matcher notAvailableMessageMatcher( String procName ) + { + return allOf( containsString( procName ), containsString( "unavailable" ) ); + } + @Before public void setUp() { @@ -125,9 +138,7 @@ public void shouldFailNicelyWhenUnsafeAPISafeMode() throws Throwable //When List procList = compiler.compileProcedure( ProcedureWithUnsafeAPI.class, Optional.empty(), false ); - verify( log ) - .warn( "org.neo4j.kernel.impl.proc.listCoolPeople is not " + - "available due to having restricted access rights, check configuration." ); + verify( log ).warn( notAvailableMessage( "org.neo4j.kernel.impl.proc.listCoolPeople" ) ); assertThat( procList.size(), equalTo( 1 ) ); try @@ -137,9 +148,7 @@ public void shouldFailNicelyWhenUnsafeAPISafeMode() throws Throwable } catch ( ProcedureException e ) { - assertThat( e.getMessage(), containsString( - "org.neo4j.kernel.impl.proc.listCoolPeople is not " + - "available due to having restricted access rights, check configuration." ) ); + assertThat( e.getMessage(), notAvailableMessageMatcher( "org.neo4j.kernel.impl.proc.listCoolPeople" ) ); } } @@ -176,9 +185,7 @@ public void shouldFailNicelyWhenUnsafeAPISafeModeFunction() throws Throwable //When List procList = compiler.compileFunction( FunctionWithUnsafeAPI.class); - verify( log ) - .warn( "org.neo4j.kernel.impl.proc.listCoolPeople is not " + - "available due to having restricted access rights, check configuration." ); + verify( log ).warn( notAvailableMessage( "org.neo4j.kernel.impl.proc.listCoolPeople" ) ); assertThat( procList.size(), equalTo( 1 ) ); try @@ -188,9 +195,7 @@ public void shouldFailNicelyWhenUnsafeAPISafeModeFunction() throws Throwable } catch ( ProcedureException e ) { - assertThat( e.getMessage(), containsString( - "org.neo4j.kernel.impl.proc.listCoolPeople is not " + - "available due to having restricted access rights, check configuration." ) ); + assertThat( e.getMessage(), notAvailableMessageMatcher( "org.neo4j.kernel.impl.proc.listCoolPeople" ) ); } } @@ -227,9 +232,7 @@ public void shouldFailNicelyWhenUnsafeAPISafeModeAggregationFunction() throws Th //When List procList = compiler.compileAggregationFunction( AggregationFunctionWithUnsafeAPI.class); - verify( log ) - .warn( "org.neo4j.kernel.impl.proc.listCoolPeople is not " + - "available due to having restricted access rights, check configuration." ); + verify( log ).warn( notAvailableMessage( "org.neo4j.kernel.impl.proc.listCoolPeople" ) ); assertThat( procList.size(), equalTo( 1 ) ); try @@ -240,9 +243,7 @@ public void shouldFailNicelyWhenUnsafeAPISafeModeAggregationFunction() throws Th } catch ( ProcedureException e ) { - assertThat( e.getMessage(), containsString( - "org.neo4j.kernel.impl.proc.listCoolPeople is not " + - "available due to having restricted access rights, check configuration." ) ); + assertThat( e.getMessage(), notAvailableMessageMatcher( "org.neo4j.kernel.impl.proc.listCoolPeople" ) ); } } @@ -255,15 +256,10 @@ public void shouldFailNicelyWhenAllUsesUnsafeAPI() throws Throwable compiler.compileAggregationFunction( FunctionsAndProcedureUnsafe.class ); // Then - verify( log ) - .warn( "org.neo4j.kernel.impl.proc.safeUserFunctionInUnsafeAPIClass is not " + - "available due to having restricted access rights, check configuration." ); - verify( log ) - .warn( "org.neo4j.kernel.impl.proc.listCoolPeopleProcedure is not " + - "available due to having restricted access rights, check configuration." ); - verify( log ) - .warn( "org.neo4j.kernel.impl.proc.listCoolPeople is not " + - "available due to having restricted access rights, check configuration." ); + verify( log ).warn( notAvailableMessage( "org.neo4j.kernel.impl.proc.safeUserFunctionInUnsafeAPIClass" ) ); + verify( log ).warn( notAvailableMessage( "org.neo4j.kernel.impl.proc.listCoolPeopleProcedure" ) ); + // With extra ' ' space at the end to distinguish from procedure form: + verify( log ).warn( notAvailableMessage( "org.neo4j.kernel.impl.proc.listCoolPeople " ) ); } public static class MyOutputRecord