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

io.scalecube.services.gateway.rsocket.RSocketGatewayAcceptor Maven / Gradle / Ivy

package io.scalecube.services.gateway.rsocket;

import io.rsocket.AbstractRSocket;
import io.rsocket.ConnectionSetupPayload;
import io.rsocket.Payload;
import io.rsocket.RSocket;
import io.rsocket.SocketAcceptor;
import io.rsocket.util.ByteBufPayload;
import io.scalecube.services.ServiceCall;
import io.scalecube.services.api.ServiceMessage;
import io.scalecube.services.gateway.GatewayMetrics;
import io.scalecube.services.transport.api.HeadersCodec;
import io.scalecube.services.transport.api.ServiceMessageCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

public class RSocketGatewayAcceptor implements SocketAcceptor {

  private static final Logger LOGGER = LoggerFactory.getLogger(RSocketGatewayAcceptor.class);

  private final ServiceCall serviceCall;
  private final GatewayMetrics metrics;

  public RSocketGatewayAcceptor(ServiceCall serviceCall, GatewayMetrics metrics) {
    this.serviceCall = serviceCall;
    this.metrics = metrics;
  }

  @Override
  public Mono accept(ConnectionSetupPayload setup, RSocket rsocket) {
    LOGGER.info("Accepted rsocket websocket: {}, connectionSetup: {}", rsocket, setup);

    rsocket
        .onClose()
        .doOnTerminate(() -> LOGGER.info("Client disconnected: {}", rsocket))
        .subscribe(null, th -> LOGGER.error("Exception on closing rsocket: {}", th));

    // Prepare message codec together with headers from metainfo
    HeadersCodec headersCodec = HeadersCodec.getInstance(setup.metadataMimeType());
    ServiceMessageCodec messageCodec = new ServiceMessageCodec(headersCodec);

    return Mono.just(new GatewayRSocket(serviceCall, metrics, messageCodec));
  }

  /**
   * Private extension class for rsocket. Holds gateway business logic in following methods: {@link
   * #fireAndForget(Payload)}, {@link #requestResponse(Payload)}, {@link #requestStream(Payload)}
   * and {@link #requestChannel(org.reactivestreams.Publisher)}.
   */
  private static class GatewayRSocket extends AbstractRSocket {

    private final ServiceCall serviceCall;
    private final GatewayMetrics metrics;
    private final ServiceMessageCodec messageCodec;

    /**
     * Constructor for gateway rsocket.
     *
     * @param serviceCall service call coming from microservices.
     * @param metrics gateway metrics.
     * @param messageCodec message messageCodec.
     */
    private GatewayRSocket(
        ServiceCall serviceCall, GatewayMetrics metrics, ServiceMessageCodec messageCodec) {
      this.serviceCall = serviceCall;
      this.metrics = metrics;
      this.messageCodec = messageCodec;
    }

    @Override
    public Mono fireAndForget(Payload payload) {
      return Mono.defer(
          () -> {
            metrics.markRequest();
            return serviceCall.oneWay(toMessage(payload));
          });
    }

    @Override
    public Mono requestResponse(Payload payload) {
      return Mono.defer(
          () -> {
            metrics.markRequest();
            return serviceCall
                .requestOne(toMessage(payload))
                .map(this::toPayload)
                .doOnNext(payload1 -> metrics.markServiceResponse());
          });
    }

    @Override
    public Flux requestStream(Payload payload) {
      return Flux.defer(
          () -> {
            metrics.markRequest();
            return serviceCall
                .requestMany(toMessage(payload))
                .map(this::toPayload)
                .doOnNext(payload1 -> metrics.markServiceResponse());
          });
    }

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

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




© 2015 - 2025 Weber Informatics LLC | Privacy Policy