Search in sources :

Example 11 with CallableUserFunction

use of org.neo4j.kernel.api.procedure.CallableUserFunction in project neo4j by neo4j.

the class ProcedureCompiler method compileFunction.

List<CallableUserFunction> compileFunction(Class<?> fcnDefinition, boolean isBuiltin) throws KernelException {
    try {
        List<Method> functionMethods = Arrays.stream(fcnDefinition.getDeclaredMethods()).filter(m -> m.isAnnotationPresent(UserFunction.class)).collect(Collectors.toList());
        if (functionMethods.isEmpty()) {
            return emptyList();
        }
        // used for proper error handling
        assertValidConstructor(fcnDefinition);
        List<CallableUserFunction> out = new ArrayList<>(functionMethods.size());
        for (Method method : functionMethods) {
            String valueName = method.getAnnotation(UserFunction.class).value();
            String definedName = method.getAnnotation(UserFunction.class).name();
            QualifiedName funcName = extractName(fcnDefinition, method, valueName, definedName);
            if (isBuiltin || config.isWhitelisted(funcName.toString())) {
                out.add(compileFunction(fcnDefinition, method, funcName));
            } else {
                log.warn(String.format("The function '%s' is not on the allowlist and won't be loaded.", funcName.toString()));
            }
        }
        out.sort(Comparator.comparing(a -> a.signature().name().toString()));
        return out;
    } catch (KernelException e) {
        throw e;
    } catch (Exception e) {
        throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, e, "Failed to compile function defined in `%s`: %s", fcnDefinition.getSimpleName(), e.getMessage());
    }
}
Also used : Mode(org.neo4j.procedure.Mode) Arrays(java.util.Arrays) Log(org.neo4j.logging.Log) UserAggregationResult(org.neo4j.procedure.UserAggregationResult) CallableUserAggregationFunction(org.neo4j.kernel.api.procedure.CallableUserAggregationFunction) Status(org.neo4j.kernel.api.exceptions.Status) UserAggregationUpdate(org.neo4j.procedure.UserAggregationUpdate) ProcedureException(org.neo4j.internal.kernel.api.exceptions.ProcedureException) Constructor(java.lang.reflect.Constructor) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) SystemProcedure(org.neo4j.kernel.api.procedure.SystemProcedure) UserFunctionSignature(org.neo4j.internal.kernel.api.procs.UserFunctionSignature) Procedure(org.neo4j.procedure.Procedure) Method(java.lang.reflect.Method) GraphDatabaseSettings.procedure_unrestricted(org.neo4j.configuration.GraphDatabaseSettings.procedure_unrestricted) ComponentInjectionException(org.neo4j.kernel.api.exceptions.ComponentInjectionException) Collections.emptyList(java.util.Collections.emptyList) CallableUserFunction(org.neo4j.kernel.api.procedure.CallableUserFunction) FailedLoadFunction(org.neo4j.kernel.api.procedure.FailedLoadFunction) Description(org.neo4j.procedure.Description) Collectors(java.util.stream.Collectors) FieldSignature(org.neo4j.internal.kernel.api.procs.FieldSignature) Internal(org.neo4j.procedure.Internal) QualifiedName(org.neo4j.internal.kernel.api.procs.QualifiedName) FailedLoadProcedure(org.neo4j.kernel.api.procedure.FailedLoadProcedure) UserFunction(org.neo4j.procedure.UserFunction) List(java.util.List) CallableProcedure(org.neo4j.kernel.api.procedure.CallableProcedure) KernelException(org.neo4j.exceptions.KernelException) Modifier.isPublic(java.lang.reflect.Modifier.isPublic) UserAggregationFunction(org.neo4j.procedure.UserAggregationFunction) FailedLoadAggregatedFunction(org.neo4j.kernel.api.procedure.FailedLoadAggregatedFunction) ProcedureSignature(org.neo4j.internal.kernel.api.procs.ProcedureSignature) Comparator(java.util.Comparator) Admin(org.neo4j.procedure.Admin) CallableUserFunction(org.neo4j.kernel.api.procedure.CallableUserFunction) CallableUserFunction(org.neo4j.kernel.api.procedure.CallableUserFunction) UserFunction(org.neo4j.procedure.UserFunction) QualifiedName(org.neo4j.internal.kernel.api.procs.QualifiedName) ArrayList(java.util.ArrayList) Method(java.lang.reflect.Method) ProcedureException(org.neo4j.internal.kernel.api.exceptions.ProcedureException) KernelException(org.neo4j.exceptions.KernelException) ProcedureException(org.neo4j.internal.kernel.api.exceptions.ProcedureException) ComponentInjectionException(org.neo4j.kernel.api.exceptions.ComponentInjectionException) KernelException(org.neo4j.exceptions.KernelException)

Example 12 with CallableUserFunction

use of org.neo4j.kernel.api.procedure.CallableUserFunction in project neo4j by neo4j.

the class ProcedureCompiler method compileFunction.

private CallableUserFunction compileFunction(Class<?> procDefinition, Method method, QualifiedName procName) throws ProcedureException {
    restrictions.verify(procName);
    List<FieldSignature> inputSignature = inputSignatureDeterminer.signatureFor(method);
    Class<?> returnType = method.getReturnType();
    TypeCheckers.TypeChecker typeChecker = typeCheckers.checkerFor(returnType);
    String description = description(method);
    UserFunction function = method.getAnnotation(UserFunction.class);
    String deprecated = deprecated(method, function::deprecatedBy, "Use of @UserFunction(deprecatedBy) without @Deprecated in " + procName);
    List<FieldSetter> setters = allFieldInjections.setters(procDefinition);
    if (!config.fullAccessFor(procName.toString())) {
        try {
            setters = safeFieldInjections.setters(procDefinition);
        } catch (ComponentInjectionException e) {
            description = describeAndLogLoadFailure(procName);
            UserFunctionSignature signature = new UserFunctionSignature(procName, inputSignature, typeChecker.type(), deprecated, config.rolesFor(procName.toString()), description, null, false);
            return new FailedLoadFunction(signature);
        }
    }
    UserFunctionSignature signature = new UserFunctionSignature(procName, inputSignature, typeChecker.type(), deprecated, config.rolesFor(procName.toString()), description, null, false);
    return ProcedureCompilation.compileFunction(signature, setters, method);
}
Also used : FieldSignature(org.neo4j.internal.kernel.api.procs.FieldSignature) UserFunctionSignature(org.neo4j.internal.kernel.api.procs.UserFunctionSignature) FailedLoadFunction(org.neo4j.kernel.api.procedure.FailedLoadFunction) CallableUserFunction(org.neo4j.kernel.api.procedure.CallableUserFunction) UserFunction(org.neo4j.procedure.UserFunction) ComponentInjectionException(org.neo4j.kernel.api.exceptions.ComponentInjectionException)

Example 13 with CallableUserFunction

use of org.neo4j.kernel.api.procedure.CallableUserFunction in project neo4j by neo4j.

the class UserFunctionTest method shouldNotLoadNoneWhiteListedFunction.

@Test
void shouldNotLoadNoneWhiteListedFunction() throws Throwable {
    // Given
    Log log = spy(Log.class);
    procedureCompiler = new ProcedureCompiler(new TypeCheckers(), components, new ComponentRegistry(), log, new ProcedureConfig(Config.defaults(GraphDatabaseSettings.procedure_allowlist, List.of("WrongName"))));
    List<CallableUserFunction> method = compile(SingleReadOnlyFunction.class);
    verify(log).warn("The function 'org.neo4j.procedure.impl.listCoolPeople' is not on the allowlist and won't be loaded.");
    assertThat(method.size()).isEqualTo(0);
}
Also used : CallableUserFunction(org.neo4j.kernel.api.procedure.CallableUserFunction) Log(org.neo4j.logging.Log) NullLog(org.neo4j.logging.NullLog) Test(org.junit.jupiter.api.Test)

Example 14 with CallableUserFunction

use of org.neo4j.kernel.api.procedure.CallableUserFunction in project neo4j by neo4j.

the class UserFunctionTest method shouldAllowOverridingProcedureName.

@Test
void shouldAllowOverridingProcedureName() throws Throwable {
    // When
    CallableUserFunction proc = compile(FunctionWithOverriddenName.class).get(0);
    // Then
    assertEquals("org.mystuff.thisisActuallyTheName", proc.signature().name().toString());
}
Also used : CallableUserFunction(org.neo4j.kernel.api.procedure.CallableUserFunction) Test(org.junit.jupiter.api.Test)

Example 15 with CallableUserFunction

use of org.neo4j.kernel.api.procedure.CallableUserFunction in project neo4j by neo4j.

the class UserFunctionTest method shouldLoadWhiteListedFunction.

@Test
void shouldLoadWhiteListedFunction() throws Throwable {
    // Given
    procedureCompiler = new ProcedureCompiler(new TypeCheckers(), components, new ComponentRegistry(), NullLog.getInstance(), new ProcedureConfig(Config.defaults(GraphDatabaseSettings.procedure_allowlist, List.of("org.neo4j.procedure.impl.listCoolPeople"))));
    CallableUserFunction method = compile(SingleReadOnlyFunction.class).get(0);
    // Expect
    Object out = method.apply(prepareContext(), new AnyValue[0]);
    assertThat(out).isEqualTo(ValueUtils.of(Arrays.asList("Bonnie", "Clyde")));
}
Also used : CallableUserFunction(org.neo4j.kernel.api.procedure.CallableUserFunction) Test(org.junit.jupiter.api.Test)

Aggregations

CallableUserFunction (org.neo4j.kernel.api.procedure.CallableUserFunction)28 Test (org.junit.jupiter.api.Test)23 UserFunctionSignature (org.neo4j.internal.kernel.api.procs.UserFunctionSignature)14 AnyValue (org.neo4j.values.AnyValue)10 ProcedureException (org.neo4j.internal.kernel.api.exceptions.ProcedureException)5 Log (org.neo4j.logging.Log)5 NullLog (org.neo4j.logging.NullLog)4 Collections.emptyList (java.util.Collections.emptyList)3 List (java.util.List)3 Method (java.lang.reflect.Method)2 Arrays.asList (java.util.Arrays.asList)2 Collections.singletonList (java.util.Collections.singletonList)2 FieldSignature (org.neo4j.internal.kernel.api.procs.FieldSignature)2 NTList (org.neo4j.internal.kernel.api.procs.Neo4jTypes.NTList)2 QualifiedName (org.neo4j.internal.kernel.api.procs.QualifiedName)2 ComponentInjectionException (org.neo4j.kernel.api.exceptions.ComponentInjectionException)2 CallableProcedure (org.neo4j.kernel.api.procedure.CallableProcedure)2 CallableUserAggregationFunction (org.neo4j.kernel.api.procedure.CallableUserAggregationFunction)2 FailedLoadFunction (org.neo4j.kernel.api.procedure.FailedLoadFunction)2 UserFunction (org.neo4j.procedure.UserFunction)2