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

io.scalecube.services.transport.rsocket.RSocketServiceClientAdapter Maven / Gradle / Ivy

package io.scalecube.services.transport.rsocket;

import io.rsocket.Payload;
import io.rsocket.RSocket;
import io.rsocket.util.ByteBufPayload;
import io.scalecube.services.api.ServiceMessage;
import io.scalecube.services.exceptions.ConnectionClosedException;
import io.scalecube.services.transport.api.ClientChannel;
import io.scalecube.services.transport.api.ServiceMessageCodec;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

public class RSocketServiceClientAdapter implements ClientChannel {

  private Mono rsocket;
  private ServiceMessageCodec messageCodec;

  public RSocketServiceClientAdapter(Mono rsocket, ServiceMessageCodec codec) {
    this.rsocket = rsocket;
    this.messageCodec = codec;
  }

  @Override
  public Mono requestResponse(ServiceMessage message) {
    return rsocket
        .flatMap(
            rsocket ->
                rsocket
                    .requestResponse(toPayload(message))
                    .takeUntilOther(listenConnectionClose(rsocket)))
        .map(this::toMessage);
  }

  @Override
  public Flux requestStream(ServiceMessage message) {
    return rsocket
        .flatMapMany(
            rsocket ->
                rsocket
                    .requestStream(toPayload(message))
                    .takeUntilOther(listenConnectionClose(rsocket)))
        .map(this::toMessage);
  }

  @Override
  public Flux requestChannel(Publisher publisher) {
    return rsocket
        .flatMapMany(
            rsocket ->
                rsocket
                    .requestChannel(Flux.from(publisher).map(this::toPayload))
                    .takeUntilOther(listenConnectionClose(rsocket)))
        .map(this::toMessage);
  }

  private Payload toPayload(ServiceMessage request) {
    return messageCodec.encodeAndTransform(request, ByteBufPayload::create);
  }

  private ServiceMessage toMessage(Payload payload) {
    return messageCodec.decode(payload.sliceData(), payload.sliceMetadata());
  }

  @SuppressWarnings("unchecked")
  private  Mono listenConnectionClose(RSocket rsocket) {
    return rsocket
        .onClose()
        .map(empty -> (T) empty)
        .switchIfEmpty(Mono.defer(this::toConnectionClosedException));
  }

  private  Mono toConnectionClosedException() {
    return Mono.error(new ConnectionClosedException("Connection closed"));
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy