diff --git a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/config/NormalizedOperationMethod.java b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/config/NormalizedOperationMethod.java index 9e0b6216..d8f31d4a 100644 --- a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/config/NormalizedOperationMethod.java +++ b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/config/NormalizedOperationMethod.java @@ -28,6 +28,8 @@ import org.springframework.cloud.gateway.server.mvc.invoke.OperationParameter; import org.springframework.cloud.gateway.server.mvc.invoke.OperationParameters; import org.springframework.cloud.gateway.server.mvc.invoke.reflect.DefaultOperationMethod; import org.springframework.cloud.gateway.server.mvc.invoke.reflect.OperationMethod; +import org.springframework.core.annotation.MergedAnnotation; +import org.springframework.core.annotation.MergedAnnotations; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -52,8 +54,9 @@ public class NormalizedOperationMethod implements OperationMethod { } public boolean isConfigurable() { - Configurable annotation = delegate.getMethod().getAnnotation(Configurable.class); - return annotation != null && delegate.getParameters().getParameterCount() == 1; + MergedAnnotation configurable = MergedAnnotations.from(delegate.getMethod()) + .get(Configurable.class); + return configurable.isPresent() && delegate.getParameters().getParameterCount() == 1; } @Override @@ -72,8 +75,10 @@ public class NormalizedOperationMethod implements OperationMethod { private Map normalizeArgs(Map operationArgs) { if (hasGeneratedKey(operationArgs)) { - Shortcut shortcut = getMethod().getAnnotation(Shortcut.class); - if (shortcut != null) { + MergedAnnotation shortcutMergedAnnotation = MergedAnnotations.from(delegate.getMethod()) + .get(Shortcut.class); + if (shortcutMergedAnnotation.isPresent()) { + Shortcut shortcut = shortcutMergedAnnotation.synthesize(); String[] fieldOrder = getFieldOrder(shortcut); return switch (shortcut.type()) { case DEFAULT -> { diff --git a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/config/RouterFunctionHolderFactory.java b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/config/RouterFunctionHolderFactory.java index e75b259f..e10a06b0 100644 --- a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/config/RouterFunctionHolderFactory.java +++ b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/config/RouterFunctionHolderFactory.java @@ -16,7 +16,9 @@ package org.springframework.cloud.gateway.server.mvc.config; +import java.util.Arrays; import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -233,6 +235,11 @@ public class RouterFunctionHolderFactory { if (handlerFilterFunction != null) { operationHandler.accept(handlerFilterFunction); } + if (log.isDebugEnabled()) { + log.debug(LogMessage.format("Yaml Properties matched Operations name: %s, args: %s, params: %s", + normalizedName, opMethod.getNormalizedArgs().toString(), + Arrays.toString(opMethod.getParameters().stream().toArray()))); + } } else { throw new IllegalArgumentException(String.format("Unable to find operation %s for %s with args %s", @@ -244,6 +251,7 @@ public class RouterFunctionHolderFactory { String operationName, Map operationArgs) { return operations.getOrDefault(operationName, Collections.emptyList()) .stream() + .sorted(Comparator.comparing(OperationMethod::isConfigurable)) .map(operationMethod -> new NormalizedOperationMethod(operationMethod, operationArgs)) .filter(opeMethod -> matchOperation(opeMethod, operationArgs)) .findFirst(); @@ -272,7 +280,7 @@ public class RouterFunctionHolderFactory { Map args = new HashMap<>(); if (operationMethod.isConfigurable()) { OperationParameter operationParameter = operationMethod.getParameters().get(0); - Object config = bindConfigurable(operationMethod, args, operationParameter); + Object config = bindConfigurable(operationMethod, operationArgs, operationParameter); args.put(operationParameter.getName(), config); } else { diff --git a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/CircuitBreakerFilterFunctions.java b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/CircuitBreakerFilterFunctions.java index 54ae1709..ba522460 100644 --- a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/CircuitBreakerFilterFunctions.java +++ b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/CircuitBreakerFilterFunctions.java @@ -68,7 +68,7 @@ public abstract class CircuitBreakerFilterFunctions { return circuitBreaker(config); } - @Shortcut + @Shortcut("id") @Configurable public static HandlerFilterFunction circuitBreaker(CircuitBreakerConfig config) { Set failureStatuses = config.getStatusCodes() diff --git a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/RetryFilterFunctions.java b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/RetryFilterFunctions.java index ac8358f0..8a550ce2 100644 --- a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/RetryFilterFunctions.java +++ b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/RetryFilterFunctions.java @@ -48,6 +48,7 @@ public abstract class RetryFilterFunctions { private RetryFilterFunctions() { } + @Shortcut public static HandlerFilterFunction retry(int retries) { return retry(config -> config.setRetries(retries)); } @@ -58,7 +59,7 @@ public abstract class RetryFilterFunctions { return retry(config); } - @Shortcut + @Shortcut({ "retries", "series", "methods" }) @Configurable public static HandlerFilterFunction retry(RetryConfig config) { RetryTemplateBuilder retryTemplateBuilder = RetryTemplate.builder(); diff --git a/spring-cloud-gateway-server-mvc/src/test/resources/application-propertiesbeandefinitionregistrartests.yml b/spring-cloud-gateway-server-mvc/src/test/resources/application-propertiesbeandefinitionregistrartests.yml index d27c4c76..5270b8cb 100644 --- a/spring-cloud-gateway-server-mvc/src/test/resources/application-propertiesbeandefinitionregistrartests.yml +++ b/spring-cloud-gateway-server-mvc/src/test/resources/application-propertiesbeandefinitionregistrartests.yml @@ -34,6 +34,7 @@ spring.cloud.gateway.mvc: - HttpbinUriResolver= - TokenRelay - AddRequestHeader=X-Test,listRoute2 + - Retry=3,SERVER_ERROR - id: listRoute3 uri: lb://httpbin predicates: