All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.yahoo.elide.extension.deployment.ElideExtensionProcessor Maven / Gradle / Ivy
/*
* Copyright 2021, Yahoo Inc.
* Licensed under the Apache License, Version 2.0
* See LICENSE file in project root for terms.
*/
package com.yahoo.elide.extension.deployment;
import static io.quarkus.deployment.annotations.ExecutionTime.STATIC_INIT;
import com.yahoo.elide.annotation.Include;
import com.yahoo.elide.annotation.LifeCycleHookBinding;
import com.yahoo.elide.annotation.SecurityCheck;
import com.yahoo.elide.core.security.checks.prefab.Collections;
import com.yahoo.elide.core.utils.ClassScanner;
import com.yahoo.elide.core.utils.coerce.converters.ElideTypeConverter;
import com.yahoo.elide.extension.runtime.ElideConfig;
import com.yahoo.elide.extension.runtime.ElideRecorder;
import com.yahoo.elide.extension.runtime.ElideResourceBuilder;
import com.yahoo.elide.graphql.DeferredId;
import com.yahoo.elide.graphql.GraphQLEndpoint;
import com.yahoo.elide.jsonapi.models.JsonApiDocument;
import com.yahoo.elide.jsonapi.resources.JsonApiEndpoint;
import com.yahoo.elide.jsonapi.serialization.DataDeserializer;
import com.yahoo.elide.jsonapi.serialization.DataSerializer;
import com.yahoo.elide.jsonapi.serialization.KeySerializer;
import com.yahoo.elide.jsonapi.serialization.MetaDeserializer;
import com.yahoo.elide.swagger.OpenApiDocument;
import com.yahoo.elide.swagger.resources.ApiDocsEndpoint;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.impl.SimpleLog;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.DotName;
import org.jboss.jandex.Type;
import org.jboss.logging.Logger;
import org.jboss.resteasy.plugins.server.servlet.ResteasyContextParameters;
import graphql.schema.GraphQLSchema;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.deployment.BeanContainerListenerBuildItem;
import io.quarkus.arc.deployment.BeanDefiningAnnotationBuildItem;
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveHierarchyBuildItem;
import io.quarkus.resteasy.server.common.deployment.ResteasyDeploymentCustomizerBuildItem;
import io.quarkus.undertow.deployment.ServletInitParamBuildItem;
import jakarta.enterprise.inject.Default;
import jakarta.inject.Singleton;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
class ElideExtensionProcessor {
private static final Logger LOG = Logger.getLogger(ElideExtensionProcessor.class.getName());
private static final String FEATURE = "elide";
@BuildStep
FeatureBuildItem feature() {
return new FeatureBuildItem(FEATURE);
}
@BuildStep
public void indexDependencies(BuildProducer dependencies) {
dependencies.produce(new IndexDependencyBuildItem("com.yahoo.elide", "elide-core"));
dependencies.produce(new IndexDependencyBuildItem("io.swagger.core.v3", "swagger-core-jakarta"));
dependencies.produce(new IndexDependencyBuildItem("io.swagger.core.v3", "swagger-models-jakarta"));
/* Needed for CoerceUtil which loads LogFactoryImpl */
dependencies.produce(new IndexDependencyBuildItem("commons-logging", "commons-logging"));
dependencies.produce(new IndexDependencyBuildItem("com.graphql-java", "graphql-java"));
}
@BuildStep
public AdditionalBeanBuildItem configureElideEndpoints(ElideConfig config) {
AdditionalBeanBuildItem.Builder builder = AdditionalBeanBuildItem.builder();
if (config.baseJsonapi != null) {
LOG.info("Enabling JSON-API Endpoint");
builder = builder.addBeanClass(JsonApiEndpoint.class);
}
if (config.baseGraphql != null) {
LOG.info("Enabling GraphQL Endpoint");
builder = builder.addBeanClass(GraphQLEndpoint.class);
}
if (config.baseSwagger != null && config.baseJsonapi != null) {
LOG.info("Enabling Swagger Endpoint");
builder = builder.addBeanClass(ApiDocsEndpoint.class);
}
return builder.build();
}
@BuildStep
public void configureRestEasy(
BuildProducer deploymentCustomizerProducer,
BuildProducer reflectiveClass,
BuildProducer initParamProducer
) {
initParamProducer.produce(
new ServletInitParamBuildItem(
ResteasyContextParameters.RESTEASY_SCANNED_RESOURCE_CLASSES_WITH_BUILDER,
ElideResourceBuilder.class.getName() + ":"
+ JsonApiEndpoint.class.getCanonicalName() + ","
+ GraphQLEndpoint.class.getCanonicalName() + ","
+ ApiDocsEndpoint.class.getCanonicalName()
));
deploymentCustomizerProducer.produce(new ResteasyDeploymentCustomizerBuildItem((deployment) -> {
deployment.getScannedResourceClassesWithBuilder().put(
ElideResourceBuilder.class.getCanonicalName(),
Arrays.asList(
JsonApiEndpoint.class.getCanonicalName(),
GraphQLEndpoint.class.getCanonicalName(),
ApiDocsEndpoint.class.getCanonicalName()
));
}));
reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, false,
ElideResourceBuilder.class.getName()));
}
@Record(STATIC_INIT)
@BuildStep
void configureElideConfig(ElideConfig elideConfig,
ElideRecorder recorder,
BuildProducer containerListenerProducer) {
containerListenerProducer.produce(
new BeanContainerListenerBuildItem(recorder.setElideConfig(elideConfig)));
}
@BuildStep
List configureBeanAnnotations() {
List additionalBeanAnnotations = new ArrayList<>();
additionalBeanAnnotations.add(
new BeanDefiningAnnotationBuildItem(
DotName.createSimple(Include.class.getCanonicalName())));
additionalBeanAnnotations.add(
new BeanDefiningAnnotationBuildItem(
DotName.createSimple(SecurityCheck.class.getCanonicalName())));
additionalBeanAnnotations.add(
new BeanDefiningAnnotationBuildItem(
DotName.createSimple(LifeCycleHookBinding.class.getCanonicalName())));
additionalBeanAnnotations.add(
new BeanDefiningAnnotationBuildItem(
DotName.createSimple(ElideTypeConverter.class.getCanonicalName())));
return additionalBeanAnnotations;
}
@BuildStep
@Record(STATIC_INIT)
public void configureElideModels(
CombinedIndexBuildItem index,
ElideRecorder elideRecorder,
BuildProducer reflectionBuildItems,
BuildProducer reflectionHierarchiesBuildItems,
BuildProducer synthenticBean
) {
List> elideClasses = new ArrayList<>();
index.getIndex().getKnownClasses().forEach(classInfo -> {
boolean found = false;
for (Class annotationClass : ElideRecorder.ANNOTATIONS) {
AnnotationInstance instance =
classInfo.classAnnotation(DotName.createSimple(annotationClass.getCanonicalName()));
if (instance != null) {
found = true;
break;
}
}
if (found) {
try {
Class> beanClass = Class.forName(classInfo.name().toString(), false,
Thread.currentThread().getContextClassLoader());
reflectionHierarchiesBuildItems.produce(new ReflectiveHierarchyBuildItem.Builder()
.type(convertToType(beanClass))
.build());
elideClasses.add(beanClass);
} catch (ClassNotFoundException e) {
LOG.error("Unable to load class from Jandex Index: " + classInfo.name());
}
}
});
synthenticBean.produce(SyntheticBeanBuildItem.configure(ClassScanner.class).scope(Singleton.class)
.supplier(elideRecorder.createClassScanner(elideClasses))
.unremovable()
.addQualifier(Default.class)
.done());
reflectionHierarchiesBuildItems.produce(new ReflectiveHierarchyBuildItem.Builder()
.type(convertToType(JsonApiDocument.class))
.build());
reflectionHierarchiesBuildItems.produce(new ReflectiveHierarchyBuildItem.Builder()
.type(convertToType(OpenApiDocument.class))
.build());
reflectionHierarchiesBuildItems.produce(new ReflectiveHierarchyBuildItem.Builder()
.type(convertToType(GraphQLSchema.class))
.build());
//JSON-API Serialization Classes:
reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, DataSerializer.class));
reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, DataDeserializer.class));
reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, MetaDeserializer.class));
reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, KeySerializer.class));
//Prefabbed Checks:
reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, Collections.AppendOnly.class));
reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, Collections.RemoveOnly.class));
//GraphQL Schema:
reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, DeferredId.class));
// reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, DeferredId.SerializeId.class));
//Needed by elide dependency coerce utils which pulls in commons logging.
// reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, JBossLogFactory.class));
reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, LogFactory.class));
reflectionBuildItems.produce(new ReflectiveClassBuildItem(true, true, SimpleLog.class));
}
private Type convertToType(Class> cls) {
return Type.create(DotName.createSimple(cls.getCanonicalName()), Type.Kind.CLASS);
}
}