io.fluxcapacitor.javaclient.FluxCapacitor Maven / Gradle / Ivy
Show all versions of java-client Show documentation
package io.fluxcapacitor.javaclient;
import io.fluxcapacitor.common.MessageType;
import io.fluxcapacitor.common.Registration;
import io.fluxcapacitor.common.api.Metadata;
import io.fluxcapacitor.javaclient.common.model.Model;
import io.fluxcapacitor.javaclient.configuration.DefaultFluxCapacitor;
import io.fluxcapacitor.javaclient.configuration.client.Client;
import io.fluxcapacitor.javaclient.eventsourcing.EventSourced;
import io.fluxcapacitor.javaclient.eventsourcing.EventSourcing;
import io.fluxcapacitor.javaclient.keyvalue.KeyValueStore;
import io.fluxcapacitor.javaclient.publishing.CommandGateway;
import io.fluxcapacitor.javaclient.publishing.ErrorGateway;
import io.fluxcapacitor.javaclient.publishing.EventGateway;
import io.fluxcapacitor.javaclient.publishing.MetricsGateway;
import io.fluxcapacitor.javaclient.publishing.QueryGateway;
import io.fluxcapacitor.javaclient.publishing.ResultGateway;
import io.fluxcapacitor.javaclient.scheduling.Scheduler;
import io.fluxcapacitor.javaclient.tracking.Tracking;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream;
import static java.util.Arrays.stream;
/**
* High-level client API for Flux Capacitor. If you are using anything other than this to interact with the service
* at runtime you're probably doing it wrong.
*
* To start handling messages build an instance of this API and invoke {@link #startTracking}.
*
* Once you are handling messages you can simply use the static methods provided (e.g. to publish messages etc).
* In those cases it is not necessary to inject an instance of this API. This minimizes the need for dependencies
* in your functional classes and maximally cashes in on location transparency.
*
* To build an instance of this API check out {@link DefaultFluxCapacitor}.
*/
public interface FluxCapacitor {
ThreadLocal instance = new ThreadLocal<>();
static FluxCapacitor get() {
return Optional.ofNullable(instance.get())
.orElseThrow(() -> new IllegalStateException("FluxCapacitor instance not set"));
}
static void publishEvent(Object event) {
get().eventGateway().publish(event);
}
static void publishEvent(Object payload, Metadata metadata) {
get().eventGateway().publish(payload, metadata);
}
static void sendAndForgetCommand(Object payload, Metadata metadata) {
get().commandGateway().sendAndForget(payload, metadata);
}
static void sendAndForgetCommand(Object command) {
get().commandGateway().sendAndForget(command, Metadata.empty());
}
static CompletableFuture sendCommand(Object payload, Metadata metadata) {
return get().commandGateway().send(payload, metadata);
}
static CompletableFuture sendCommand(Object command) {
return get().commandGateway().send(command, Metadata.empty());
}
static CompletableFuture query(Object query) {
return get().queryGateway().send(query);
}
static CompletableFuture query(Object payload, Metadata metadata) {
return get().queryGateway().send(payload, metadata);
}
static void publishMetrics(Object metrics) {
get().metricsGateway().publish(metrics);
}
static void publishMetrics(Object payload, Metadata metadata) {
get().metricsGateway().publish(payload, metadata);
}
static Model loadAggregate(String id, Class modelType) {
if (modelType.isAnnotationPresent(EventSourced.class)) {
return get().eventSourcing().load(id, modelType);
}
throw new UnsupportedOperationException("Only event sourced aggregates are supported at the moment");
}
default Registration startTracking(Object... handlers) {
return startTracking(Arrays.asList(handlers));
}
@SuppressWarnings("ConstantConditions")
default Registration startTracking(List> handlers) {
return stream(MessageType.values())
.map(t -> tracking(t).start(this, handlers)).reduce(Registration::merge).get();
}
default Registration registerLocalHandlers(Object... handlers) {
return registerLocalHandlers(Arrays.asList(handlers));
}
default Registration registerLocalHandlers(List> handlers) {
return handlers.stream().flatMap(h -> Stream
.of(commandGateway().registerLocalHandler(h), queryGateway().registerLocalHandler(h),
eventGateway().registerLocalHandler(h))).reduce(Registration::merge).orElse(Registration.noOp());
}
EventSourcing eventSourcing();
Scheduler scheduler();
KeyValueStore keyValueStore();
CommandGateway commandGateway();
QueryGateway queryGateway();
EventGateway eventGateway();
ResultGateway resultGateway();
ErrorGateway errorGateway();
MetricsGateway metricsGateway();
Tracking tracking(MessageType messageType);
Client client();
}