I have a Java Spring config client application ("A") that works with my config server ("B"). I also have an application.yaml configuration file in project "A". If the contents of the application.yaml file are:
spring:
config:
import: configserver:http://localhost:8080/config
activate:
on-profile: useConfigServer
cloud:
config:
enabled: true
Everything works perfectly. However, if I try to set the import property with my custom actuator endpoint in "B" like this:
spring:
config:
import: configserver:http://config-server-1-9-int/actuator/getconfigurations/proxy-gw-1-8-c78d88cbf-nfbh4/proxy-gw/useConfigServer,dev
I am getting an exception:
[main] ERROR org.springframework.boot.SpringApplication - Application run failed
java.lang.IllegalStateException: Unable to load config data from 'dev'
at org.springframework.boot.context.config.StandardConfigDataLocationResolver.getReferences(StandardConfigDataLocationResolver.java:141)
at org.springframework.boot.context.config.StandardConfigDataLocationResolver.getReferences(StandardConfigDataLocationResolver.java:126)
at org.springframework.boot.context.config.StandardConfigDataLocationResolver.resolve(StandardConfigDataLocationResolver.java:119)
at org.springframework.boot.context.config.ConfigDataLocationResolvers.lambda$resolve$1(ConfigDataLocationResolvers.java:115)
at org.springframework.boot.context.config.ConfigDataLocationResolvers.resolve(ConfigDataLocationResolvers.java:126)
at org.springframework.boot.context.config.ConfigDataLocationResolvers.resolve(ConfigDataLocationResolvers.java:115)
at org.springframework.boot.context.config.ConfigDataLocationResolvers.resolve(ConfigDataLocationResolvers.java:107)
at org.springframework.boot.context.config.ConfigDataImporter.resolve(ConfigDataImporter.java:105)
at org.springframework.boot.context.config.ConfigDataImporter.resolve(ConfigDataImporter.java:97)
at org.springframework.boot.context.config.ConfigDataImporter.resolveAndLoad(ConfigDataImporter.java:85)
at org.springframework.boot.context.config.ConfigDataEnvironmentContributors.withProcessedImports(ConfigDataEnvironmentContributors.java:116)
at org.springframework.boot.context.config.ConfigDataEnvironment.processWithProfiles(ConfigDataEnvironment.java:311)
at org.springframework.boot.context.config.ConfigDataEnvironment.processAndApply(ConfigDataEnvironment.java:232)
at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:102)
at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:94)
at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEnvironmentPreparedEvent(EnvironmentPostProcessorApplicationListener.java:102)
at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEvent(EnvironmentPostProcessorApplicationListener.java:87)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:131)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:85)
at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:66)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:120)
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:114)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:65)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:343)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:301)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:164)
at com.poalim.modernization.infra.Application.main(Application.java:34)
Caused by: java.lang.IllegalStateException: File extension is not known to any PropertySourceLoader. If the location is meant to reference a directory, it must end in '/' or File.separator
at org.springframework.boot.context.config.StandardConfigDataLocationResolver.getReferencesForFile(StandardConfigDataLocationResolver.java:229)
at org.springframework.boot.context.config.StandardConfigDataLocationResolver.getReferences(StandardConfigDataLocationResolver.java:138)
... 30 common frames omitted
Process finished with exit code 1
And in this case, the actuator endpoint in "B" is not accessed (during debugging). Please pay attention to the fact that if I perform a REST request from "A" to "B" to the address http://config-server-1-9-int/actuator/getconfigurations/proxy-gw-1-8-c78d88cbf-nfbh4/proxy-gw/useConfigServer,dev, everything works perfectly, and I get the Environment object (configurations) in response.
application.yaml in config server "B":
spring:
application:
name: config-server
cloud:
config:
server:
health:
enabled: false
prefix: /config
I also tried to change the prefix in all of the combinations.
Actuator endpoint in config-server "B":
@Component
@Endpoint(id = "getconfigurations")
@RequiredArgsConstructor
public class GetConfigurationsEndpoint {
private final RefreshConfigsManagementService refreshConfigsManagementService;
@ReadOperation
// (produces = EnvironmentMediaType.V2_JSON)
public Environment getConfigurations(@Selector String podId, @Selector String serviceName, @Selector String profilesList) {
return refreshConfigsManagementService.getConfigurations(
PodId.builder()
.id(podId)
.service(serviceName)
.profilesList(profilesList)
.build()
);
}
}
That's works perfect if I perform REST request.
The exception thrown from org.springframework.boot.context.config.StandardConfigDataLocationResolver:
private Set getReferencesForFile(ConfigDataLocation configDataLocation, String file, String profile) { Matcher extensionHintMatcher = EXTENSION_HINT_PATTERN.matcher(file); boolean extensionHintLocation = extensionHintMatcher.matches(); if (extensionHintLocation) { file = extensionHintMatcher.group(1) + extensionHintMatcher.group(2); } for (PropertySourceLoader propertySourceLoader : this.propertySourceLoaders) { String extension = getLoadableFileExtension(propertySourceLoader, file); if (extension != null) { String root = file.substring(0, file.length() - extension.length() - 1); StandardConfigDataReference reference = new StandardConfigDataReference(configDataLocation, null, root, profile, (!extensionHintLocation) ? extension : null, propertySourceLoader); return Collections.singleton(reference); } } throw new IllegalStateException("File extension is not known to any PropertySourceLoader. " + "If the location is meant to reference a directory, it must end in '/' or File.separator"); }
Debugger is accessing this method only when I trying to make spring access to the actuator endpoint on application loading. I need that because I need to know in my config-server which application is accessing. In my company rest requests network is only option at this moment. I can't use KAFKA or RabbitMq or something else.
Best Regards, Please help❤✌