0

I have a custom annotation defined below which exists in a shared common library that all microservices in the project will use. On declaring this annotation OpenApiConfiguration.class is imported which fetches various information from the .properties file to make a customised OpenAPI bean. The logic to disable swagger-ui in environments specified by the user is intended to be written in OpenApiDisabledEnvironmentValidator.class which is used in @Conditional below.

@Inherited
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(OpenApiConfiguration.class)
@Conditional(OpenApiDisabledEnvironmentValidator.class)
public @interface EnableSwaggerUiGeneration {

  String[] disableInEnvironments() default OpenApiConstant.PRODUCTION_ENVIRONMENT;

}

The consuming microservices are expected to use this annotation like below, wherein swagger-ui is to be disabled if the current active profile matches the ones mentioned in the sole exposed parameter.

@SpringBootApplication
@EnableSwaggerUiGeneration(disableInEnvironments = {"staging", "prod"})
public class ConsumingApplication {

  public static void main(String[] args) {
    SpringApplication.run(ConsumingApplication.class, args);
  }

}

The OpenApiDisabledEnvironmentValidator.class defined in the @Conditional statement above is responsible for detecting if the active profile contains any of the profiles the user has mentioned in disableInEnvironments parameter of the above annotation. If the condition is matched then it is expected to disable swagger-ui generation.

public class OpenApiDisabledEnvironmentValidator implements Condition {

  @Override
  public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    final var attributes =
        metadata.getAllAnnotationAttributes(EnableSwaggerUiGeneration.class.getName());

    for (Object value : attributes.get("disableInEnvironments")) {
      if (Arrays.stream(context.getEnvironment().getActiveProfiles())
          .anyMatch(environment -> contains(environment, (String[]) value))) {

        // TODO: Code to disable swagger-ui
      }
    }

    return Boolean.TRUE;
  }

  private boolean contains(String currentEnvironment, String[] disallowedEnvironments) {
    return Arrays.stream(disallowedEnvironments).anyMatch(
        disallowedEnvironment -> disallowedEnvironment.equalsIgnoreCase(currentEnvironment));
  }

}

I tried couple of things in place of the TODO comment above, initially I tried putting the properties which disable the swagger-ui in the application.properties file at runtime, but this only worked on restarting the application and not fulfil the required functionality.

  Properties properties = new Properties();
  try (OutputStream outputStream = new FileOutputStream("application.properties")) {
    properties.setProperty("springdoc.api-docs.enabled", "false");
    properties.setProperty("springdoc.swagger-ui.enabled", "false");
    properties.store(outputStream, null);
    outputStream.close();
  } catch (IOException e) {
    e.printStackTrace();
  }

Need a solution that implements the desired functionality and disables the swagger-ui at runtime. I don't want to define the 2 required properties in application.properties file of each microservice

behlHardik
  • 21
  • 3
  • 4

0 Answers0