com.github.sseserver.remote.RemoteMessageRepository Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sse-server Show documentation
Show all versions of sse-server Show documentation
Sse server for Spring Boot
package com.github.sseserver.remote;
import com.github.sseserver.local.LocalController;
import com.github.sseserver.qos.Message;
import com.github.sseserver.qos.MessageRepository;
import com.github.sseserver.springboot.SseServerProperties;
import com.github.sseserver.util.AutoTypeBean;
import com.github.sseserver.util.CompletableFuture;
import com.github.sseserver.util.LambdaUtil;
import com.github.sseserver.util.SpringUtil;
import com.github.sseserver.util.SpringUtil.AsyncRestTemplate;
import com.github.sseserver.util.SpringUtil.HttpEntity;
import java.io.Serializable;
import java.net.URL;
import java.nio.channels.ClosedChannelException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
public class RemoteMessageRepository implements MessageRepository {
public static int connectTimeout = Integer.getInteger("sseserver.RemoteMessageRepository.connectTimeout",
500);
public static int readTimeout = Integer.getInteger("sseserver.RemoteMessageRepository.readTimeout",
1500);
public static int threadsIfAsyncRequest = Integer.getInteger("sseserver.RemoteMessageRepository.threadsIfAsyncRequest",
1);
public static int threadsIfBlockRequest = Integer.getInteger("sseserver.RemoteMessageRepository.threadsIfBlockRequest",
Math.max(16, Runtime.getRuntime().availableProcessors() * 2));
private final AsyncRestTemplate restTemplate;
private final URL url;
private final String urlMessageRepository;
private final String id;
private final SseServerProperties.ClusterConfig.MessageRepository config;
private final Set classNotFoundSet = Collections.newSetFromMap(new ConcurrentHashMap<>());
private boolean closeFlag = false;
private final boolean primary;
public RemoteMessageRepository(URL url, String account, String password, SseServerProperties.ClusterConfig.MessageRepository config, boolean primary) {
this.url = url;
this.urlMessageRepository = url + "/MessageRepository";
this.id = account;
this.config = config;
this.primary = primary;
this.restTemplate = SpringUtil.newAsyncRestTemplate(
connectTimeout, readTimeout,
threadsIfAsyncRequest, threadsIfBlockRequest,
account + "RemoteMessageRepository", account, password);
}
@Override
public boolean isPrimary() {
return primary;
}
@Override
public String insert(Message message) {
RemoteCompletableFuture future = insertAsync(message);
return future.block();
}
@Override
public List list() {
RemoteCompletableFuture, RemoteMessageRepository> future = listAsync();
return future.block();
}
@Override
public List select(Query query) {
RemoteCompletableFuture, RemoteMessageRepository> future = selectAsync(query);
return future.block();
}
@Override
public Message delete(String id) {
RemoteCompletableFuture future = deleteAsync(id);
return future.block();
}
public RemoteCompletableFuture, RemoteMessageRepository> listAsync() {
Map request = new HashMap<>(1);
return asyncPost("/list", request, this::extractListMessage);
}
public RemoteCompletableFuture insertAsync(Message message) {
Map request = new HashMap<>(8);
request.put("filters", message.getFilters());
request.put("id", message.getId());
request.put("body", message.getBody());
request.put("eventName", message.getEventName());
request.put("listenerName", message.getListenerName());
request.put("userIdList", message.getUserIdList());
request.put("tenantIdList", message.getTenantIdList());
request.put("accessTokenList", message.getAccessTokenList());
request.put("channelList", message.getChannelList());
return asyncPost("/insert", request, this::extract);
}
public RemoteCompletableFuture, RemoteMessageRepository> selectAsync(Query query) {
Map request = new HashMap<>(6);
request.put("tenantId", query.getTenantId());
request.put("channel", query.getChannel());
request.put("accessToken", query.getAccessToken());
request.put("userId", query.getUserId());
request.put("listeners", query.getListeners());
return asyncPost("/select", request, this::extractListMessage);
}
public RemoteCompletableFuture deleteAsync(String id) {
Map request = new HashMap<>(1);
request.put("id", id);
return asyncPost("/delete", request, entity -> {
Map data = (Map) entity.getBody().getData();
return buildMessage(data);
});
}
@Override
public void close() {
restTemplate.close();
this.closeFlag = true;
}
@Override
public void addDeleteListener(Consumer listener) {
throw new UnsupportedOperationException("public void addDeleteListener(Consumer listener)");
}
protected RemoteCompletableFuture asyncPost(String url,
Object request,
Function, T> extract) {
checkClose();
CompletableFuture> future = restTemplate.postForEntity(
urlMessageRepository + url, request, LocalController.Response.class);
return completable(future, extract);
}
protected RemoteCompletableFuture completable(
CompletableFuture> future,
Function, T> extract) {
RemoteCompletableFuture result = new RemoteCompletableFuture<>();
result.setClient(this);
future.whenComplete((response, throwable) -> {
if (throwable != null) {
result.completeExceptionally(throwable);
} else {
T data;
try {
data = extract.apply(response);
} catch (Throwable e) {
result.completeExceptionally(e);
return;
}
result.complete(data);
}
});
return result;
}
protected T extract(HttpEntity response) {
LocalController.Response body = response.getBody();
try {
return AutoTypeBean.cast(body.getData(),
body.getArrayClassName(), body.getObjectClassName(),
config.getAutoType(), classNotFoundSet);
} catch (ClassNotFoundException e) {
LambdaUtil.sneakyThrows(e);
return null;
}
}
protected List extractListMessage(HttpEntity response) {
List