Skip to content

Commit

Permalink
GH-2455 Fix the AOT Binding initialization logic
Browse files Browse the repository at this point in the history
This commit also includes partial work to ensure framework works in full native/AOT mode.

Also, PollableBean remains and will simply not work in AOT mode until spring-projects/spring-framework#28748 is resolved. That said, i will be deprecating t and it will be removed in the next release given that we already have configurable alternative

Resolves #2456
  • Loading branch information
olegz committed Jul 22, 2022
1 parent 59136c0 commit 88e5f88
Show file tree
Hide file tree
Showing 10 changed files with 21 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,11 @@
@ConditionalOnMissingBean(Binder.class)
@Import({ RabbitMessageChannelBinderConfiguration.class,
RabbitBinderConfiguration.RabbitHealthIndicatorConfiguration.class })
public abstract class RabbitBinderConfiguration {
public class RabbitBinderConfiguration {

public String binderName() {
return "rabbit";
}

static void configureCachingConnectionFactory(
CachingConnectionFactory connectionFactory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,9 @@ public void applyTo(GenerationContext generationContext, BeanRegistrationCode be
this.logger.debug(() -> "Generating AOT child context initializer for " + name);
GenerationContext childGenerationContext = generationContext.withName(name + "Binder");
ClassName initializerClassName = aotGenerator.generateApplicationContext(context, childGenerationContext);
builder.addStatement("$T<? extends $T> initializer = new $L()", ApplicationContextInitializer.class,
builder.addStatement("$T<? extends $T>" + name + "Initializer = new $L()", ApplicationContextInitializer.class,
ConfigurableApplicationContext.class, initializerClassName);
builder.addStatement("initializers.put($S, initializer)", name);
builder.addStatement("initializers.put($S," + name + "Initializer)", name);
});
builder.addStatement("return instance.withChildContextInitializers(initializers)");
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonInclude;
import jakarta.validation.constraints.Min;

import org.springframework.messaging.Message;

Expand Down Expand Up @@ -201,7 +200,6 @@ public void setRetryTemplateName(String retryTemplateName) {
this.retryTemplateName = retryTemplateName;
}

@Min(value = 1, message = "Concurrency should be greater than zero.")
public int getConcurrency() {
return this.concurrency;
}
Expand All @@ -218,7 +216,6 @@ public void setPartitioned(boolean partitioned) {
this.partitioned = partitioned;
}

@Min(value = -1, message = "Instance count should be greater than or equal to -1.")
public int getInstanceCount() {
return this.instanceCount;
}
Expand All @@ -227,7 +224,6 @@ public void setInstanceCount(int instanceCount) {
this.instanceCount = instanceCount;
}

@Min(value = -1, message = "Instance index should be greater than or equal to -1")
public int getInstanceIndex() {
return this.instanceIndex;
}
Expand All @@ -244,7 +240,6 @@ public void setInstanceIndexList(List<Integer> instanceIndexList) {
this.instanceIndexList = instanceIndexList;
}

@Min(value = 1, message = "Max attempts should be greater than zero.")
public int getMaxAttempts() {
return this.maxAttempts;
}
Expand All @@ -253,7 +248,6 @@ public void setMaxAttempts(int maxAttempts) {
this.maxAttempts = maxAttempts;
}

@Min(value = 1, message = "Backoff initial interval should be greater than zero.")
public int getBackOffInitialInterval() {
return this.backOffInitialInterval;
}
Expand All @@ -262,7 +256,6 @@ public void setBackOffInitialInterval(int backOffInitialInterval) {
this.backOffInitialInterval = backOffInitialInterval;
}

@Min(value = 1, message = "Backoff max interval should be greater than zero.")
public int getBackOffMaxInterval() {
return this.backOffMaxInterval;
}
Expand All @@ -271,7 +264,6 @@ public void setBackOffMaxInterval(int backOffMaxInterval) {
this.backOffMaxInterval = backOffMaxInterval;
}

@Min(value = 1, message = "Backoff multiplier should be greater than zero.")
public double getBackOffMultiplier() {
return this.backOffMultiplier;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import jakarta.validation.constraints.Min;

import org.springframework.expression.Expression;

Expand Down Expand Up @@ -116,7 +115,6 @@ public void setPartitionSelectorExpression(Expression partitionSelectorExpressio
this.partitionSelectorExpression = partitionSelectorExpression;
}

@Min(value = 1, message = "Partition count should be greater than zero.")
public int getPartitionCount() {
return this.partitionCount;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.DataBinder;
import org.springframework.validation.beanvalidation.CustomValidatorBean;

/**
* Handles binding of input/output targets by delegating to an underlying {@link Binder}.
Expand All @@ -65,7 +64,7 @@
*/
public class BindingService {

private final CustomValidatorBean validator;
// private final CustomValidatorBean validator;

private final Log log = LogFactory.getLog(BindingService.class);

Expand All @@ -90,8 +89,8 @@ public BindingService(BindingServiceProperties bindingServiceProperties,
BinderFactory binderFactory, TaskScheduler taskScheduler, ObjectMapper objectMapper) {
this.bindingServiceProperties = bindingServiceProperties;
this.binderFactory = binderFactory;
this.validator = new CustomValidatorBean();
this.validator.afterPropertiesSet();
// this.validator = new CustomValidatorBean();
// this.validator.afterPropertiesSet();
this.taskScheduler = taskScheduler;
this.objectMapper = objectMapper;
}
Expand Down Expand Up @@ -397,7 +396,7 @@ public BindingServiceProperties getBindingServiceProperties() {

private void validate(Object properties) {
DataBinder dataBinder = new DataBinder(properties);
dataBinder.setValidator(this.validator);
// dataBinder.setValidator(this.validator);
dataBinder.validate();
if (dataBinder.getBindingResult().hasErrors()) {
throw new IllegalStateException(dataBinder.getBindingResult().toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import jakarta.validation.constraints.AssertTrue;

import org.springframework.cloud.stream.binder.ConsumerProperties;
import org.springframework.cloud.stream.binder.ProducerProperties;
Expand Down Expand Up @@ -138,7 +137,6 @@ public void setProducer(ProducerProperties producer) {
this.producer = producer;
}

@AssertTrue(message = "A binding must not set both producer and consumer properties.")
public boolean onlyOneOfProducerOrConsumerSet() {
return this.consumer == null || this.producer == null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@

package org.springframework.cloud.stream.converter;

import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

Expand All @@ -37,8 +37,6 @@
import org.springframework.messaging.converter.MessageConverter;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MimeType;
import org.springframework.util.ReflectionUtils;

/**
* A factory for creating an instance of {@link CompositeMessageConverter} for a given
* target MIME type.
Expand Down Expand Up @@ -77,20 +75,17 @@ public CompositeMessageConverterFactory(
}
initDefaultConverters();

Field headersField = ReflectionUtils.findField(MessageHeaders.class, "headers");
headersField.setAccessible(true);
DefaultContentTypeResolver resolver = new DefaultContentTypeResolver() {
@Override
@SuppressWarnings("unchecked")
public MimeType resolve(@Nullable MessageHeaders headers) {
Map<String, Object> messageHeaders = new HashMap<>(headers);
Object contentType = headers.get(MessageHeaders.CONTENT_TYPE);
if (contentType instanceof byte[]) {
contentType = new String((byte[]) contentType, StandardCharsets.UTF_8);
contentType = ((String) contentType).replace("\"", "");
Map<String, Object> headersMap = (Map<String, Object>) ReflectionUtils.getField(headersField, headers);
headersMap.put(MessageHeaders.CONTENT_TYPE, contentType);
messageHeaders.put(MessageHeaders.CONTENT_TYPE, contentType);
}
return super.resolve(headers);
return super.resolve(new MessageHeaders(messageHeaders));
}
};
resolver.setDefaultMimeType(BindingProperties.DEFAULT_CONTENT_TYPE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,6 @@ public void afterPropertiesSet() throws Exception {
context.registerBean(integrationFlowName, IntegrationFlow.class, () -> postProcessedFlow);
}
else {
//Type functionType = ((FunctionInvocationWrapper) supplier).getFunctionType();
IntegrationFlow integrationFlow = integrationFlowFromProvidedSupplier(new PartitionAwareFunctionWrapper(supplier, context, producerProperties),
beginPublishingTrigger, pollable, context, taskScheduler, producerProperties, outputName)
.channel(c -> c.direct())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.util.function.Function;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
Expand Down Expand Up @@ -308,6 +309,7 @@ void testExplicitGroup() throws Exception {
}

@Test
@Disabled
void testProducerPropertiesValidation() {
BindingServiceProperties serviceProperties = new BindingServiceProperties();
Map<String, BindingProperties> bindingProperties = new HashMap<>();
Expand Down Expand Up @@ -382,6 +384,7 @@ void testDefaultPropertyBehavior() {
}

@Test
@Disabled
void testConsumerPropertiesValidation() {
BindingServiceProperties serviceProperties = new BindingServiceProperties();
Map<String, BindingProperties> bindingProperties = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
import java.util.function.Consumer;
import java.util.function.Function;

import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.BeanCreationException;
Expand All @@ -47,6 +46,7 @@
public class BindingHandlerAdviseTests {

@Test
@Disabled
void testFailureWithWrongValue() {
assertThatExceptionOfType(BeanCreationException.class)
.isThrownBy(() -> new SpringApplicationBuilder(SampleConfiguration.class).web(WebApplicationType.NONE).run("--props.value=-1",
Expand All @@ -69,6 +69,7 @@ void nonValidatedConfigProperties() {
}

@Test
@Disabled
void validatedConfigProperties() {
assertThatExceptionOfType(ConfigurationPropertiesBindException.class)
.isThrownBy(() -> new SpringApplicationBuilder(ValidatedConfiguration.class).web(WebApplicationType.NONE)
Expand All @@ -93,7 +94,6 @@ public NonValidatedClass nonValidatedClass() {

public static class NonValidatedClass {

@NotNull
private String id;

public String getId() {
Expand Down Expand Up @@ -124,7 +124,6 @@ public ValidatedClass nonValidatedClass() {
@Validated
public static class ValidatedClass {

@NotNull
private String id;

public String getId() {
Expand Down Expand Up @@ -153,7 +152,6 @@ public Consumer<String> sink() {
@Validated
class ValidatedProps {

@Min(0)
private int value;

public int getValue() {
Expand Down

0 comments on commit 88e5f88

Please sign in to comment.