Search in sources :

Example 1 with ApplicationClassLoader

use of fish.payara.microprofile.openapi.resource.classloader.ApplicationClassLoader in project Payara by payara.

the class OpenApiWalkerTest method testClassOrderingAndSearch.

/**
 * When the OpenAPI schema is created, a lot of lookups of classes included
 * in the schema are made.Therefore, it is required to keep to asymptotic
 * complexity as low as possible.Keeping the classes sorted in a TreeSet
 * ensures O(log(n)) complexity, as the tree is re-built on insert.<p>
 * Inside the Set (the internal contract defined by a private field is Set,
 * not TreeSet), regardless of the actual implementation used, all the
 * inserted classes should be foundable afterwards.
 * <p>
 * This method tests a fix for issue
 * {@link https://github.com/payara/Payara/issues/4489}, which pointed out
 * the original custom TreeSet comparator did a reduction to the space of
 * possible classes on lookup, making it impossible for a large subset of
 * classes to be found, even if present in the TreeSet.
 * <p>
 * The compared objects inside the internal comparator supplied to the Set
 * implementation are of type "Class". And classes have no natural distinct
 * ordinal numbers in Java. One way to get an ordinal number for a Class is
 * to use it's fully qualified name and compare the distance to the other
 * compared class in the space consisting of other class names. This way,
 * "more similar" strings have closer cartesian distance. And as String
 * representation of a Class is used, fast lookup is ensured.
 *
 * @throws java.lang.NoSuchFieldException
 * @throws java.lang.IllegalAccessException
 * @throws java.io.IOException
 * @throws java.lang.InterruptedException
 */
@Test
public void testClassOrderingAndSearch() throws NoSuchFieldException, IllegalAccessException, IOException, InterruptedException {
    final Set<Class<?>> testedClasssses = new LinkedHashSet<>();
    ApplicationClassLoader appClassLoader = new ApplicationClassLoader(testedClasssses);
    final OpenApiWalker openApiWalker = new OpenApiWalker(getDocument(), ApplicationProcessedDocument.getTypes(), ApplicationProcessedDocument.getApplicationTypes(testedClasssses.toArray(new Class<?>[0])), appClassLoader);
    final java.lang.reflect.Field sortedClassesField = OpenApiWalker.class.getDeclaredField("allowedTypes");
    // Ensure fast lookup is possible with at least any Set
    assertEquals(Set.class, sortedClassesField.getType());
    try {
        sortedClassesField.setAccessible(true);
        final Object possibleTreeSet = sortedClassesField.get(openApiWalker);
        assertEquals(TreeSet.class, possibleTreeSet.getClass());
        final Set sortedClasses = ((TreeSet<Type>) possibleTreeSet).stream().map(Type::getName).collect(toSet());
        assertNotNull(sortedClasses);
        // All tested Classes must be foundable inside the OpenApi's internal sorted classes
        testedClasssses.forEach(clazz -> assertTrue(sortedClasses.contains(clazz.getName())));
    } finally {
        sortedClassesField.setAccessible(false);
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) LinkedHashSet(java.util.LinkedHashSet) TreeSet(java.util.TreeSet) Collectors.toSet(java.util.stream.Collectors.toSet) TreeSet(java.util.TreeSet) ApplicationClassLoader(fish.payara.microprofile.openapi.resource.classloader.ApplicationClassLoader) OpenApiApplicationTest(fish.payara.microprofile.openapi.test.app.OpenApiApplicationTest) Test(org.junit.Test)

Example 2 with ApplicationClassLoader

use of fish.payara.microprofile.openapi.resource.classloader.ApplicationClassLoader in project Payara by payara.

the class ApplicationProcessedDocument method createDocument.

public static OpenAPI createDocument(Class<? extends OASFilter> filter, Class<?>... extraClasses) {
    try {
        ApplicationClassLoader appClassLoader = new ApplicationClassLoader(new HashSet<>(asList(extraClasses)));
        OpenAPIImpl document = new OpenAPIImpl();
        // Apply base processor
        new BaseProcessor(asList(new URL("http://localhost:8080/testlocation_123"))).process(document, null);
        // Apply application processor
        new ApplicationProcessor(getTypes(), getApplicationTypes(extraClasses), appClassLoader).process(document, null);
        if (filter != null) {
            new FilterProcessor(filter.newInstance()).process(document, null);
        }
        return document;
    } catch (IOException | IllegalAccessException | InstantiationException | InterruptedException ex) {
        throw new AssertionError("Failed to build document.", ex);
    }
}
Also used : OpenAPIImpl(fish.payara.microprofile.openapi.impl.model.OpenAPIImpl) FilterProcessor(fish.payara.microprofile.openapi.impl.processor.FilterProcessor) IOException(java.io.IOException) ApplicationClassLoader(fish.payara.microprofile.openapi.resource.classloader.ApplicationClassLoader) URL(java.net.URL) ApplicationProcessor(fish.payara.microprofile.openapi.impl.processor.ApplicationProcessor) BaseProcessor(fish.payara.microprofile.openapi.impl.processor.BaseProcessor)

Aggregations

ApplicationClassLoader (fish.payara.microprofile.openapi.resource.classloader.ApplicationClassLoader)2 OpenAPIImpl (fish.payara.microprofile.openapi.impl.model.OpenAPIImpl)1 ApplicationProcessor (fish.payara.microprofile.openapi.impl.processor.ApplicationProcessor)1 BaseProcessor (fish.payara.microprofile.openapi.impl.processor.BaseProcessor)1 FilterProcessor (fish.payara.microprofile.openapi.impl.processor.FilterProcessor)1 OpenApiApplicationTest (fish.payara.microprofile.openapi.test.app.OpenApiApplicationTest)1 IOException (java.io.IOException)1 URL (java.net.URL)1 LinkedHashSet (java.util.LinkedHashSet)1 Set (java.util.Set)1 TreeSet (java.util.TreeSet)1 Collectors.toSet (java.util.stream.Collectors.toSet)1 Test (org.junit.Test)1