Repository: open-telemetry/opentelemetry-java
File: api/incubator/src/main/java/io/opentelemetry/api/incubator/config/ConfigProvider.java (Java)

Code before:
 *
 * <p>See {@link InstrumentationConfigUtil} for convenience methods for extracting config from
 * {@link ConfigProvider}.
 */
@ThreadSafe
public interface ConfigProvider {

  /**
   * Returns the {@link DeclarativeConfigProperties} corresponding to <a
   * href="https://github.com/open-telemetry/opentelemetry-configuration/blob/main/schema/instrumentation.json">instrumentation
   * config</a>, or {@code null} if unavailable.
   *
   * @return the instrumentation {@link DeclarativeConfigProperties}
   */
  @Nullable
  DeclarativeConfigProperties getInstrumentationConfig();

  /**
   * Returns the {@link DeclarativeConfigProperties} for a specific instrumentation by name. If no
   * configuration is available for the given name, an empty {@link DeclarativeConfigProperties} is
   * returned.
   *
   * @param name the name of the instrumentation
   * @return the {@link DeclarativeConfigProperties} for the given instrumentation name
   */
  default DeclarativeConfigProperties get(String name) {
    DeclarativeConfigProperties config = getInstrumentationConfig();
    if (config == null) {
      return empty();
    }
    return config.getStructured("java", empty()).getStructured(name, empty());
  }

  /** Returns a no-op {@link ConfigProvider}. */
  static ConfigProvider noop() {
    return () -> null;
  }
}


Review comment (refactor):
I'm a bit worried that if `ConfigProvider` is expanded in the future to have other functions, it won't be clear that `get` is sugar for `getInstrumentationConfig`.

Can remove this risk with naming `getJavaInstrumentationConfig(String name)`, which I think is more clear that this method is about accessing a particular java instrumentation library's config.

Looking at this, I wonder if we should scrap #7920 in favor of an approach like this PR @trask.

This approach is a bit of a "have your cake and eat it to", since it still allows users to determine if `.instrumentation/development` was set, but provides syntactic sugar for the common case where you don't actually care. 

Code after:
 */
@ThreadSafe
public interface ConfigProvider {

  /**
   * Returns the {@link DeclarativeConfigProperties} corresponding to <a
   * href="https://github.com/open-telemetry/opentelemetry-configuration/blob/main/schema/instrumentation.json">instrumentation
   * config</a>, or {@link DeclarativeConfigProperties#empty()} if unavailable.
   *
   * @return the instrumentation {@link DeclarativeConfigProperties}
   */
  DeclarativeConfigProperties getInstrumentationConfig();

  /**
   * Returns the {@link DeclarativeConfigProperties} for a specific instrumentation by name. If no
   * configuration is available for the given name, an empty {@link DeclarativeConfigProperties} is
   * returned.
   *
   * <p>For example, {@code getInstrumentationConfig("foo")} returns the node:
   *
   * <pre>{@code
   * instrumentation/development:
   *   java:
   *     foo:
   * }</pre>
   *
   * @param name the name of the instrumentation
   * @return the {@link DeclarativeConfigProperties} for the given instrumentation name
   */
  default DeclarativeConfigProperties getInstrumentationConfig(String name) {
    return getInstrumentationConfig().get("java").get(name);
  }

  /**
   * Returns the {@link DeclarativeConfigProperties} for general instrumentation configuration.
   *
   * <pre>{@code
   * instrumentation/development:
   *   general:
   * }</pre>
   *
   * <p>If the general configuration is not available, an empty {@link DeclarativeConfigProperties}
   * is returned.
   *
   * @return the {@link DeclarativeConfigProperties} for the general instrumentation configuration
   */
  default DeclarativeConfigProperties getGeneralInstrumentationConfig() {
    return getInstrumentationConfig().get("general");
  }

  /** Returns a no-op {@link ConfigProvider}. */