use of org.neo4j.internal.kernel.api.procs.UserAggregator in project neo4j by neo4j.
the class AllStoreHolder method createAggregationFunction.
private UserAggregator createAggregationFunction(int id) throws ProcedureException {
ktx.assertOpen();
AccessMode mode = ktx.securityContext().mode();
if (!globalProcedures.isBuiltInAggregatingFunction(id) && !mode.allowsExecuteAggregatingFunction(id)) {
String message = format("Executing a user defined aggregating function is not allowed for %s.", ktx.securityContext().description());
throw ktx.securityAuthorizationHandler().logAndGetAuthorizationException(ktx.securityContext(), message);
}
final SecurityContext securityContext = mode.shouldBoostAggregatingFunction(id) ? ktx.securityContext().withMode(new OverriddenAccessMode(mode, AccessMode.Static.READ)) : ktx.securityContext().withMode(new RestrictedAccessMode(mode, AccessMode.Static.READ));
try (KernelTransaction.Revertable ignore = ktx.overrideWith(securityContext)) {
UserAggregator aggregator = globalProcedures.createAggregationFunction(prepareContext(securityContext, ProcedureCallContext.EMPTY), id);
return new UserAggregator() {
@Override
public void update(AnyValue[] input) throws ProcedureException {
try (KernelTransaction.Revertable ignore = ktx.overrideWith(securityContext)) {
aggregator.update(input);
}
}
@Override
public AnyValue result() throws ProcedureException {
try (KernelTransaction.Revertable ignore = ktx.overrideWith(securityContext)) {
return aggregator.result();
}
}
};
}
}
use of org.neo4j.internal.kernel.api.procs.UserAggregator in project neo4j by neo4j.
the class ProcedureCompilationTest method aggregationShouldAccessContext.
@Test
void aggregationShouldAccessContext() throws ProcedureException, NoSuchFieldException {
// Given
UserFunctionSignature signature = functionSignature("test", "foo").in("in", NTString).out(NTString).build();
FieldSetter setter = createSetter(InnerClass.class, "thread", Context::thread);
String threadName = Thread.currentThread().getName();
UserAggregator aggregator = compileAggregation(signature, singletonList(setter), method(InnerClass.class, "create"), method(InnerClass.Aggregator.class, "update", String.class), method(InnerClass.Aggregator.class, "result")).create(ctx);
// When
aggregator.update(new AnyValue[] { stringValue("1:") });
aggregator.update(new AnyValue[] { stringValue("2:") });
aggregator.update(new AnyValue[] { stringValue("3:") });
// Then
assertEquals(stringValue(format("1: %s, 2: %s, 3: %s", threadName, threadName, threadName)), aggregator.result());
}
use of org.neo4j.internal.kernel.api.procs.UserAggregator in project neo4j by neo4j.
the class ProcedureCompilationTest method shouldHandleThrowingAggregations.
@Test
void shouldHandleThrowingAggregations() throws ProcedureException {
UserFunctionSignature signature = functionSignature("test", "foo").out(NTInteger).build();
UserAggregator aggregator = compileAggregation(signature, emptyList(), method("blackAdder"), method(BlackAdder.class, "update"), method(BlackAdder.class, "result")).create(ctx);
assertThrows(ProcedureException.class, () -> aggregator.update(EMPTY));
assertThrows(ProcedureException.class, aggregator::result);
}
use of org.neo4j.internal.kernel.api.procs.UserAggregator in project neo4j by neo4j.
the class UserAggregationFunctionTest method shouldLoadWhiteListedFunction.
@Test
void shouldLoadWhiteListedFunction() throws Throwable {
// Given
procedureCompiler = new ProcedureCompiler(new TypeCheckers(), components, new ComponentRegistry(), NullLog.getInstance(), new ProcedureConfig(Config.defaults(GraphDatabaseSettings.procedure_allowlist, List.of("org.neo4j.procedure.impl.collectCool"))));
CallableUserAggregationFunction method = compile(SingleAggregationFunction.class).get(0);
// Expect
UserAggregator created = method.create(prepareContext());
created.update(new AnyValue[] { stringValue("Bonnie") });
assertThat(created.result()).isEqualTo(VirtualValues.list(stringValue("Bonnie")));
}
use of org.neo4j.internal.kernel.api.procs.UserAggregator in project neo4j by neo4j.
the class UserAggregationFunctionTest method shouldRunClassWithMultipleFunctionsDeclared.
@Test
void shouldRunClassWithMultipleFunctionsDeclared() throws Throwable {
// Given
List<CallableUserAggregationFunction> compiled = compile(MultiFunction.class);
CallableUserAggregationFunction f1 = compiled.get(0);
CallableUserAggregationFunction f2 = compiled.get(1);
// When
UserAggregator f1Aggregator = f1.create(prepareContext());
f1Aggregator.update(new AnyValue[] { stringValue("Bonnie") });
f1Aggregator.update(new AnyValue[] { stringValue("Clyde") });
UserAggregator f2Aggregator = f2.create(prepareContext());
f2Aggregator.update(new AnyValue[] { stringValue("Bonnie"), longValue(1337L) });
f2Aggregator.update(new AnyValue[] { stringValue("Bonnie"), longValue(42L) });
// Then
assertThat(f1Aggregator.result()).isEqualTo(VirtualValues.list(stringValue("Bonnie"), stringValue("Clyde")));
assertThat(((MapValue) f2Aggregator.result()).get("Bonnie")).isEqualTo(longValue(1337L));
}
Aggregations