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

feat(rest-json): emits a warning during build time if we detect the need of a json extension and none is provided #4165

Merged
merged 1 commit into from
Sep 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public final class Capabilities extends SimpleBuildItem {
public static final String CDI_ARC = "io.quarkus.cdi";
public static final String SERVLET = "io.quarkus.servlet";
public static final String TRANSACTIONS = "io.quarkus.transactions";
public static final String RESTEASY_JSON_EXTENSION = "resteasy-json-extension";

private final Set<String> capabilities;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.quarkus.resteasy.common.deployment;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
Expand All @@ -8,16 +9,26 @@
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.*;

import org.jboss.jandex.*;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Providers;

import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.DotName;
import org.jboss.jandex.IndexView;
import org.jboss.jandex.MethodInfo;
import org.jboss.logging.Logger;
import org.jboss.resteasy.core.MediaTypeMap;
import org.jboss.resteasy.plugins.interceptors.AcceptEncodingGZIPFilter;
import org.jboss.resteasy.plugins.interceptors.GZIPDecodingInterceptor;
import org.jboss.resteasy.plugins.interceptors.GZIPEncodingInterceptor;
import org.jboss.resteasy.plugins.providers.StringTextStar;

import io.quarkus.arc.deployment.BeanArchiveIndexBuildItem;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
Expand All @@ -29,6 +40,7 @@
import io.quarkus.runtime.configuration.MemorySize;

public class ResteasyCommonProcessor {
private static final Logger LOGGER = Logger.getLogger(ResteasyCommonProcessor.class.getName());

private static final ProviderDiscoverer[] PROVIDER_DISCOVERERS = {
new ProviderDiscoverer(ResteasyDotNames.GET, false, true),
Expand Down Expand Up @@ -81,12 +93,13 @@ void setupGzipProviders(BuildProducer<ResteasyJaxrsProviderBuildItem> providers)
JaxrsProvidersToRegisterBuildItem setupProviders(BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
CombinedIndexBuildItem indexBuildItem,
BeanArchiveIndexBuildItem beanArchiveIndexBuildItem,
List<ResteasyJaxrsProviderBuildItem> contributedProviderBuildItems) throws Exception {
List<ResteasyJaxrsProviderBuildItem> contributedProviderBuildItems, Capabilities capabilities) throws Exception {

Set<String> contributedProviders = new HashSet<>();
for (ResteasyJaxrsProviderBuildItem contributedProviderBuildItem : contributedProviderBuildItems) {
contributedProviders.add(contributedProviderBuildItem.getName());
}

for (AnnotationInstance i : indexBuildItem.getIndex().getAnnotations(ResteasyDotNames.PROVIDER)) {
if (i.target().kind() == AnnotationTarget.Kind.CLASS) {
contributedProviders.add(i.target().asClass().name().toString());
Expand All @@ -107,6 +120,18 @@ JaxrsProvidersToRegisterBuildItem setupProviders(BuildProducer<ReflectiveClassBu
// add the other providers detected
Set<String> providersToRegister = new HashSet<>(otherProviders);

if (!capabilities.isCapabilityPresent(Capabilities.RESTEASY_JSON_EXTENSION)) {

boolean needJsonSupport = restJsonSupportNeeded(indexBuildItem, ResteasyDotNames.CONSUMES)
|| restJsonSupportNeeded(indexBuildItem, ResteasyDotNames.PRODUCES);
if (needJsonSupport) {
LOGGER.warn(
"Quarkus detected the need of REST JSON support but you have not provided the necessary JSON " +
"extension for this. You can visit https://quarkus.io/guides/rest-json-guide for more " +
"information on how to set one.");
}
}

// we add a couple of default providers
providersToRegister.add(StringTextStar.class.getName());
providersToRegister.addAll(categorizedWriters.getPossible(MediaType.APPLICATION_JSON_TYPE));
Expand Down Expand Up @@ -134,6 +159,21 @@ JaxrsProvidersToRegisterBuildItem setupProviders(BuildProducer<ReflectiveClassBu
return new JaxrsProvidersToRegisterBuildItem(providersToRegister, contributedProviders, useBuiltinProviders);
}

private boolean restJsonSupportNeeded(CombinedIndexBuildItem indexBuildItem, DotName mediaTypeAnnotation) {
for (AnnotationInstance annotationInstance : indexBuildItem.getIndex().getAnnotations(mediaTypeAnnotation)) {
final AnnotationValue annotationValue = annotationInstance.value();
if (annotationInstance == null) {
continue;
}

final List<String> mediaTypes = Arrays.asList(annotationValue.asStringArray());
return mediaTypes.contains(MediaType.APPLICATION_JSON)
|| mediaTypes.contains(MediaType.APPLICATION_JSON_PATCH_JSON);
}

return false;
}

public static void categorizeProviders(Set<String> availableProviders, MediaTypeMap<String> categorizedReaders,
MediaTypeMap<String> categorizedWriters, MediaTypeMap<String> categorizedContextResolvers,
Set<String> otherProviders) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import io.quarkus.arc.InstanceHandle;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.deployment.UnremovableBeanBuildItem;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
Expand All @@ -49,7 +50,7 @@ public class ResteasyJacksonProcessor {

private static final String QUARKUS_CONTEXT_RESOLVER_NAME = "io.quarkus.resteasy.jackson.runtime.QuarkusObjectMapperContextResolver";

@BuildStep
@BuildStep(providesCapabilities = Capabilities.RESTEASY_JSON_EXTENSION)
void build(BuildProducer<FeatureBuildItem> feature) {
feature.produce(new FeatureBuildItem(FeatureBuildItem.RESTEASY_JACKSON));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package io.quarkus.resteasy.jsonb.deployment;

import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.FeatureBuildItem;

public class ResteasyJsonbProcessor {

@BuildStep
@BuildStep(providesCapabilities = Capabilities.RESTEASY_JSON_EXTENSION)
void build(BuildProducer<FeatureBuildItem> feature) {
feature.produce(new FeatureBuildItem(FeatureBuildItem.RESTEASY_JSONB));
}
Expand Down
2 changes: 1 addition & 1 deletion extensions/resteasy/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<!-- These are needed to test the JSON representation of the NotFoundExceptionMapper-->
<!-- These are needed to test the RESTEASY_JSON_EXTENSION representation of the NotFoundExceptionMapper-->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-json-binding-provider</artifactId>
Expand Down