Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
reta opened this issue Aug 14, 2023 · 0 comments · Fixed by #11175
Closed

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

reta opened this issue Aug 14, 2023 · 0 comments · Fixed by #11175
Assignees
Labels
API Issues with external APIs enhancement Enhancement or improvement to existing feature or request Plugins

Comments

@reta
Copy link
Collaborator

reta commented Aug 14, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API Issues with external APIs enhancement Enhancement or improvement to existing feature or request Plugins
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants