TJReinert
TJReinert

Reputation: 347

Spring cloud gateway refresh with RewritePath fails

I'm running a spring cloud gateway instance that relies on spring cloud configuration server. My application starts up with the given following configuration.

  cloud:
    gateway:
      routes:
        - id: route-foo
          uri: lb://foo
          predicates:
            - Path=/api/foo/**
          filters:
            - name: RewritePath
              args:
                regexp: "/api/foo/(?<remaining>.*)"
                replacement: "/${remaining}"  

Say I make a modification to my configuration and add an additional route below

        - id: route-bar
          uri: lb://bar
          predicates:
            - Path=/api/bar/**
          filters:
            - name: RewritePath
              args:
                regexp: "/api/bar/(?<remaining>.*)"
                replacement: "/${remaining}"  

Executing a POST to http://localhost:8080/actuator/refresh returns the following error.

500 Server Error for HTTP POST &#34;/actuator/refresh&#34; (Encoded)
java.lang.IllegalArgumentException: Could not resolve placeholder 'remaining' in value "/${remaining}"
    at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:178)

It appears that spring is trying to parse my RewritePath replacement and substitute it with environment variables. What are my options?

Upvotes: 0

Views: 2819

Answers (1)

TJReinert
TJReinert

Reputation: 347

You're running into spring trying to replace variables in your configuration.

There are two solutions

Escape the replacement syntax (Preferred)

change replacement: "/${remaining}"

to replacement: "/$\\{remaining}"

The RewriteGatewayFilterFactory does a replace on the configuration before running the filter.



Enable ignoreUnresolvableNestedPlaceholders

@Bean
@Primary
public StandardReactiveWebEnvironment standardReactiveWebEnvironmentCustomizer(StandardReactiveWebEnvironment environment) {
    environment.setIgnoreUnresolvableNestedPlaceholders(true);
    return environment;
}

This will leave all unresolvable placeholders alone in your configuration and not fail during the refresh. I would recommend against this approach as it may end up delaying some issues into runtime if you're relying on a field to be populated correctly.

Theoretically you should be able to accomplish this same functionality with the PropertySourcesPlaceholderConfigurer, I had a hard time getting that to cooperate.

Upvotes: 0

Related Questions