
org.zodiac.ds.api.switcher.DefaultReactiveSwitcher Maven / Gradle / Ivy
package org.zodiac.ds.api.switcher;
import org.reactivestreams.Publisher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zodiac.reactor.context.ReactorContextUtil;
import org.zodiac.sdk.toolkit.context.ContextKey;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.Collection;
import java.util.Deque;
import java.util.LinkedList;
import java.util.function.Consumer;
import java.util.function.Function;
public class DefaultReactiveSwitcher implements ReactiveSwitcher {
protected Logger log = LoggerFactory.getLogger(getClass());
private String name;
private String defaultId;
private String type;
public DefaultReactiveSwitcher(String name,String type) {
this.name = "ReactiveSwitcher.".concat(name);
this.defaultId = name.concat(".").concat("_default");
this.type=type;
}
private Mono doInContext(Function, Mono> function) {
return ReactorContextUtil.reactiveContext()
.map(ctx -> ctx.getOrDefault(ContextKey.>of(this.name), LinkedList::new))
.flatMap(function);
}
@SuppressWarnings("all")
private > R doInContext(R publisher, Consumer> consumer) {
if (publisher instanceof Mono) {
return (R)((Mono>) publisher)
.subscriberContext(ReactorContextUtil.acceptContext(ctx -> {
consumer.accept(ctx.getOrDefault(ContextKey.>of(this.name), LinkedList::new));
}));
} else if (publisher instanceof Flux) {
return (R)((Flux>) publisher)
.subscriberContext(ReactorContextUtil.acceptContext(ctx -> {
consumer.accept(ctx.getOrDefault(ContextKey.>of(this.name), LinkedList::new));
}));
}
return publisher;
}
@Override
public > P useLast(P publisher) {
return doInContext(publisher,queue -> {
/*Not last time.*/
if (queue.isEmpty()) {
return;
}
/*If you remove the tail of the queue, the current tail of the queue is the last configuration used.*/
queue.removeLast();
});
}
@Override
public
> P use(P publisher, String id) {
return doInContext(publisher,queue-> queue.addLast(id));
}
@Override
public
> P useDefault(P publisher) {
return use(publisher,defaultId);
}
@Override
public
> P reset(P publisher) {
return doInContext(publisher, Collection::clear);
}
@Override
public Mono current() {
return doInContext(queue -> {
if (queue.isEmpty()) {
return Mono.empty();
}
String activeId = queue.getLast();
if (defaultId.equals(activeId)) {
return Mono.empty();
}
return Mono.just(activeId);
});
}
}