Skip to content

ApiFeatures does not support setting via ENV vars #2506

Description

@amorton

API features enum looks like this:

public enum ApiFeature {

  LEXICAL("lexical", true),

  RERANKING("reranking", false),

  BILLING_EVENTS_LOGGING("billing-events-logging", false);
}

So to set things like the lexical and reranking we can set an ENV var like this:

export STARGATE_FEATURE_FLAGS_LEXICAL=true

Which is merged into this config interface

@ConfigMapping(prefix = "stargate.feature")
public interface FeaturesConfig {
  // Quarkus/SmallRye Config won't accept use of `null` values, so we must bind
  // as Strings and only convert to Boolean when needed.
  Map<ApiFeature, String> flags();
}

the "LEIXCAL" at the end of the env var is used to get the name "LEXICAL" from the enum.

But when there is "_" in the enum name, SmallRy turns this into dotted notation "billing.events.logging" while the converter from the name to the enum values wants billing-events-logging. While ENV vars can contain neither.

This means we are setting feature flags in different ways and needs to be fixed

change this to be a map <string, string>

 */
@ConfigMapping(prefix = "stargate.feature")
public interface FeaturesConfig {
  // Quarkus/SmallRye Config won't accept use of `null` values, so we must bind
  // as Strings and only convert to Boolean when needed.
  Map<String, String> flags();
}

Update this so it parses the <string, string> flags into the ApiFeature enum

public class ApiFeatures {
  private final Map<ApiFeature, String> fromConfig;
  private final RequestContext.HttpHeaderAccess httpHeaders;

  private ApiFeatures(
      Map<ApiFeature, String> fromConfig, RequestContext.HttpHeaderAccess httpHeaders) {
    this.fromConfig = fromConfig;
    this.httpHeaders = httpHeaders;
  }
  public static ApiFeatures fromConfigAndRequest(
      FeaturesConfig config, RequestContext.HttpHeaderAccess httpHeaders) {

// TODO: add a fromString() to the enum, throw error if not found
    Map<ApiFeature, String> fromConfig = config.flags();
    if (fromConfig == null) {
      fromConfig = Collections.emptyMap();
    }
    return new ApiFeatures(fromConfig, httpHeaders);
  }

An alternative design is to write a Converter<> class and register in src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.Converter - however then use does not need to be declared inside of FeaturesConfig and I am not a fan of the "spooky action at a distance" this brings

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions