Two kinds of java clients are given.
First, Java clients to call the synchronous APIs.
Let us note that many other clients can be generated using the given OpenAPI file, including clients for other HTTP libraries, or even other languages.
The asynchronous API enables listening to job events emitted by Optimization Server. All these events are relative to a job posted on Optimization Server.
They can be:
The asynchronous API is described by the following interfaces:
public interface JobExecutionAsyncApi {
CompletionStage<JobSolution> getJobSolution(String jobId, Duration timeout);
JobEventSource getJobEventSource(JobSubscriptionFilter filter);
}
public interface JobExecutionSharedAsyncApi {
JobEventSource getSharedJobEventSource(String subscriptionId);
}
public class JobSubscriptionFilter {
private String jobId;
}
public interface JobEventSource extends ConnectableEventSource {
CompletionStage<JobSolution> jobSolution();
Flow.Publisher<JobStatusEvent> statusEvents();
Flow.Publisher<KpiEvent> kpiEvents();
Flow.Publisher<ProgressEvent> progressEvents();
Flow.Publisher<LogEvent> logEvents();
}
public interface ConnectableEventSource {
void connect();
void disconnect();
}
The client program has to :
connect
to tell the source to start emitting.Here is a pseudo-code snippet that outlines these 3 steps:
import com.decisionbrain.optimserver.client.java.ApiException;
import com.decisionbrain.optimserver.client.java.async.api.ConsumerSubscriber;
import com.decisionbrain.optimserver.client.java.async.api.JobEventSource;
import com.decisionbrain.optimserver.client.java.async.api.JobExecutionAsyncApi;
import com.decisionbrain.optimserver.client.java.async.api.JobSubscriptionFilter;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.CompletableFuture;
public class RunningJobListener {
private final JobExecutionAsyncApi jobExecutionAsyncApi;
public void onApplicationReady() {
String jobId = "theJobToListen";
CompletableFuture<Void> onComplete = new CompletableFuture<>();
onComplete.whenComplete((v, e) ->
LOGGER.info("The flow of events for this job is finished"));
JobEventSource eventSource = jobExecutionAsyncApi.getJobEventSource(
new JobSubscriptionFilter(jobId)
);
eventSource.statusEvents().subscribe(new ConsumerSubscriber<>(
onComplete,
jobStatusEvent ->
LOGGER.info(String.format("[STATUS]: %s", jobStatusEvent.getStatus().name()))
));
eventSource.connect();
jobExecutionAsyncApi.getJobSolution(jobDefinition.getId(), Duration.ofSeconds(3))
.whenComplete((jobSolution, throwable) -> {
if (jobSolution != null) {
LOGGER.info("Solution retrieved before timeout");
}
if (throwable != null) {
LOGGER.error("Exception while waiting for solution", throwable);
}
});
}
}
To learn more, you can read the javadoc in this page
An event source bound to one job
As shown in the example above, the JobEventSource emits all the events of the job identified by the id filled in the JobSubscriptionFilter .
All the events are relative to this job and this job only.
An event source bound to all jobs
A JobEventSource can also emits all the events of all the jobs. To achieve this, no job id should be supplied to the JobSubscriptionFilter .
An shared event source
A JobEventSource can be shared among several clients, where each alternatively receives a message.
Example: if 2 clients share a same a JobEventSource that emits e1 and e2, one receives e1 (but not e2) and the other receives e2 (but not e1).
This source can be retrieved by calling the JobExecutionSharedAsyncApi.getSharedJobEventSource()
method.
Optimization Server provides 3 clients that comply with this API
Not every implementation supplies the features described above
Implementation | One job event source | All jobs event source | Shared event source |
---|---|---|---|
Spring AMPQ | Yes | Yes | Yes |
Jersey SSE | Yes | No | No |
Spring SSE | Yes | No | No |
Optimization Server also provides 2 additional clients that support the STOMP Protocol which have not been migrated yet to comply with the API.
These clients are not generated. This list may be extended in the future to support other protocols.