Search in sources :

Example 11 with CallableProcedure

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());
    }
}
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) QualifiedName(org.neo4j.internal.kernel.api.procs.QualifiedName) ArrayList(java.util.ArrayList) CallableProcedure(org.neo4j.kernel.api.procedure.CallableProcedure) SystemProcedure(org.neo4j.kernel.api.procedure.SystemProcedure) Procedure(org.neo4j.procedure.Procedure) FailedLoadProcedure(org.neo4j.kernel.api.procedure.FailedLoadProcedure) CallableProcedure(org.neo4j.kernel.api.procedure.CallableProcedure) 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 CallableProcedure

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);
}
Also used : ProcedureSignature(org.neo4j.internal.kernel.api.procs.ProcedureSignature) FailedLoadProcedure(org.neo4j.kernel.api.procedure.FailedLoadProcedure) Mode(org.neo4j.procedure.Mode) SystemProcedure(org.neo4j.kernel.api.procedure.SystemProcedure) Procedure(org.neo4j.procedure.Procedure) FailedLoadProcedure(org.neo4j.kernel.api.procedure.FailedLoadProcedure) CallableProcedure(org.neo4j.kernel.api.procedure.CallableProcedure) FieldSignature(org.neo4j.internal.kernel.api.procs.FieldSignature) ComponentInjectionException(org.neo4j.kernel.api.exceptions.ComponentInjectionException)

Example 13 with CallableProcedure

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);
}
Also used : CallableProcedure(org.neo4j.kernel.api.procedure.CallableProcedure) AbstractSecurityLog(org.neo4j.internal.kernel.api.security.AbstractSecurityLog) AuthorizationViolationException(org.neo4j.graphdb.security.AuthorizationViolationException)

Example 14 with CallableProcedure

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);
        }
    }
}
Also used : ProcedureSignature(org.neo4j.internal.kernel.api.procs.ProcedureSignature) QualifiedName(org.neo4j.internal.kernel.api.procs.QualifiedName) CallableProcedure(org.neo4j.kernel.api.procedure.CallableProcedure) ProcedureException(org.neo4j.internal.kernel.api.exceptions.ProcedureException)

Example 15 with CallableProcedure

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());
}
Also used : CallableProcedure(org.neo4j.kernel.api.procedure.CallableProcedure) Test(org.junit.jupiter.api.Test)

Aggregations

CallableProcedure (org.neo4j.kernel.api.procedure.CallableProcedure)35 Test (org.junit.jupiter.api.Test)29 ProcedureException (org.neo4j.internal.kernel.api.exceptions.ProcedureException)16 ProcedureSignature (org.neo4j.internal.kernel.api.procs.ProcedureSignature)13 Log (org.neo4j.logging.Log)7 AnyValue (org.neo4j.values.AnyValue)7 NullLog (org.neo4j.logging.NullLog)6 URL (java.net.URL)4 FieldSignature (org.neo4j.internal.kernel.api.procs.FieldSignature)2 QualifiedName (org.neo4j.internal.kernel.api.procs.QualifiedName)2 ComponentInjectionException (org.neo4j.kernel.api.exceptions.ComponentInjectionException)2 CallableUserAggregationFunction (org.neo4j.kernel.api.procedure.CallableUserAggregationFunction)2 CallableUserFunction (org.neo4j.kernel.api.procedure.CallableUserFunction)2 FailedLoadProcedure (org.neo4j.kernel.api.procedure.FailedLoadProcedure)2 SystemProcedure (org.neo4j.kernel.api.procedure.SystemProcedure)2 Mode (org.neo4j.procedure.Mode)2 Procedure (org.neo4j.procedure.Procedure)2 Constructor (java.lang.reflect.Constructor)1 Method (java.lang.reflect.Method)1 Modifier.isPublic (java.lang.reflect.Modifier.isPublic)1