Skip to content

[BWC and API enforcement] Introduce checks for enforcing the API restrictions #9304

@reta

Description

@reta

Is your feature request related to a problem? Please describe.
Ideally, the public API should never expose anything that is internal. To enforce that (or at least to understand the limits of how far we can go), we have to introspect each type annotated with @PublicApi or @ExprimentalApi and make sure it leaks only @PublicApi or @ExprimentalApi types as well (exceptions, method return values, method arguments, annotations). How can we do that?

Describe the solution you'd like

  • craft annotation processor
    @SupportedAnnotationTypes("org.opensearch.common.annotation.*")
    public class ApiAnnotationProcessor extends AbstractProcessor {
        @Override
        public SourceVersion getSupportedSourceVersion() {
            return SourceVersion.latest();
        }
    
        @Override
        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment round) {
            final Set<? extends Element> elements = round.getElementsAnnotatedWithAny(Set.of(Api.class, Experimental.class));
            processingEnv.getMessager().printMessage(Kind.NOTE, "Processing Api annotations");
    
            for (var element : elements) {
                if (element instanceof TypeElement) {
                    final TypeElement type = (TypeElement) element;
                    process(type);
                } 
                 ....
            } 
    
            return false;
        }
    }
  • use something like ArchUnit and introduce the API level tests (pseudo rule is below but it is very close to what we could have as real one)
    public class ApiRules {
        @ArchTest
        public static final ArchRule PUBLIC_API_METHODS_USE_ONLY_PUBLIC_OR_EXPERIMENTAL_API_TYPES =
            freeze(
                methods()
                    .that()
                    .areDeclaredInClassesThat().resideInAPackage("org.opensearch..")
                    .and().arePublic()
                    .should(
                        haveArgsOrReturnTypes()
                            .that()
                            .resideOutsideOfPackage("org.opensearch..")
                            .or()
                                .resideInAPackage("org.opensearch..")
                                .and(areAnnotatedWithAtLeastOneOf(Public.class, Experimental.class)))
                    .as("Return and argument types of methods annotated with @Api or @Experimental must be annotated with @Api or @Experimental."));
    }

Describe alternatives you've considered
N/A

Additional context
Part of #8127

Metadata

Metadata

Assignees

Labels

APIIssues with external APIsPluginsenhancementEnhancement or improvement to existing feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions