Search in sources :

Example 11 with CallableUserFunction

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

the class ProcedureJarLoaderTest method shouldLoadUnsafeAllowedProcedureFromJar.

@Test
public void shouldLoadUnsafeAllowedProcedureFromJar() throws Throwable {
    // Given
    URL jar = createJarFor(ClassWithUnsafeConfiguredComponent.class);
    // When
    ProcedureJarLoader.Callables callables = jarloader.loadProcedures(jar);
    List<CallableUserFunction> functions = callables.functions();
    List<CallableProcedure> procedures = callables.procedures();
    // Then
    List<ProcedureSignature> signatures = procedures.stream().map(CallableProcedure::signature).collect(toList());
    assertThat(signatures, contains(procedureSignature("org", "neo4j", "kernel", "impl", "proc", "unsafeFullAccessProcedure").out("someNumber", NTInteger).build()));
    assertThat(asList(procedures.get(0).apply(new BasicContext(), new Object[0])), contains(IsEqual.equalTo(new Object[] { 7331L })));
    List<UserFunctionSignature> functionsSignatures = functions.stream().map(CallableUserFunction::signature).collect(toList());
    assertThat(functionsSignatures, contains(functionSignature("org", "neo4j", "kernel", "impl", "proc", "unsafeFullAccessFunction").out(NTInteger).build()));
    assertThat(functions.get(0).apply(new BasicContext(), new Object[0]), equalTo(7331L));
}
Also used : CallableUserFunction(org.neo4j.kernel.api.proc.CallableUserFunction) BasicContext(org.neo4j.kernel.api.proc.BasicContext) UserFunctionSignature(org.neo4j.kernel.api.proc.UserFunctionSignature) URL(java.net.URL) ProcedureSignature(org.neo4j.kernel.api.proc.ProcedureSignature) CallableProcedure(org.neo4j.kernel.api.proc.CallableProcedure) Test(org.junit.Test)

Example 12 with CallableUserFunction

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

the class ReflectiveProcedureCompiler method compileFunction.

List<CallableUserFunction> compileFunction(Class<?> fcnDefinition) throws KernelException {
    try {
        List<Method> procedureMethods = Arrays.stream(fcnDefinition.getDeclaredMethods()).filter(m -> m.isAnnotationPresent(UserFunction.class)).collect(Collectors.toList());
        if (procedureMethods.isEmpty()) {
            return emptyList();
        }
        MethodHandle constructor = constructor(fcnDefinition);
        ArrayList<CallableUserFunction> out = new ArrayList<>(procedureMethods.size());
        for (Method method : procedureMethods) {
            String valueName = method.getAnnotation(UserFunction.class).value();
            String definedName = method.getAnnotation(UserFunction.class).name();
            QualifiedName procName = extractName(fcnDefinition, method, valueName, definedName);
            if (config.isWhitelisted(procName.toString())) {
                out.add(compileFunction(fcnDefinition, constructor, method, procName));
            } else {
                log.warn(String.format("The function '%s' is not on the whitelist and won't be loaded.", procName.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 : FailedLoadProcedure(org.neo4j.kernel.api.proc.FailedLoadProcedure) Mode(org.neo4j.procedure.Mode) MethodHandle(java.lang.invoke.MethodHandle) Arrays(java.util.Arrays) ProcedureException(org.neo4j.kernel.api.exceptions.ProcedureException) Log(org.neo4j.logging.Log) RawIterator(org.neo4j.collection.RawIterator) CallableProcedure(org.neo4j.kernel.api.proc.CallableProcedure) UserAggregationResult(org.neo4j.procedure.UserAggregationResult) Status(org.neo4j.kernel.api.exceptions.Status) UserAggregationUpdate(org.neo4j.procedure.UserAggregationUpdate) FailedLoadFunction(org.neo4j.kernel.api.proc.FailedLoadFunction) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) Iterators.asRawIterator(org.neo4j.helpers.collection.Iterators.asRawIterator) FailedLoadAggregatedFunction(org.neo4j.kernel.api.proc.FailedLoadAggregatedFunction) ProcedureSignature(org.neo4j.kernel.api.proc.ProcedureSignature) CallableUserAggregationFunction(org.neo4j.kernel.api.proc.CallableUserAggregationFunction) Procedure(org.neo4j.procedure.Procedure) Method(java.lang.reflect.Method) ComponentInjectionException(org.neo4j.kernel.api.exceptions.ComponentInjectionException) CallableUserFunction(org.neo4j.kernel.api.proc.CallableUserFunction) Iterator(java.util.Iterator) UserFunctionSignature(org.neo4j.kernel.api.proc.UserFunctionSignature) Collections.emptyList(java.util.Collections.emptyList) MethodHandles(java.lang.invoke.MethodHandles) Description(org.neo4j.procedure.Description) Collections.emptyIterator(java.util.Collections.emptyIterator) Collectors(java.util.stream.Collectors) KernelException(org.neo4j.kernel.api.exceptions.KernelException) FieldSignature(org.neo4j.kernel.api.proc.FieldSignature) UserFunction(org.neo4j.procedure.UserFunction) List(java.util.List) Stream(java.util.stream.Stream) UserAggregationFunction(org.neo4j.procedure.UserAggregationFunction) QualifiedName(org.neo4j.kernel.api.proc.QualifiedName) Modifier(java.lang.reflect.Modifier) Optional(java.util.Optional) PerformsWrites(org.neo4j.procedure.PerformsWrites) Comparator(java.util.Comparator) Context(org.neo4j.kernel.api.proc.Context) OutputMapper(org.neo4j.kernel.impl.proc.OutputMappers.OutputMapper) CallableUserFunction(org.neo4j.kernel.api.proc.CallableUserFunction) QualifiedName(org.neo4j.kernel.api.proc.QualifiedName) ArrayList(java.util.ArrayList) Method(java.lang.reflect.Method) ProcedureException(org.neo4j.kernel.api.exceptions.ProcedureException) ComponentInjectionException(org.neo4j.kernel.api.exceptions.ComponentInjectionException) KernelException(org.neo4j.kernel.api.exceptions.KernelException) CallableUserFunction(org.neo4j.kernel.api.proc.CallableUserFunction) UserFunction(org.neo4j.procedure.UserFunction) ProcedureException(org.neo4j.kernel.api.exceptions.ProcedureException) KernelException(org.neo4j.kernel.api.exceptions.KernelException) MethodHandle(java.lang.invoke.MethodHandle)

Example 13 with CallableUserFunction

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

the class ReflectiveProcedureCompiler method compileFunction.

private CallableUserFunction compileFunction(Class<?> procDefinition, MethodHandle constructor, Method method, QualifiedName procName) throws ProcedureException, IllegalAccessException {
    if (procName.namespace() == null || procName.namespace().length == 0) {
        throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "It is not allowed to define functions in the root namespace please use a namespace, e.g. `@UserFunction(\"org.example.com.%s\")", procName.name());
    }
    List<FieldSignature> inputSignature = inputSignatureDeterminer.signatureFor(method);
    Class<?> returnType = method.getReturnType();
    TypeMappers.NeoValueConverter valueConverter = typeMappers.converterFor(returnType);
    MethodHandle procedureMethod = lookup.unreflect(method);
    Optional<String> description = description(method);
    UserFunction function = method.getAnnotation(UserFunction.class);
    Optional<String> deprecated = deprecated(method, function::deprecatedBy, "Use of @UserFunction(deprecatedBy) without @Deprecated in " + procName);
    List<FieldInjections.FieldSetter> setters = allFieldInjections.setters(procDefinition);
    if (!config.fullAccessFor(procName.toString())) {
        try {
            setters = safeFieldInjections.setters(procDefinition);
        } catch (ComponentInjectionException e) {
            description = Optional.of(procName.toString() + " is not available due to having restricted access rights, check configuration.");
            log.warn(description.get());
            UserFunctionSignature signature = new UserFunctionSignature(procName, inputSignature, valueConverter.type(), deprecated, config.rolesFor(procName.toString()), description);
            return new FailedLoadFunction(signature);
        }
    }
    UserFunctionSignature signature = new UserFunctionSignature(procName, inputSignature, valueConverter.type(), deprecated, config.rolesFor(procName.toString()), description);
    return new ReflectiveUserFunction(signature, constructor, procedureMethod, valueConverter, setters);
}
Also used : FieldSignature(org.neo4j.kernel.api.proc.FieldSignature) UserFunctionSignature(org.neo4j.kernel.api.proc.UserFunctionSignature) FailedLoadFunction(org.neo4j.kernel.api.proc.FailedLoadFunction) CallableUserFunction(org.neo4j.kernel.api.proc.CallableUserFunction) UserFunction(org.neo4j.procedure.UserFunction) ProcedureException(org.neo4j.kernel.api.exceptions.ProcedureException) ComponentInjectionException(org.neo4j.kernel.api.exceptions.ComponentInjectionException) MethodHandle(java.lang.invoke.MethodHandle)

Example 14 with CallableUserFunction

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

the class ReflectiveUserFunctionTest method shouldAllowOverridingProcedureName.

@Test
public 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.proc.CallableUserFunction) Test(org.junit.Test)

Example 15 with CallableUserFunction

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

the class ReflectiveUserFunctionTest method shouldGiveHelpfulErrorOnNullMessageException.

@Test
public void shouldGiveHelpfulErrorOnNullMessageException() throws Throwable {
    // Given
    CallableUserFunction proc = compile(FunctionThatThrowsNullMsgExceptionAtInvocation.class).get(0);
    // Expect
    exception.expect(ProcedureException.class);
    exception.expectMessage("Failed to invoke function `org.neo4j.kernel.impl.proc.throwsAtInvocation`: " + "Caused by: java.lang.IndexOutOfBoundsException");
    // When
    proc.apply(new BasicContext(), new Object[0]);
}
Also used : CallableUserFunction(org.neo4j.kernel.api.proc.CallableUserFunction) BasicContext(org.neo4j.kernel.api.proc.BasicContext) Test(org.junit.Test)

Aggregations

CallableUserFunction (org.neo4j.kernel.api.proc.CallableUserFunction)17 Test (org.junit.Test)12 BasicContext (org.neo4j.kernel.api.proc.BasicContext)9 ProcedureException (org.neo4j.kernel.api.exceptions.ProcedureException)5 UserFunctionSignature (org.neo4j.kernel.api.proc.UserFunctionSignature)5 Log (org.neo4j.logging.Log)5 NullLog (org.neo4j.logging.NullLog)4 CallableProcedure (org.neo4j.kernel.api.proc.CallableProcedure)3 QualifiedName (org.neo4j.kernel.api.proc.QualifiedName)3 MethodHandle (java.lang.invoke.MethodHandle)2 ComponentInjectionException (org.neo4j.kernel.api.exceptions.ComponentInjectionException)2 CallableUserAggregationFunction (org.neo4j.kernel.api.proc.CallableUserAggregationFunction)2 FailedLoadFunction (org.neo4j.kernel.api.proc.FailedLoadFunction)2 FieldSignature (org.neo4j.kernel.api.proc.FieldSignature)2 ProcedureSignature (org.neo4j.kernel.api.proc.ProcedureSignature)2 UserFunction (org.neo4j.procedure.UserFunction)2 MethodHandles (java.lang.invoke.MethodHandles)1 Method (java.lang.reflect.Method)1 Modifier (java.lang.reflect.Modifier)1 URL (java.net.URL)1