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

Allow to use HeaderDelegateProvider to parse the response MediaType #4419

Merged
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 @@ -54,6 +54,7 @@

import org.glassfish.jersey.internal.LocalizationMessages;
import org.glassfish.jersey.internal.PropertiesDelegate;
import org.glassfish.jersey.internal.RuntimeDelegateDecorator;
import org.glassfish.jersey.message.MessageBodyWorkers;

/**
Expand Down Expand Up @@ -331,7 +332,7 @@ private <T> T singleHeader(String name, Function<String, T> converter, boolean c
}

try {
return converter.apply(HeaderUtils.asString(value, null));
return converter.apply(HeaderUtils.asString(value, configuration));
} catch (ProcessingException ex) {
throw exception(name, value, ex);
}
Expand Down Expand Up @@ -450,7 +451,9 @@ public MediaType getMediaType() {
@Override
public MediaType apply(String input) {
try {
return MediaType.valueOf(input);
return RuntimeDelegateDecorator.configured(configuration)
.createHeaderDelegate(MediaType.class)
.fromString(input);
} catch (IllegalArgumentException iae) {
throw new ProcessingException(iae);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,8 @@ public Locale getLanguage() {
* message entity).
*/
public MediaType getMediaType() {
return singleHeader(HttpHeaders.CONTENT_TYPE, MediaType.class, MediaType::valueOf, false);
return singleHeader(HttpHeaders.CONTENT_TYPE, MediaType.class, RuntimeDelegateDecorator.configured(configuration)
.createHeaderDelegate(MediaType.class)::fromString, false);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -17,8 +17,12 @@
package org.glassfish.jersey.tests.e2e.header;

import org.glassfish.jersey.CommonProperties;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.internal.ServiceFinder;
import org.glassfish.jersey.message.internal.HeaderUtils;
import org.glassfish.jersey.message.internal.HeaderValueException;
import org.glassfish.jersey.message.internal.InboundMessageContext;
import org.glassfish.jersey.message.internal.OutboundMessageContext;
import org.glassfish.jersey.spi.HeaderDelegateProvider;
import org.junit.Assert;
import org.junit.Test;
Expand All @@ -34,14 +38,18 @@
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ReaderInterceptor;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.fail;

public class HeaderDelegateProviderTest {
static final String HEADER_NAME = "BEAN_HEADER";
static final String DISABLED_VALUE = new BeanForHeaderDelegateProviderTest().toString();
Expand All @@ -64,6 +72,23 @@ public String toString(BeanForHeaderDelegateProviderTest value) {
}
}

public static class EmptyContentTypeHandler implements HeaderDelegateProvider<MediaType> {
@Override
public boolean supports(Class<?> type) {
return MediaType.class == type;
}

@Override
public MediaType fromString(String value) {
return value.isEmpty() ? MediaType.APPLICATION_OCTET_STREAM_TYPE : MediaType.valueOf(value);
}

@Override
public String toString(MediaType value) {
return value.toString();
}
};

public static class BeanForHeaderDelegateProviderTest {
public static String getValue() {
return "CORRECT_VALUE";
Expand Down Expand Up @@ -116,13 +141,18 @@ public void filter(ClientRequestContext requestContext) throws IOException {

@Test
public void testTheProviderIsFound() {
int found = 0;
for (HeaderDelegateProvider provider : ServiceFinder.find(HeaderDelegateProvider.class, true)) {
Assert.assertEquals(provider.getClass(), BeanHeaderDelegateProvider.class);
if (provider.getClass() == BeanHeaderDelegateProvider.class
|| provider.getClass() == EmptyContentTypeHandler.class) {
found++;
}
}
Assert.assertEquals(2, found);
}

@Test
public void headerDelegateIsUsedWhenRuntimeDelegateDecoratorIsUsed() {
public void testHeaderDelegateIsUsedWhenRuntimeDelegateDecoratorIsUsed() {
MultivaluedHashMap headers = new MultivaluedHashMap();
headers.put(HEADER_NAME, Arrays.asList(new BeanForHeaderDelegateProviderTest()));
MultivaluedMap<String, String> converted = HeaderUtils.asStringHeaders(headers, null);
Expand All @@ -134,7 +164,7 @@ public void headerDelegateIsUsedWhenRuntimeDelegateDecoratorIsUsed() {
}

@Test
public void headerDelegateIsNotUsed() {
public void testHeaderDelegateIsNotUsed() {
MultivaluedHashMap headers = new MultivaluedHashMap();
headers.put(HEADER_NAME, Arrays.asList(new BeanForHeaderDelegateProviderTest()));

Expand All @@ -147,6 +177,54 @@ public void headerDelegateIsNotUsed() {
testMap(converted, DISABLED_VALUE);
}

@Test
public void testGetMediaTypeInInboundMessageContext() {
ClientConfig config = new ClientConfig().property(CommonProperties.METAINF_SERVICES_LOOKUP_DISABLE, true);
InboundMessageContext inboundMessageContext = new InboundMessageContext(config.getConfiguration()) {
@Override
protected Iterable<ReaderInterceptor> getReaderInterceptors() {
return null;
}
};
inboundMessageContext.header(HttpHeaders.CONTENT_TYPE, "");
try {
inboundMessageContext.getMediaType();
fail("Expected HeaderValueException has not been thrown");
} catch (HeaderValueException ex) {
// expected
}

config.property(CommonProperties.METAINF_SERVICES_LOOKUP_DISABLE, false);
inboundMessageContext = new InboundMessageContext(config.getConfiguration()) {
@Override
protected Iterable<ReaderInterceptor> getReaderInterceptors() {
return null;
}
};
inboundMessageContext.header(HttpHeaders.CONTENT_TYPE, "");
MediaType mediaType = inboundMessageContext.getMediaType();
Assert.assertEquals(MediaType.APPLICATION_OCTET_STREAM_TYPE, mediaType);
}

@Test
public void testGetMediaTypeInOutboundMessageContext() {
ClientConfig config = new ClientConfig().property(CommonProperties.METAINF_SERVICES_LOOKUP_DISABLE, true);
OutboundMessageContext outboundMessageContext = new OutboundMessageContext(config.getConfiguration());
outboundMessageContext.getHeaders().add(HttpHeaders.CONTENT_TYPE, "");
try {
outboundMessageContext.getMediaType();
fail("Expected HeaderValueException has not been thrown");
} catch (IllegalArgumentException ex) {
// expected
}

config.property(CommonProperties.METAINF_SERVICES_LOOKUP_DISABLE, false);
outboundMessageContext = new OutboundMessageContext(config.getConfiguration());
outboundMessageContext.getHeaders().add(HttpHeaders.CONTENT_TYPE, "");
MediaType mediaType = outboundMessageContext.getMediaType();
Assert.assertEquals(MediaType.APPLICATION_OCTET_STREAM_TYPE, mediaType);
}

private void testMap(MultivaluedMap<String, String> map, String expectedValue) {
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
Assert.assertEquals(HEADER_NAME, entry.getKey());
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
org.glassfish.jersey.tests.e2e.header.HeaderDelegateProviderTest$BeanHeaderDelegateProvider
org.glassfish.jersey.tests.e2e.header.HeaderDelegateProviderTest$BeanHeaderDelegateProvider
org.glassfish.jersey.tests.e2e.header.HeaderDelegateProviderTest$EmptyContentTypeHandler