From ec1f2ad5bbeb6bb91560ca587fca00974ab09f30 Mon Sep 17 00:00:00 2001 From: Olga MaciaszekSharma Date: Wed, 12 May 2021 13:51:43 +0200 Subject: [PATCH] Refactor FeignHalConfiguration to use HalMediaTypeConfiguration under the hood. Fixes gh-541. --- .../hateoas/FeignHalAutoConfiguration.java | 45 ++++--------------- .../FeignHalAutoConfigurationTests.java | 26 ++++++----- 2 files changed, 23 insertions(+), 48 deletions(-) diff --git a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/hateoas/FeignHalAutoConfiguration.java b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/hateoas/FeignHalAutoConfiguration.java index f5ce6015..b402d0d8 100644 --- a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/hateoas/FeignHalAutoConfiguration.java +++ b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/hateoas/FeignHalAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 the original author or authors. + * Copyright 2016-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,37 +16,30 @@ package org.springframework.cloud.openfeign.hateoas; -import java.util.Arrays; import java.util.Collections; -import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration; -import org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration; import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.hateoas.RepresentationModel; -import org.springframework.hateoas.mediatype.MessageResolver; -import org.springframework.hateoas.mediatype.hal.CurieProvider; -import org.springframework.hateoas.mediatype.hal.DefaultCurieProvider; -import org.springframework.hateoas.mediatype.hal.HalConfiguration; -import org.springframework.hateoas.mediatype.hal.Jackson2HalModule; -import org.springframework.hateoas.server.LinkRelationProvider; +import org.springframework.hateoas.mediatype.hal.HalMediaTypeConfiguration; import org.springframework.hateoas.server.mvc.TypeConstrainedMappingJackson2HttpMessageConverter; import static org.springframework.hateoas.MediaTypes.HAL_JSON; /** * @author Hector Espert + * @author Olga Maciaszek-Sharma */ @Configuration(proxyBeanMethods = false) @ConditionalOnWebApplication @@ -54,41 +47,19 @@ import static org.springframework.hateoas.MediaTypes.HAL_JSON; @AutoConfigureAfter({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, RepositoryRestMvcAutoConfiguration.class }) -@AutoConfigureBefore(HypermediaAutoConfiguration.class) public class FeignHalAutoConfiguration { @Bean + @ConditionalOnBean(HalMediaTypeConfiguration.class) @ConditionalOnMissingBean public TypeConstrainedMappingJackson2HttpMessageConverter halJacksonHttpMessageConverter( ObjectProvider objectMapper, - ObjectProvider halConfiguration, - ObjectProvider messageResolver, - ObjectProvider curieProvider, - ObjectProvider linkRelationProvider) { - + HalMediaTypeConfiguration halConfiguration) { ObjectMapper mapper = objectMapper.getIfAvailable(ObjectMapper::new).copy(); - mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); - - HalConfiguration configuration = halConfiguration - .getIfAvailable(HalConfiguration::new); - - CurieProvider curieProviderInstance = curieProvider - .getIfAvailable(() -> new DefaultCurieProvider(Collections.emptyMap())); - - Jackson2HalModule.HalHandlerInstantiator halHandlerInstantiator = new Jackson2HalModule.HalHandlerInstantiator( - linkRelationProvider.getIfAvailable(), curieProviderInstance, - messageResolver.getIfAvailable(), configuration); - - mapper.setHandlerInstantiator(halHandlerInstantiator); - - if (!Jackson2HalModule.isAlreadyRegisteredIn(mapper)) { - Jackson2HalModule halModule = new Jackson2HalModule(); - mapper.registerModule(halModule); - } - + halConfiguration.configureObjectMapper(mapper); TypeConstrainedMappingJackson2HttpMessageConverter converter = new TypeConstrainedMappingJackson2HttpMessageConverter( RepresentationModel.class); - converter.setSupportedMediaTypes(Arrays.asList(HAL_JSON)); + converter.setSupportedMediaTypes(Collections.singletonList(HAL_JSON)); converter.setObjectMapper(mapper); return converter; } diff --git a/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/hateoas/FeignHalAutoConfigurationTests.java b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/hateoas/FeignHalAutoConfigurationTests.java index c1da26e6..5c923c46 100644 --- a/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/hateoas/FeignHalAutoConfigurationTests.java +++ b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/hateoas/FeignHalAutoConfigurationTests.java @@ -16,7 +16,7 @@ package org.springframework.cloud.openfeign.hateoas; -import java.util.Arrays; +import java.util.Collections; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; @@ -26,9 +26,11 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.hateoas.mediatype.MessageResolver; import org.springframework.hateoas.mediatype.hal.CurieProvider; import org.springframework.hateoas.mediatype.hal.HalConfiguration; +import org.springframework.hateoas.mediatype.hal.HalMediaTypeConfiguration; import org.springframework.hateoas.mediatype.hal.Jackson2HalModule; import org.springframework.hateoas.server.LinkRelationProvider; import org.springframework.hateoas.server.mvc.TypeConstrainedMappingJackson2HttpMessageConverter; @@ -45,20 +47,20 @@ import static org.springframework.hateoas.MediaTypes.HAL_JSON; @RunWith(MockitoJUnitRunner.class) public class FeignHalAutoConfigurationTests { - @Mock - private ObjectProvider objectMapper; - @Mock private ObjectProvider halConfiguration; @Mock - private ObjectProvider relProvider; + private ObjectProvider objectMapper; + + @Mock + private LinkRelationProvider relProvider; @Mock private ObjectProvider curieProvider; @Mock - private ObjectProvider messageResolver; + private MessageResolver messageResolver; @InjectMocks private FeignHalAutoConfiguration feignHalAutoConfiguration; @@ -70,17 +72,19 @@ public class FeignHalAutoConfigurationTests { when(halConfiguration.getIfAvailable(any())) .thenReturn(mock(HalConfiguration.class)); - when(relProvider.getIfAvailable()).thenReturn(mock(LinkRelationProvider.class)); when(curieProvider.getIfAvailable(any())).thenReturn(mock(CurieProvider.class)); - when(messageResolver.getIfAvailable()).thenReturn(mock(MessageResolver.class)); + + HalMediaTypeConfiguration halMediaTypeConfiguration = new HalMediaTypeConfiguration( + relProvider, curieProvider, halConfiguration, messageResolver, + new DefaultListableBeanFactory()); TypeConstrainedMappingJackson2HttpMessageConverter converter = feignHalAutoConfiguration - .halJacksonHttpMessageConverter(objectMapper, halConfiguration, - messageResolver, curieProvider, relProvider); + .halJacksonHttpMessageConverter(objectMapper, halMediaTypeConfiguration); assertThat(converter).isNotNull(); assertThat(converter.getObjectMapper()).isNotNull(); - assertThat(converter.getSupportedMediaTypes()).isEqualTo(Arrays.asList(HAL_JSON)); + assertThat(converter.getSupportedMediaTypes()) + .isEqualTo(Collections.singletonList(HAL_JSON)); assertThat(Jackson2HalModule.isAlreadyRegisteredIn(converter.getObjectMapper())) .isTrue();