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

io.opentelemetry.exporter.sender.jdk.internal.BodyPublisher Maven / Gradle / Ivy

There is a newer version: 1.42.1
Show newest version
/*
 * Copyright The OpenTelemetry Authors
 * SPDX-License-Identifier: Apache-2.0
 */

package io.opentelemetry.exporter.sender.jdk.internal;

import java.net.http.HttpRequest;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Flow;
import java.util.function.Supplier;

final class BodyPublisher implements HttpRequest.BodyPublisher {

  private final int length;
  private final byte[] content;
  private final Supplier bufSupplier;

  BodyPublisher(byte[] content, int length, Supplier bufSupplier) {
    this.content = content;
    this.length = length;
    this.bufSupplier = bufSupplier;
  }

  private List copyToBuffers() {
    int offset = 0;
    int length = this.length;

    List buffers = new ArrayList<>();
    while (length > 0) {
      ByteBuffer b = bufSupplier.get();
      b.clear();
      int lengthToCopy = Math.min(b.capacity(), length);
      b.put(content, offset, lengthToCopy);
      offset += lengthToCopy;
      length -= lengthToCopy;
      b.flip();
      buffers.add(b);
    }
    return buffers;
  }

  @Override
  public long contentLength() {
    return length;
  }

  @Override
  public void subscribe(Flow.Subscriber subscriber) {
    Subscription subscription = new Subscription(copyToBuffers(), subscriber);
    subscriber.onSubscribe(subscription);
  }

  private static class Subscription implements Flow.Subscription {

    private volatile boolean isCompleted;
    private final List buffers;
    private final Flow.Subscriber subscriber;

    private int offset = 0;

    private Subscription(List buffers, Flow.Subscriber subscriber) {
      this.buffers = buffers;
      this.subscriber = subscriber;
    }

    @Override
    public void request(long n) {
      if (isCompleted) {
        return;
      }
      if (n <= 0) {
        subscriber.onError(new IllegalArgumentException("Subscription request must be >= 0"));
        isCompleted = true;
      } else {
        run(n);
      }
    }

    @Override
    public void cancel() {
      isCompleted = true;
    }

    private synchronized void run(long requestedItems) {
      if (isCompleted) {
        return;
      }

      long count = 0;
      ByteBuffer next;
      while (count < requestedItems) {
        int nextIndex = offset++;
        if (nextIndex >= buffers.size()) {
          break;
        }
        next = buffers.get(nextIndex);
        subscriber.onNext(next);
        count++;
      }
      if (offset >= buffers.size()) {
        isCompleted = true;
        subscriber.onComplete();
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy