diff --git a/server/src/main/java/org/springsource/restbucks/JacksonCustomizations.java b/server/src/main/java/org/springsource/restbucks/JacksonCustomizations.java index 70f2ce8b..de1ef697 100644 --- a/server/src/main/java/org/springsource/restbucks/JacksonCustomizations.java +++ b/server/src/main/java/org/springsource/restbucks/JacksonCustomizations.java @@ -16,9 +16,6 @@ package org.springsource.restbucks; import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import java.util.regex.Pattern; import javax.money.MonetaryAmount; @@ -31,6 +28,7 @@ import org.springframework.data.rest.webmvc.json.JsonSchema.JsonSchemaProperty; import org.springframework.data.rest.webmvc.json.JsonSchemaPropertyCustomizer; import org.springframework.data.util.TypeInformation; +import org.springframework.lang.Nullable; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.DeserializationContext; @@ -53,26 +51,6 @@ Module moneyModule() { return new MoneyModule(); } - @Bean - Module restbucksModule(List mixins) { - - Map, Class> annotations = mixins.stream().map(Mixins::getMixins) - .reduce(new HashMap<>(), (left, right) -> { - left.putAll(right); - return left; - }); - - return new RestbucksModule(annotations); - } - - @SuppressWarnings("serial") - static class RestbucksModule extends SimpleModule { - - public RestbucksModule(Map, Class> mixins) { - mixins.entrySet().forEach(it -> setMixInAnnotation(it.getKey(), it.getValue())); - } - } - @SuppressWarnings("serial") static class MoneyModule extends SimpleModule { @@ -115,7 +93,8 @@ public MonetaryAmountSerializer() { * @see com.fasterxml.jackson.databind.ser.std.StdSerializer#serialize(java.lang.Object, com.fasterxml.jackson.core.JsonGenerator, com.fasterxml.jackson.databind.SerializerProvider) */ @Override - public void serialize(MonetaryAmount value, JsonGenerator jgen, SerializerProvider provider) throws IOException { + public void serialize(@Nullable MonetaryAmount value, JsonGenerator jgen, SerializerProvider provider) + throws IOException { if (value != null) { jgen.writeString(MonetaryFormats.getAmountFormat(LocaleContextHolder.getLocale()).format(value)); diff --git a/server/src/main/java/org/springsource/restbucks/Mixins.java b/server/src/main/java/org/springsource/restbucks/drinks/DrinksConfiguration.java similarity index 51% rename from server/src/main/java/org/springsource/restbucks/Mixins.java rename to server/src/main/java/org/springsource/restbucks/drinks/DrinksConfiguration.java index e831d726..2f5c1f88 100644 --- a/server/src/main/java/org/springsource/restbucks/Mixins.java +++ b/server/src/main/java/org/springsource/restbucks/drinks/DrinksConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2023 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. @@ -13,21 +13,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springsource.restbucks; +package org.springsource.restbucks.drinks; -import java.util.Map; +import javax.money.MonetaryAmount; + +import org.springframework.boot.jackson.JsonMixin; +import org.springframework.context.annotation.Configuration; + +import com.fasterxml.jackson.annotation.JsonCreator; /** - * SPI for configuration classes or beans that expose a {@link Map} of mixin types to be registered. + * Customizations for the drinks module. * * @author Oliver Drotbohm */ -public interface Mixins { +@Configuration(proxyBeanMethods = false) +class DrinksConfiguration { + + @JsonMixin(Drink.class) + static abstract class DrinkMixin { - /** - * The mixins to be registered with the application. - * - * @return - */ - Map, Class> getMixins(); + @JsonCreator + public DrinkMixin(String name, Milk milk, Size size, MonetaryAmount price) {} + } } diff --git a/server/src/main/java/org/springsource/restbucks/engine/Engine.java b/server/src/main/java/org/springsource/restbucks/engine/Engine.java index f69a2916..f13fdc2c 100644 --- a/server/src/main/java/org/springsource/restbucks/engine/Engine.java +++ b/server/src/main/java/org/springsource/restbucks/engine/Engine.java @@ -23,7 +23,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import org.springframework.modulith.ApplicationModuleListener; +import org.springframework.modulith.events.ApplicationModuleListener; import org.springframework.stereotype.Service; import org.springsource.restbucks.order.Order; import org.springsource.restbucks.order.OrderPaid; diff --git a/server/src/main/java/org/springsource/restbucks/order/web/OrderConfiguration.java b/server/src/main/java/org/springsource/restbucks/order/web/OrderConfiguration.java index 51ef1c18..cd36b659 100644 --- a/server/src/main/java/org/springsource/restbucks/order/web/OrderConfiguration.java +++ b/server/src/main/java/org/springsource/restbucks/order/web/OrderConfiguration.java @@ -18,12 +18,12 @@ import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; import java.util.Collection; -import java.util.Map; import java.util.Optional; import java.util.function.Supplier; import javax.money.MonetaryAmount; +import org.springframework.boot.jackson.JsonMixin; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.hateoas.Link; @@ -31,7 +31,6 @@ import org.springframework.hateoas.mediatype.MediaTypeConfigurationCustomizer; import org.springframework.hateoas.mediatype.hal.forms.HalFormsConfiguration; import org.springframework.hateoas.mediatype.hal.forms.HalFormsOptions; -import org.springsource.restbucks.Mixins; import org.springsource.restbucks.drinks.DrinksOptions; import org.springsource.restbucks.drinks.Milk; import org.springsource.restbucks.drinks.Size; @@ -46,7 +45,7 @@ * @author Oliver Drotbohm */ @Configuration(proxyBeanMethods = false) -class OrderConfiguration implements Mixins { +class OrderConfiguration { @Bean MediaTypeConfigurationCustomizer orderHalFormsCustomization() { @@ -64,19 +63,7 @@ MediaTypeConfigurationCustomizer orderHalFormsCustomizati __ -> HalFormsOptions.remote(drinkOptionsLink.get()).withMinItems(1L)); } - /* - * (non-Javadoc) - * @see org.springsource.restbucks.Mixins#getMixins() - */ - @Override - public Map, Class> getMixins() { - - return Map.of( // - Order.class, OrderMixin.class, // - LineItem.class, LineItemMixin.class // - ); - } - + @JsonMixin(Order.class) @JsonAutoDetect(isGetterVisibility = JsonAutoDetect.Visibility.NONE) static abstract class OrderMixin { @@ -84,6 +71,7 @@ static abstract class OrderMixin { public OrderMixin(Collection lineItems, Location location) {} } + @JsonMixin(LineItem.class) static abstract class LineItemMixin { @JsonCreator diff --git a/server/src/main/java/org/springsource/restbucks/payment/web/PaymentConfiguration.java b/server/src/main/java/org/springsource/restbucks/payment/web/PaymentConfiguration.java index 792b15df..ec08b0cb 100644 --- a/server/src/main/java/org/springsource/restbucks/payment/web/PaymentConfiguration.java +++ b/server/src/main/java/org/springsource/restbucks/payment/web/PaymentConfiguration.java @@ -15,13 +15,11 @@ */ package org.springsource.restbucks.payment.web; -import java.util.Map; - +import org.springframework.boot.jackson.JsonMixin; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.hateoas.mediatype.MediaTypeConfigurationCustomizer; import org.springframework.hateoas.mediatype.hal.forms.HalFormsConfiguration; -import org.springsource.restbucks.Mixins; import org.springsource.restbucks.payment.CreditCard; import org.springsource.restbucks.payment.CreditCardNumber; import org.springsource.restbucks.payment.Payment.Receipt; @@ -33,31 +31,21 @@ * @author Oliver Drotbohm */ @Configuration(proxyBeanMethods = false) -class PaymentConfiguration implements Mixins { +class PaymentConfiguration { @Bean MediaTypeConfigurationCustomizer paymentHalFormsCustomization() { return config -> config.withPattern(CreditCardNumber.class, CreditCardNumber.REGEX); } - /* - * (non-Javadoc) - * @see org.springsource.restbucks.Mixins#getMixins() - */ - @Override - public Map, Class> getMixins() { - return Map.of( // - Receipt.class, ReceiptMixin.class, // - CreditCard.class, CreditCardMixin.class // - ); - } - + @JsonMixin(Receipt.class) static abstract class ReceiptMixin { @JsonIgnore abstract Object getOrder(); } + @JsonMixin(CreditCard.class) @JsonAutoDetect(isGetterVisibility = JsonAutoDetect.Visibility.NONE) static abstract class CreditCardMixin {} } diff --git a/server/src/test/java/org/springsource/restbucks/JacksonTestUtils.java b/server/src/test/java/org/springsource/restbucks/JacksonTestUtils.java index 582f434f..2ebb3a09 100644 --- a/server/src/test/java/org/springsource/restbucks/JacksonTestUtils.java +++ b/server/src/test/java/org/springsource/restbucks/JacksonTestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2019 the original author or authors. + * Copyright 2015-2023 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. @@ -28,6 +28,6 @@ public class JacksonTestUtils extends JacksonCustomizations { public static Set getModules(Map, Class> mixins) { - return Set.of(new RestbucksModule(mixins), new MoneyModule()); + return Set.of(new MoneyModule()); } } diff --git a/server/src/test/java/org/springsource/restbucks/payment/PaymentServiceImplUnitTest.java b/server/src/test/java/org/springsource/restbucks/payment/PaymentServiceImplUnitTest.java index 1d32be2e..6e229885 100644 --- a/server/src/test/java/org/springsource/restbucks/payment/PaymentServiceImplUnitTest.java +++ b/server/src/test/java/org/springsource/restbucks/payment/PaymentServiceImplUnitTest.java @@ -16,9 +16,6 @@ package org.springsource.restbucks.payment; import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; - -import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -77,7 +74,7 @@ void rejectsAlreadyPaidOrder() { @Test void rejectsPaymentIfNoCreditCardFound() { - when(creditCardRepository.findByNumber(NUMBER)).thenReturn(Optional.empty()); + // when(creditCardRepository.findByNumber(NUMBER)).thenReturn(Optional.empty()); assertThatExceptionOfType(PaymentFailed.class) // .isThrownBy(() -> paymentService.pay(new Order(), NUMBER)) // diff --git a/server/src/test/java/org/springsource/restbucks/payment/web/CreditCardMarshallingTest.java b/server/src/test/java/org/springsource/restbucks/payment/web/CreditCardMarshallingTest.java index a5deca96..af6ee1f2 100644 --- a/server/src/test/java/org/springsource/restbucks/payment/web/CreditCardMarshallingTest.java +++ b/server/src/test/java/org/springsource/restbucks/payment/web/CreditCardMarshallingTest.java @@ -24,9 +24,11 @@ import org.jmolecules.jackson.JMoleculesModule; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springsource.restbucks.JacksonTestUtils; import org.springsource.restbucks.payment.CreditCard; import org.springsource.restbucks.payment.CreditCardNumber; +import org.springsource.restbucks.payment.Payment.Receipt; +import org.springsource.restbucks.payment.web.PaymentConfiguration.CreditCardMixin; +import org.springsource.restbucks.payment.web.PaymentConfiguration.ReceiptMixin; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; @@ -54,7 +56,8 @@ void setUp() { mapper.registerModule(new JavaTimeModule()); mapper.registerModule(new ParameterNamesModule()); mapper.registerModule(new JMoleculesModule()); - mapper.registerModules(JacksonTestUtils.getModules(new PaymentConfiguration().getMixins())); + mapper.addMixIn(Receipt.class, ReceiptMixin.class); + mapper.addMixIn(CreditCard.class, CreditCardMixin.class); } @Test @@ -71,8 +74,7 @@ void serializesCreditCardWithOutIdAndWithAppropriateMontshAndYears() throws Exce Configuration configuration = Configuration.defaultConfiguration().addOptions(Option.SUPPRESS_EXCEPTIONS); - Object read = JsonPath.compile("$.valid").read(result, configuration); - assertThat(read).isNull(); + assertThat(JsonPath.compile("$.valid"). read(result, configuration)).isNull(); } @Test