content: /*
   * Copyright The OpenTelemetry Authors
   * SPDX-License-Identifier: Apache-2.0
   */
  
  package io.opentelemetry.instrumentation.testing.junit.http;
  
  import static io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerUsingTest.TEST_CLIENT_IP;
  import static io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerUsingTest.TEST_USER_AGENT;
  
  import io.opentelemetry.instrumentation.test.utils.PortUtils;
  import io.opentelemetry.instrumentation.testing.AgentTestRunner;
  import io.opentelemetry.instrumentation.testing.InstrumentationTestRunner;
  import io.opentelemetry.instrumentation.testing.LibraryTestRunner;
  import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
  import io.opentelemetry.testing.internal.armeria.client.ClientFactory;
  import io.opentelemetry.testing.internal.armeria.client.WebClient;
  import io.opentelemetry.testing.internal.armeria.client.logging.LoggingClient;
  import io.opentelemetry.testing.internal.armeria.common.HttpHeaderNames;
  import java.time.Duration;
  import org.junit.jupiter.api.extension.ExtensionContext;
  
  /**
   * A {@link InstrumentationExtension} which sets up infrastructure, such as a test HTTP client, for
   * {@link AbstractHttpServerUsingTest}.
   */
  public final class HttpServerInstrumentationExtension extends InstrumentationExtension {
  
    /**
     * Returns a {@link InstrumentationExtension} to be used with {@link AbstractHttpClientTest} for
     * javaagent instrumentation.
     */
    public static InstrumentationExtension forAgent() {
      return new HttpServerInstrumentationExtension(AgentTestRunner.instance());
    }
  
    /**
     * Returns a {@link InstrumentationExtension} to be used with {@link AbstractHttpClientTest} for
     * library instrumentation.
     */
    public static InstrumentationExtension forLibrary() {
      return new HttpServerInstrumentationExtension(LibraryTestRunner.instance());
    }
  
    private final int port;
    private final WebClient client;
  
    private HttpServerInstrumentationExtension(InstrumentationTestRunner runner) {
      super(runner);
  
      port = PortUtils.findOpenPort();
      client =
          WebClient.builder()
              .responseTimeout(Duration.ofMinutes(1))
              .writeTimeout(Duration.ofMinutes(1))
              .factory(ClientFactory.builder().connectTimeout(Duration.ofMinutes(1)).build())
              .setHeader(HttpHeaderNames.USER_AGENT, TEST_USER_AGENT)
              .setHeader(HttpHeaderNames.X_FORWARDED_FOR, TEST_CLIENT_IP)
              .decorator(LoggingClient.newDecorator())
              .build();
    }
  
    @Override
    public void beforeAll(ExtensionContext extensionContext) throws Exception {
      super.beforeAll(extensionContext);
      Object testInstance = extensionContext.getRequiredTestInstance();
  
      if (!(testInstance instanceof AbstractHttpServerUsingTest)) {
        throw new AssertionError(
            "HttpServerInstrumentationExtension can only be applied to a subclass of "
                + "AbstractHttpServerUsingTest");
      }
  
      ((AbstractHttpServerUsingTest) testInstance).setTesting(getTestRunner(), client, port);
    }
  }
  