mercredi 7 juillet 2021

Modifying swagger annotations at runtime

I have a Swagger API documentation. Some of the methods I want to hide dynamically, depending on user permissions for reading/ accessing the API.

Since I couldn't come up with a Swagger functionality on this, I have implemented a ContainerRequestFilter on my service, which is executed when getting the openapi.json document for the Swagger UI. This filter is scanning all methods containing the @Operation annotation and changing the field hidden from false to true for users with the correct permission.

import io.swagger.v3.oas.annotations.Operation;

@Provider
@Priority(Priorities.USER)
public class MyFilter implements ContainerRequestFilter{

    public void filter(ContainerRequestContext crc) throws IOException{

        Reflections reflections = new Reflections(new ConfigurationBuilder()
             .setUrls(ClasspathHelper.forPackage("my.package"))
             .setScanners(new MethodAnnotationsScanner()));
        
        // get all Operation methods
        Set<Method> resources = reflections.getMethodsAnnotatedWith(Operation.class);
        
        for(Method method : resources) {
            method.setAccessible(true);
    
            Operation operation = method.getAnnotation(Operation.class);
            InvocationHandler h = Proxy.getInvocationHandler(operation);
                
            Field hField = h.getClass().getDeclaredField("memberValues");
            hField.setAccessible(true);
            Map memberValues = (Map) hField.get(h);
                
            for(Object key : memberValues.keySet()) {
                System.out.println("memberValue: "+key+", "+memberValues.get(key));
            }

            memberValues.put("hidden", false);    
            System.out.println("operation is hidden?: " +operation.hidden());
        }
    }
}

The code seems to work insofar as the hidden field value is changed from false to true inside this filter class. However, the openapi.json document returned from the same service request does not reflect those changes.

Why are the changes on the modified annotations not consistent within the executed request?





Aucun commentaire:

Enregistrer un commentaire