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

io.scalecube.services.transport.rsocket.RSocketClientChannel 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 java.lang.reflect.Type;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.netty.channel.AbortedException;

public class RSocketClientChannel implements ClientChannel {

  private final Mono promise;
  private final ServiceMessageCodec messageCodec;

  public RSocketClientChannel(Mono promise, ServiceMessageCodec codec) {
    this.promise = promise;
    this.messageCodec = codec;
  }

  @Override
  public Mono requestResponse(ServiceMessage message, Type responseType) {
    return promise
        .flatMap(rsocket -> rsocket.requestResponse(toPayload(message)))
        .map(this::toMessage)
        .map(msg -> ServiceMessageCodec.decodeData(msg, responseType))
        .onErrorMap(RSocketClientChannel::mapConnectionAborted);
  }

  @Override
  public Flux requestStream(ServiceMessage message, Type responseType) {
    return promise
        .flatMapMany(rsocket -> rsocket.requestStream(toPayload(message)))
        .map(this::toMessage)
        .map(msg -> ServiceMessageCodec.decodeData(msg, responseType))
        .onErrorMap(RSocketClientChannel::mapConnectionAborted);
  }

  @Override
  public Flux requestChannel(
      Publisher publisher, Type responseType) {
    return promise
        .flatMapMany(rsocket -> rsocket.requestChannel(Flux.from(publisher).map(this::toPayload)))
        .map(this::toMessage)
        .map(msg -> ServiceMessageCodec.decodeData(msg, responseType))
        .onErrorMap(RSocketClientChannel::mapConnectionAborted);
  }

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

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

  private static Throwable mapConnectionAborted(Throwable t) {
    return AbortedException.isConnectionReset(t) || ConnectionClosedException.isConnectionClosed(t)
        ? new ConnectionClosedException(t)
        : t;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy