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);
}
}
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);
}
}
Aggregations