use of org.neo4j.kernel.api.procedure.Context in project neo4j by neo4j.
the class ProceduresTest method shouldMakeContextAvailable.
@Test
void shouldMakeContextAvailable() throws Throwable {
// Given
procs.register(new CallableProcedure.BasicProcedure(signature) {
@Override
public RawIterator<AnyValue[], ProcedureException> apply(Context ctx, AnyValue[] input, ResourceTracker resourceTracker) {
return RawIterator.<AnyValue[], ProcedureException>of(new AnyValue[] { stringValue(ctx.thread().getName()) });
}
});
Context ctx = prepareContext();
ProcedureHandle procedureHandle = procs.procedure(signature.name());
// When
RawIterator<AnyValue[], ProcedureException> result = procs.callProcedure(ctx, procedureHandle.id(), new AnyValue[0], EMPTY_RESOURCE_TRACKER);
// Then
assertThat(asList(result)).contains(new AnyValue[] { stringValue(Thread.currentThread().getName()) });
}
use of org.neo4j.kernel.api.procedure.Context in project neo4j by neo4j.
the class BoltChannelAutoReadLimiterIT method installSleepProcedure.
private static void installSleepProcedure(GraphDatabaseService db) throws ProcedureException {
GraphDatabaseAPI dbApi = (GraphDatabaseAPI) db;
dbApi.getDependencyResolver().resolveDependency(GlobalProcedures.class).register(new CallableProcedure.BasicProcedure(procedureSignature("boltissue", "sleep").in("data", Neo4jTypes.NTString).out(ProcedureSignature.VOID).build()) {
@Override
public RawIterator<AnyValue[], ProcedureException> apply(Context context, AnyValue[] objects, ResourceTracker resourceTracker) throws ProcedureException {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
throw new ProcedureException(Status.General.UnknownError, e, "Interrupted");
}
return RawIterator.empty();
}
});
}
use of org.neo4j.kernel.api.procedure.Context in project neo4j by neo4j.
the class DatabaseManagementServiceFactory method setupProcedures.
/**
* Creates and registers the systems procedures, including those which belong to a particular edition.
* N.B. This method takes a {@link DatabaseManager} as an unused parameter *intentionally*, in
* order to enforce that the databaseManager must be constructed first.
*/
@SuppressWarnings("unused")
private static void setupProcedures(GlobalModule globalModule, AbstractEditionModule editionModule, DatabaseManager<?> databaseManager) {
Supplier<GlobalProcedures> procedureInitializer = () -> {
Config globalConfig = globalModule.getGlobalConfig();
Path proceduresDirectory = globalConfig.get(GraphDatabaseSettings.plugin_dir);
LogService logService = globalModule.getLogService();
Log internalLog = logService.getInternalLog(GlobalProcedures.class);
Log proceduresLog = logService.getUserLog(GlobalProcedures.class);
ProcedureConfig procedureConfig = new ProcedureConfig(globalConfig);
Edition neo4jEdition = globalModule.getDbmsInfo().edition;
SpecialBuiltInProcedures builtInProcedures = new SpecialBuiltInProcedures(Version.getNeo4jVersion(), neo4jEdition.toString());
GlobalProceduresRegistry globalProcedures = new GlobalProceduresRegistry(builtInProcedures, proceduresDirectory, internalLog, procedureConfig);
globalProcedures.registerType(Node.class, NTNode);
globalProcedures.registerType(NodeValue.class, NTNode);
globalProcedures.registerType(Relationship.class, NTRelationship);
globalProcedures.registerType(RelationshipValue.class, NTRelationship);
globalProcedures.registerType(org.neo4j.graphdb.Path.class, NTPath);
globalProcedures.registerType(PathValue.class, NTPath);
globalProcedures.registerType(Geometry.class, NTGeometry);
globalProcedures.registerType(Point.class, NTPoint);
globalProcedures.registerType(PointValue.class, NTPoint);
// Below components are not public API, but are made available for internal
// procedures to call, and to provide temporary workarounds for the following
// patterns:
// - Batch-transaction imports (GDAPI, needs to be real and passed to background processing threads)
// - Group-transaction writes (same pattern as above, but rather than splitting large transactions,
// combine lots of small ones)
// - Bleeding-edge performance (KernelTransaction, to bypass overhead of working with Core API)
globalProcedures.registerComponent(DependencyResolver.class, Context::dependencyResolver, false);
globalProcedures.registerComponent(KernelTransaction.class, ctx -> ctx.internalTransaction().kernelTransaction(), false);
globalProcedures.registerComponent(GraphDatabaseAPI.class, Context::graphDatabaseAPI, false);
globalProcedures.registerComponent(SystemGraphComponents.class, ctx -> globalModule.getSystemGraphComponents(), false);
globalProcedures.registerComponent(ValueMapper.class, Context::valueMapper, true);
// Register injected public API components
globalProcedures.registerComponent(Log.class, ctx -> proceduresLog, true);
globalProcedures.registerComponent(Transaction.class, new ProcedureTransactionProvider(), true);
globalProcedures.registerComponent(org.neo4j.procedure.TerminationGuard.class, new TerminationGuardProvider(), true);
globalProcedures.registerComponent(SecurityContext.class, Context::securityContext, true);
globalProcedures.registerComponent(ProcedureCallContext.class, Context::procedureCallContext, true);
globalProcedures.registerComponent(FulltextAdapter.class, ctx -> ctx.dependencyResolver().resolveDependency(FulltextAdapter.class), true);
globalProcedures.registerComponent(GraphDatabaseService.class, ctx -> new GraphDatabaseFacade((GraphDatabaseFacade) ctx.graphDatabaseAPI(), new ProcedureLoginContextTransformer(ctx)), true);
globalProcedures.registerComponent(DataCollector.class, ctx -> ctx.dependencyResolver().resolveDependency(DataCollector.class), false);
// Edition procedures
try {
editionModule.registerProcedures(globalProcedures, procedureConfig, globalModule, databaseManager);
} catch (KernelException e) {
internalLog.error("Failed to register built-in edition procedures at start up: " + e.getMessage());
}
globalModule.getGlobalLife().add(globalProcedures);
return globalProcedures;
};
GlobalProcedures procedures = tryResolveOrCreate(GlobalProcedures.class, globalModule.getExternalDependencyResolver(), procedureInitializer);
if (procedures instanceof Consumer) {
((Consumer) procedures).accept(procedureInitializer);
}
globalModule.getGlobalDependencies().satisfyDependency(procedures);
}
use of org.neo4j.kernel.api.procedure.Context in project neo4j by neo4j.
the class UserFunctionsTest method shouldMakeContextAvailable.
@Test
void shouldMakeContextAvailable() throws Throwable {
// Given
procs.register(new CallableUserFunction.BasicUserFunction(signature) {
@Override
public AnyValue apply(Context ctx, AnyValue[] input) throws ProcedureException {
return Values.stringValue(ctx.thread().getName());
}
});
Context ctx = prepareContext();
int functionId = procs.function(signature.name()).id();
// When
Object result = procs.callFunction(ctx, functionId, new AnyValue[0]);
// Then
assertThat(result).isEqualTo(Values.stringValue(Thread.currentThread().getName()));
}
use of org.neo4j.kernel.api.procedure.Context in project neo4j by neo4j.
the class ProcedureCompilation method generateAggregator.
private static Class<?> generateAggregator(CodeGenerator codeGenerator, Method update, Method result, UserFunctionSignature signature) {
assert update.getDeclaringClass().equals(result.getDeclaringClass());
Class<?> userAggregatorClass = update.getDeclaringClass();
ClassHandle handle;
try (ClassGenerator generator = codeGenerator.generateClass(PACKAGE, "Aggregator" + userAggregatorClass.getSimpleName() + System.nanoTime(), UserAggregator.class)) {
FieldReference aggregator = generator.field(userAggregatorClass, "aggregator");
FieldReference context = generator.field(Context.class, "ctx");
// constructor
try (CodeBlock constructor = generator.generateConstructor(param(userAggregatorClass, "aggregator"), param(Context.class, "ctx"))) {
constructor.expression(invokeSuper(OBJECT));
constructor.put(constructor.self(), aggregator, constructor.load("aggregator"));
constructor.put(constructor.self(), context, constructor.load("ctx"));
}
// update
try (CodeBlock block = generator.generate(AGGREGATION_UPDATE)) {
block.tryCatch(onSuccess -> onSuccess.expression(invoke(get(onSuccess.self(), aggregator), methodReference(update), parameters(onSuccess, update, get(onSuccess.self(), context)))), onError -> onError(onError, format("function `%s`", signature.name())), param(Throwable.class, "T"));
}
// result
try (CodeBlock block = generator.generate(AGGREGATION_RESULT)) {
block.tryCatch(onSuccess -> onSuccess.returns(toAnyValue(invoke(get(onSuccess.self(), aggregator), methodReference(result)), result.getReturnType(), get(onSuccess.self(), context))), onError -> onError(onError, format("function `%s`", signature.name())), param(Throwable.class, "T"));
}
handle = generator.handle();
}
try {
return handle.loadClass();
} catch (CompilationFailureException e) {
// We are being called from a lambda so it'll have to do with runtime exceptions here
throw new RuntimeException("Failed to generate iterator", e);
}
}
Aggregations