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

com.rollbar.reactivestreams.notifier.sender.AsyncSender Maven / Gradle / Ivy

package com.rollbar.reactivestreams.notifier.sender;

import com.rollbar.api.payload.Payload;
import com.rollbar.notifier.sender.SyncSender;
import com.rollbar.notifier.sender.json.JsonSerializer;
import com.rollbar.notifier.sender.json.JsonSerializerImpl;
import com.rollbar.notifier.sender.result.Response;
import com.rollbar.notifier.sender.result.Result;
import com.rollbar.reactivestreams.Utils;
import com.rollbar.reactivestreams.notifier.sender.http.AsyncHttpClient;
import com.rollbar.reactivestreams.notifier.sender.http.AsyncHttpRequest;
import com.rollbar.reactivestreams.notifier.sender.http.AsyncHttpResponse;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.LinkedHashMap;
import org.reactivestreams.Publisher;

/**
 * Asynchronous, non-blocking sender based on the Reactive Streams specification.
 */
public class AsyncSender implements Sender {
  private final AsyncHttpClient httpClient;
  private final String url;
  private final JsonSerializer jsonSerializer;
  private final String accessToken;

  AsyncSender(Builder builder) {
    this.httpClient = builder.httpClient;
    this.url = builder.url.toExternalForm();
    this.jsonSerializer = builder.jsonSerializer;
    this.accessToken = builder.accessToken;
  }

  /**
   * Sends the payload.
   *
   * @param payload the payload.
   * @return A {@link Publisher} that will execute the operation once a subscriber requests it.
   */
  @Override
  public Publisher send(Payload payload) {
    LinkedHashMap headers = new LinkedHashMap<>();

    if (accessToken != null && !"".equals(accessToken)) {
      headers.put("x-rollbar-access-token", accessToken);
    }

    headers.put("Accept-Charset", SyncSender.UTF_8);
    headers.put("Content-Type", "application/json; charset=" + SyncSender.UTF_8);
    headers.put("Accept", "application/json");

    String reqBody = jsonSerializer.toJson(payload);

    AsyncHttpRequest request =
        AsyncHttpRequest.Builder.build(this.url, headers.entrySet(), reqBody);

    return Utils.map(httpClient.send(request),
        new Utils.Converter() {
          @Override
          public Response convert(AsyncHttpResponse from) {
            Result result = jsonSerializer.resultFrom(from.getBody());
            return new Response.Builder().result(result).status(from.getStatusCode()).build();
          }
        });
  }

  @Override
  public void close(boolean wait) {
    httpClient.close(wait);
  }

  @Override
  public void close() throws Exception {
    httpClient.close();
  }

  /**
   * Builder class for {@link AsyncSender}.
   */
  public static class Builder {
    private final AsyncHttpClient httpClient;
    private URL url;
    private JsonSerializer jsonSerializer;
    private String accessToken;

    /**
     * Constructor.
     *
     * @param httpClient The async HTTP client to use.
     */
    public Builder(AsyncHttpClient httpClient) {
      this(httpClient, SyncSender.DEFAULT_API_ENDPOINT);
    }

    /**
     * Constructor.
     *
     * @param httpClient The async HTTP client to use.
     * @param url the url.
     */
    public Builder(AsyncHttpClient httpClient, String url) {
      this.httpClient = httpClient;
      this.url = parseUrl(url);
      this.jsonSerializer = new JsonSerializerImpl();
    }

    /**
     * The url as string.
     *
     * @param url the url.
     * @return the builder instance.
     */
    public Builder url(String url) {
      this.url = parseUrl(url);
      return this;
    }

    /**
     * The url as {@link URL}.
     *
     * @param url the url.
     * @return the builder instance.
     */
    public Builder url(URL url) {
      this.url = url;
      return this;
    }

    /**
     * The {@link JsonSerializer json serializer}.
     *
     * @param jsonSerializer the json serializer.
     * @return the builder instance.
     */
    public Builder jsonSerializer(JsonSerializer jsonSerializer) {
      this.jsonSerializer = jsonSerializer;
      return this;
    }

    /**
     * The rollbar access token.
     *
     * @param accessToken the access token.
     * @return the builder instance.
     */
    public Builder accessToken(String accessToken) {
      this.accessToken = accessToken;
      return this;
    }

    /**
     * Builds the {@link AsyncSender} async sender.
     *
     * @return the async sender.
     */
    public AsyncSender build() {
      return new AsyncSender(this);
    }

    /**
     * Builds a {@link Sender} that will execute all operations in fire-and-forget mode.
     * 

* All calls are delegated to an async sender, so this provides a quick migration path if * an application is using non-blocking IO but is currently calling the synchronous * {@link com.rollbar.notifier.Rollbar} methods. *

*

* Note that the registered {@link com.rollbar.notifier.sender.listener.SenderListener} * listeners will still be called, and if they perform blocking IO they might cause severe * performance degradation for the non-blocking IO environment. *

* * @return the sync sender. */ public com.rollbar.notifier.sender.Sender buildSync() { return new SyncSenderWrapper(this); } private static URL parseUrl(String url) { try { return new URL(url); } catch (MalformedURLException e) { throw new IllegalArgumentException("The url provided is not valid: " + url, e); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy