use of org.neo4j.kernel.api.procedure.CallableProcedure in project neo4j by neo4j.
the class ProcedureCompiler method compileProcedure.
List<CallableProcedure> compileProcedure(Class<?> procDefinition, 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();
}
assertValidConstructor(procDefinition);
List<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, method, warning, fullAccess, procName));
} else {
log.warn(String.format("The procedure '%s' is not on the allowlist 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());
}
}
use of org.neo4j.kernel.api.procedure.CallableProcedure in project neo4j by neo4j.
the class ProcedureCompiler method compileProcedure.
private CallableProcedure compileProcedure(Class<?> procDefinition, Method method, String warning, boolean fullAccess, QualifiedName procName) throws ProcedureException {
List<FieldSignature> inputSignature = inputSignatureDeterminer.signatureFor(method);
List<FieldSignature> outputSignature = outputSignatureCompiler.fieldSignatures(method);
String description = description(method);
Procedure procedure = method.getAnnotation(Procedure.class);
Mode mode = procedure.mode();
boolean admin = method.isAnnotationPresent(Admin.class);
boolean systemProcedure = method.isAnnotationPresent(SystemProcedure.class);
boolean allowExpiredCredentials = systemProcedure ? method.getAnnotation(SystemProcedure.class).allowExpiredCredentials() : false;
boolean internal = method.isAnnotationPresent(Internal.class);
String deprecated = deprecated(method, procedure::deprecatedBy, "Use of @Procedure(deprecatedBy) without @Deprecated in " + procName);
List<FieldSetter> setters = allFieldInjections.setters(procDefinition);
if (!fullAccess && !config.fullAccessFor(procName.toString())) {
try {
setters = safeFieldInjections.setters(procDefinition);
} catch (ComponentInjectionException e) {
description = describeAndLogLoadFailure(procName);
ProcedureSignature signature = new ProcedureSignature(procName, inputSignature, outputSignature, Mode.DEFAULT, admin, null, new String[0], description, warning, procedure.eager(), false, systemProcedure, internal, allowExpiredCredentials);
return new FailedLoadProcedure(signature);
}
}
ProcedureSignature signature = new ProcedureSignature(procName, inputSignature, outputSignature, mode, admin, deprecated, config.rolesFor(procName.toString()), description, warning, procedure.eager(), false, systemProcedure, internal, allowExpiredCredentials);
return ProcedureCompilation.compileProcedure(signature, setters, method);
}
use of org.neo4j.kernel.api.procedure.CallableProcedure in project neo4j by neo4j.
the class ProcedureRegistry method callProcedure.
public RawIterator<AnyValue[], ProcedureException> callProcedure(Context ctx, int id, AnyValue[] input, ResourceTracker resourceTracker) throws ProcedureException {
CallableProcedure proc;
try {
proc = procedures.get(id);
if (proc.signature().admin() && !ctx.securityContext().allowExecuteAdminProcedure(id)) {
String message = format("Executing admin procedure '%s' is not allowed for %s.", proc.signature().name(), ctx.securityContext().description());
ctx.dependencyResolver().resolveDependency(AbstractSecurityLog.class).error(ctx.securityContext(), message);
throw new AuthorizationViolationException(message);
}
} catch (IndexOutOfBoundsException e) {
throw noSuchProcedure(id);
}
return proc.apply(ctx, input, resourceTracker);
}
use of org.neo4j.kernel.api.procedure.CallableProcedure 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, signature.caseInsensitive());
} else {
if (overrideCurrentImplementation) {
procedures.put(name, proc, signature.caseInsensitive());
} 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.procedure.CallableProcedure in project neo4j by neo4j.
the class ProcedureTest method shouldAllowOverridingProcedureNameWithoutNamespace.
@Test
void shouldAllowOverridingProcedureNameWithoutNamespace() throws Throwable {
// When
CallableProcedure proc = compile(ProcedureWithSingleName.class).get(0);
// Then
assertEquals("singleName", proc.signature().name().toString());
}
Aggregations