Java Jersey Server Sent Events

The Jersey Server Sent Events client is a java client that allows to receive events when :

  • A job status is modified
  • A job solution is found

Please refer to the documentation of the Master SSE endpoints for further details.

Installation

Maven users

Add this dependency to your project’s POM:

<dependency>
  <groupId>com.decisionbrain</groupId>
  <artifactId>optimserver-client-sse-jersey</artifactId>
  <version>PROJECT_VERSION</version>
  <scope>compile</scope>
</dependency>

Gradle users

Add this dependency to your project’s build file:

compile "com.decisionbrain:optimserver-client-sse-jersey:PROJECT_VERSION"

Getting Started


import com.decisionbrain.optimserver.client.sse.AuthenticationService;
import com.decisionbrain.optimserver.client.sse.JobEventListener;
import com.decisionbrain.optimserver.client.sse.SseListener;
import com.decisionbrain.optimserver.client.sse.config.KeycloakClientConfig;
import com.decisionbrain.optimserver.client.sse.impl.KeycloakAuthenticationServiceImpl;
import com.decisionbrain.optimserver.client.sse.jersey.config.SseJerseyConfig;
import com.decisionbrain.optimserver.master.model.JobSolution;
import com.decisionbrain.optimserver.master.model.JobStatusEvent;

import java.util.function.Consumer;

public class OptimserverSseClientApplication {

    private static final String API_URL = "https://OPTIMSERVER";
    private static final String KEYCLOAK_URL = "https://OPTIMSERVER_AUTHENTICATION/auth";
    private static final String KEYCLOAK_REALM = "decisionbrain";
    private static final String KEYCLOAK_CLIENT = "optimserver";
    private static final String KEYCLOAK_USER = "optimserver";
    private static final String KEYCLOAK_PASSWORD = "optimserver";

    public static void main(String[] args) {

        // Use the rest API to create a job and get its identifier.
        String jobId = "jobAlreadyCreatedId";

        // This is the main keycloak configuration to authenticate on your Master API.
        final KeycloakClientConfig keycloakClientConfig = KeycloakClientConfig.builder()
                                                                          .url(KEYCLOAK_URL)
                                                                          .realm(KEYCLOAK_REALM)
                                                                          .client(KEYCLOAK_CLIENT)
                                                                          .user(KEYCLOAK_USER)
                                                                          .password(KEYCLOAK_PASSWORD)
                                                                          .build();
        final AuthenticationService authenticationService = new KeycloakAuthenticationServiceImpl(keycloakClientConfig);

        // Configure the master API url and optionally the SSE reconnect time.
        final SseJerseyConfig sseJerseyConfig = SseJerseyConfig.builder().apiUrl(API_URL).reconnect(2000).build();

        // Create the listener service instance 
        final SseListener sseListener = new JerseySseListenerImpl(authenticationService, sseJerseyConfig);

        // Register a listener to the service 
        // This is an inline representation of a JobEventListener but you could also create your own implementation.
        sseListener.register(jobId, new JobEventListener() {
            @Override
            public Consumer<JobSolution> onSolution() {
                // When a job solution will be found, this method will be called
                return (jobSolution) -> System.out.println("Do whatever you want with the jobSolution");
            }

            @Override
            public Consumer<JobStatusEvent> onJobStatusEvent() {
                // When a job status will change, this method will be called
                return (jobStatusEvent) -> System.out.println("Do whatever you want with the jobStatusEvent");
            }
        });

    }
}

If you want to catch the exceptions that can occur during the job execution, you can also implement the methods ‘onSolutionError’ and ‘onJobStatusEventError’ in your JobEventListener implementation :


    sseListener.register(jobId, new JobEventListener() {
            @Override
            public Consumer<JobSolution> onSolution() {
                return (jobSolution) -> System.out.println("Do whatever you want with the jobSolution");
            }

            @Override
            public Consumer<com.decisionbrain.optimserver.master.model.JobStatusEvent> onJobStatusEvent() {
                return (jobStatusEvent) -> System.out.println("Do whatever you want with the jobStatusEvent");
            }

            @Override
            public Consumer<Throwable> onSolutionError() {
                return (exception) -> System.out.println("Do whatever you want with the Exception");
            }

            @Override
            public Consumer<Throwable> onJobStatusEventError() {
                return (exception) -> System.out.println("Do whatever you want with the Exception");
            }
        });
        

You may also want to connect to your Master API with a basic auth authentication. You can then use the following code :

        final BasicAuthConfig basicAuthConfig = BasicAuthConfig.builder().userName("user").password("password").build();

        final AuthenticationService authenticationService = new BasicAuthenticationServiceImpl(basicAuthConfig);