All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.yamcs.client.base.AbstractSubscription Maven / Gradle / Ivy

There is a newer version: 5.10.8
Show newest version
package org.yamcs.client.base;

import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.yamcs.api.MethodHandler;
import org.yamcs.api.Observer;
import org.yamcs.client.MessageListener;
import org.yamcs.client.Subscription;

import com.google.protobuf.Message;

/**
 * Default base class for a {@link Subscription}.
 * 

* This is designed such that most subclasses need only to provide type information. More advanced subscription * subclasses may want to add custom functionality such as call-specific message processing. */ public abstract class AbstractSubscription implements Subscription { // A future that resolves when the call is confirmed by the server // A call is confirmed when the server has assigned it an id (upon first message) private CompletableFuture confirmationFuture = new CompletableFuture<>(); // A future that resolves when the call is completed private CompletableFuture wrappedFuture = new CompletableFuture<>(); protected Observer clientObserver; private Set> messageListeners = new CopyOnWriteArraySet<>(); protected AbstractSubscription(MethodHandler methodHandler, String topic, Class responseClass) { WebSocketClient client = ((HttpMethodHandler) methodHandler).getWebSocketClient(); clientObserver = client.call(topic, new DataObserver() { @Override public void confirm() { confirmationFuture.complete(null); } @Override public void next(S message) { messageListeners.forEach(l -> l.onMessage(message)); } @Override public void completeExceptionally(Throwable t) { messageListeners.forEach(l -> l.onError(t)); wrappedFuture.completeExceptionally(t); } @Override public void complete() { wrappedFuture.complete(null); } @Override public Class getMessageClass() { return responseClass; } }); } /** * Send a message (typically a subscription request) to Yamcs */ @Override public void sendMessage(C message) { clientObserver.next(message); } /** * Get updated on received server messages. */ @Override public void addMessageListener(MessageListener listener) { messageListeners.add(listener); } /** * Cancel this subscription. After this method is called, you will no longer receive any messages from it. */ @Override public boolean cancel(boolean mayInterruptIfRunning) { messageListeners.clear(); // Immediately ensure nobody will receive anything anymore clientObserver.complete(); // Now notify Yamcs async. return true; } public CompletableFuture getConfirmationFuture() { return confirmationFuture; } /** * Waits until the server has confirmed the call for this subscription. Only the first client message of a call is * confirmed. */ public void awaitConfirmation() throws InterruptedException, ExecutionException { confirmationFuture.get(); } /** * Waits until the server has confirmed the call for this subscription. Only the first client message of a call is * confirmed. */ public void awaitConfirmation(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { confirmationFuture.get(timeout, unit); } @Override public boolean isCancelled() { return wrappedFuture.isCancelled(); } @Override public boolean isDone() { return wrappedFuture.isDone(); } @Override public Void get() throws InterruptedException, ExecutionException { return wrappedFuture.get(); } @Override public Void get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return wrappedFuture.get(timeout, unit); } }