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));
}
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());
}
}
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);
}
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());
}
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]);
}
Aggregations