Skip to main content

nexora-api

NexoraEngine, the public facade. This is the only class you need to import for production use.

Builder reference​

NexoraEngine engine = NexoraEngine.builder()
// Capabilities and plugins
.withPlugin(new PaymentPlugin())
.withPlugin(new NotificationPlugin())

// Step definitions (if not contributed by plugins)
.withStepDefinition(new StepDefinition("validate", "validate_order", ...))

// Retry behaviour
.withDefaultRetryPolicy(
ExponentialBackoffPolicy.builder()
.maxAttempts(3)
.initialDelay(Duration.ofMillis(200))
.build()
)

// Per-step default timeout (overridden by StepDefinition.timeout)
.withDefaultTimeout(Duration.ofSeconds(30))

// Distributed tracing
.withTracer(new OtelTracer(GlobalOpenTelemetry.get()))

// Execution persistence
.withExecutionStore(new JdbcExecutionStore(dataSource))

// Saga rollback
.withSagaEnabled(true)

// Custom executor (default: virtual threads)
.withExecutor(Executors.newVirtualThreadPerTaskExecutor())

// Plugin JARs (loaded + activated in build(), after withPlugin() plugins, in the order added)
.withPluginJar(Path.of("/etc/nexora/plugins/payment-plugin-1.2.0.jar"))

.build();

Executing an intent​

Intent intent = new Intent("process_order", Map.of(
"orderId", "ORD-991",
"customerId", "CUST-42"
));

ExecutionResult result = engine.execute(intent).join();

if (result.status() == ExecutionStatus.COMPLETED) {
Object receipt = result.outputFor("send_receipt"); // step output by key
} else {
result.stepResults().stream()
.filter(s -> s.status() == StepStatus.FAILED)
.forEach(s -> log.error("Step {} failed: {}", s.stepId(), s.error()));
}

Subscribing to events​

Subscription sub = engine.subscribe(event -> {
if (event instanceof StepFailedEvent e) {
alerting.fire("step.failed", e.capabilityId());
}
});

// Later:
sub.cancel();

Inspecting contract health​

NexoraEngine.HealthSnapshot snap = NexoraEngine.HealthSnapshot.from(engine.capabilityHealth("charge_card"));
// snap.state(), snap.sampleCount(), snap.errorRate(), snap.p99Latency()

Plugin management at runtime​

// Loads the JAR and activates the plugin with the given id
engine.loadPlugin(Path.of("/opt/plugins/v2-plugin.jar"), "v2-plugin");

engine.activePluginIds(); // [..., "v2-plugin"]

All active plugins are deactivated when the engine shuts down (engine.shutdown() or close()). There is no public API to deactivate a single plugin at runtime.


Cancelling an execution​

ExecutionHandle handle = engine.submit(intent); // id is known immediately

engine.cancel(handle.executionId()).join(); // true if cancelled, false if already finished
handle.result().join().status(); // CANCELLED

Pending steps never start and running steps are interrupted. Unknown ids fail with ExecutionNotFoundException. See Execution Cancellation for the full reference.


Replaying an execution​

ExecutionHandle replay = engine.replay(failedExecutionId); // new id, same goal and context
replay.result().join();

Allowed for FAILED, TIMED_OUT, CANCELLED and COMPENSATED executions. Steps that completed reuse their idempotency keys unless the original was compensated. See Execution Replay.


Cron scheduling​

Requires a persistence store. Returns a ScheduledExecution handle with id(), nextFireTime(), and cancel().

// Register, default FIRE_ONCE missed-fire policy
ScheduledExecution handle = engine.schedule("0 0 * * *", new Intent("nightly cleanup", Map.of()));

System.out.println(handle.nextFireTime()); // next UTC midnight

// Override missed-fire policy
engine.schedule("*/5 * * * *", intent, MissedFirePolicy.SKIP);

// Cancel
handle.cancel();
engine.cancelSchedule(handle.id()); // equivalent

// Query
List<ScheduleRecord> active = engine.listActiveSchedules();
List<ScheduleRecord> all = engine.listSchedules();

See Cron Scheduling for the full reference.


Shutdown​

Always close the engine to drain in-flight executions and shut down plugins cleanly:

try (NexoraEngine engine = NexoraEngine.builder()...build()) {
engine.execute(intent).join();
} // shutdown() called automatically

Or explicitly:

engine.shutdown();

Shutdown waits for all in-flight executions to complete before closing plugin class loaders and the execution store.