use of org.neo4j.kernel.api.exceptions.ProcedureException in project neo4j by neo4j.
the class OperationsFacade method callProcedure.
private RawIterator<Object[], ProcedureException> callProcedure(QualifiedName name, Object[] input, final AccessMode override) throws ProcedureException {
statement.assertOpen();
final SecurityContext procedureSecurityContext = tx.securityContext().withMode(override);
final RawIterator<Object[], ProcedureException> procedureCall;
try (KernelTransaction.Revertable ignore = tx.overrideWith(procedureSecurityContext)) {
BasicContext ctx = new BasicContext();
ctx.put(Context.KERNEL_TRANSACTION, tx);
ctx.put(Context.THREAD, Thread.currentThread());
ctx.put(Context.SECURITY_CONTEXT, procedureSecurityContext);
procedureCall = procedures.callProcedure(ctx, name, input);
}
return new RawIterator<Object[], ProcedureException>() {
@Override
public boolean hasNext() throws ProcedureException {
try (KernelTransaction.Revertable ignore = tx.overrideWith(procedureSecurityContext)) {
return procedureCall.hasNext();
}
}
@Override
public Object[] next() throws ProcedureException {
try (KernelTransaction.Revertable ignore = tx.overrideWith(procedureSecurityContext)) {
return procedureCall.next();
}
}
};
}
use of org.neo4j.kernel.api.exceptions.ProcedureException in project neo4j by neo4j.
the class ProcedureRegistry method register.
/**
* Register a new procedure.
*
* @param proc the procedure.
*/
public void register(CallableProcedure proc, boolean overrideCurrentImplementation) throws ProcedureException {
ProcedureSignature signature = proc.signature();
QualifiedName name = signature.name();
String descriptiveName = signature.toString();
validateSignature(descriptiveName, signature.inputSignature(), "input");
validateSignature(descriptiveName, signature.outputSignature(), "output");
if (!signature.isVoid() && signature.outputSignature().isEmpty()) {
throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "Procedures with zero output fields must be declared as VOID");
}
CallableProcedure oldImplementation = procedures.get(name);
if (oldImplementation == null) {
procedures.put(name, proc);
} else {
if (overrideCurrentImplementation) {
procedures.put(name, proc);
} else {
throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "Unable to register procedure, because the name `%s` is already in use.", name);
}
}
}
use of org.neo4j.kernel.api.exceptions.ProcedureException in project neo4j by neo4j.
the class ReflectiveProcedureCompiler method compileAggregationFunction.
List<CallableUserAggregationFunction> compileAggregationFunction(Class<?> fcnDefinition) throws KernelException {
try {
List<Method> methods = Arrays.stream(fcnDefinition.getDeclaredMethods()).filter(m -> m.isAnnotationPresent(UserAggregationFunction.class)).collect(Collectors.toList());
if (methods.isEmpty()) {
return emptyList();
}
MethodHandle constructor = constructor(fcnDefinition);
ArrayList<CallableUserAggregationFunction> out = new ArrayList<>(methods.size());
for (Method method : methods) {
String valueName = method.getAnnotation(UserAggregationFunction.class).value();
String definedName = method.getAnnotation(UserAggregationFunction.class).name();
QualifiedName funcName = extractName(fcnDefinition, method, valueName, definedName);
if (config.isWhitelisted(funcName.toString())) {
out.add(compileAggregationFunction(fcnDefinition, constructor, method, funcName));
} else {
log.warn(String.format("The function '%s' is not on the whitelist 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());
}
}
use of org.neo4j.kernel.api.exceptions.ProcedureException in project neo4j by neo4j.
the class ReflectiveProcedureCompiler method compileProcedure.
private CallableProcedure compileProcedure(Class<?> procDefinition, MethodHandle constructor, Method method, Optional<String> warning, boolean fullAccess, QualifiedName procName) throws ProcedureException, IllegalAccessException {
MethodHandle procedureMethod = lookup.unreflect(method);
List<FieldSignature> inputSignature = inputSignatureDeterminer.signatureFor(method);
OutputMapper outputMapper = outputMappers.mapper(method);
Optional<String> description = description(method);
Procedure procedure = method.getAnnotation(Procedure.class);
Mode mode = procedure.mode();
if (method.isAnnotationPresent(PerformsWrites.class)) {
if (!procedure.mode().equals(org.neo4j.procedure.Mode.DEFAULT)) {
throw new ProcedureException(Status.Procedure.ProcedureRegistrationFailed, "Conflicting procedure annotation, cannot use PerformsWrites and mode");
} else {
mode = Mode.WRITE;
}
}
Optional<String> deprecated = deprecated(method, procedure::deprecatedBy, "Use of @Procedure(deprecatedBy) without @Deprecated in " + procName);
List<FieldInjections.FieldSetter> setters = allFieldInjections.setters(procDefinition);
if (!fullAccess && !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());
ProcedureSignature signature = new ProcedureSignature(procName, inputSignature, outputMapper.signature(), Mode.DEFAULT, Optional.empty(), new String[0], description, warning);
return new FailedLoadProcedure(signature);
}
}
ProcedureSignature signature = new ProcedureSignature(procName, inputSignature, outputMapper.signature(), mode, deprecated, config.rolesFor(procName.toString()), description, warning);
return new ReflectiveProcedure(signature, constructor, procedureMethod, outputMapper, setters);
}
use of org.neo4j.kernel.api.exceptions.ProcedureException in project neo4j by neo4j.
the class ReflectiveProcedureCompiler method compileProcedure.
List<CallableProcedure> compileProcedure(Class<?> procDefinition, Optional<String> warning, boolean fullAccess) throws KernelException {
try {
List<Method> procedureMethods = Arrays.stream(procDefinition.getDeclaredMethods()).filter(m -> m.isAnnotationPresent(Procedure.class)).collect(Collectors.toList());
if (procedureMethods.isEmpty()) {
return emptyList();
}
MethodHandle constructor = constructor(procDefinition);
ArrayList<CallableProcedure> out = new ArrayList<>(procedureMethods.size());
for (Method method : procedureMethods) {
String valueName = method.getAnnotation(Procedure.class).value();
String definedName = method.getAnnotation(Procedure.class).name();
QualifiedName procName = extractName(procDefinition, method, valueName, definedName);
if (fullAccess || config.isWhitelisted(procName.toString())) {
out.add(compileProcedure(procDefinition, constructor, method, warning, fullAccess, procName));
} else {
log.warn(String.format("The procedure '%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 procedure defined in `%s`: %s", procDefinition.getSimpleName(), e.getMessage());
}
}
Aggregations