Closed torsten-liermann closed 6 years ago
I'm not sure what you want to do but maybe a custom mappings provider is what you need: https://github.com/mkopylec/charon-spring-boot-starter#mappings If not please provide more details.
More details: I like the configuration of the mapping in the application.yml. But in my case, the port @docindex.api.port@
is determined at runtime. So it would be convenient to subsequently correct the destination URLs.
charon: mappings: - name: forward to local external api path: /docindex/api destinations: http://127.0.0.1:@docindex.api.port@/docindex/api
Background why dynamically ports: My spring-boot app starts an external process (via de.flapdoodle.embed) which picks a random free port for this service.
Ok, and how you would now what is the value of @docindex.api.port@
?
If your backend app wil restart you need to update the @docindex.api.port@
value, how will you handle that?
If you have a solution how you can update the yml file when your backend is restarted than you could do something like:
some.port: @docindex.api.port@
charon:
mappings:
- name: forward to local external api
path: /docindex/api
destinations: http://127.0.0.1:${some.port}/docindex/api
Do you know the embedded mongodb construct in spring-boot? If not: spring-boot starts an embedded mongo DB with a calculated random port und put the value into the enviroment. The code looks like:
private void setPortProperty(ApplicationContext currentContext, final int port) {
if (currentContext instanceof ConfigurableApplicationContext) {
MutablePropertySources sources = ((ConfigurableApplicationContext) currentContext)
.getEnvironment().getPropertySources();
if (sources.get("local.restheart.port") == null) {
PropertySource<String> propertySource = new PropertySource<String>("docindex.api.port") {
@Override
public Object getProperty(String name) {
return "docindex.api.port".equals(name) ? port : null;
}
};
sources.addFirst(propertySource);
}
}
if (currentContext.getParent() != null) {
setPortProperty(currentContext.getParent(), port);
}
}
All consumers who need this information, for example the Mongo Client, get this value from the environment -- Sorry, I can not express myself in English.
My first attempt at a solution looked like this:
@Bean
public CustomMappingsProvider customMappingsProvider(
ServerProperties serverProperties,
CharonProperties charonProperties,
MappingsCorrector mappingsCorrector,
HttpClientProvider httpClientProvider,
Environment environment) {
String docindexApiPort = environment.getProperty("docindex.api.port");
if (docindexApiPort != null) {
for (MappingProperties mappings : charonProperties.getMappings()) {
for (int i = 0; i < mappings.getDestinations().size(); i++) {
if (mappings.getDestinations().get(i).contains("@docindex.api.port@")) {
String correctedUrl = mappings.getDestinations().get(i).replace("@docindex.api.port@", docindexApiPort);
mappings.getDestinations().set(i, correctedUrl);
}
}
}
}
....
}
Unfortunately, this correction takes place too late.
Thanks for listening: this is a solution:
@Bean
public MappingsProvider charonMappingsProvider(CharonProperties charon, ServerProperties server, MappingsCorrector mappingsCorrector, HttpClientProvider httpClientProvider, Environment environment) {
String localApiPort = environment.getProperty("local.api.port");
if (localApiPort != null) {
correctProxyDestinations(charon.getMappings(), localApiPort );
}
return new ConfigurationMappingsProvider(server, charon, mappingsCorrector, httpClientProvider);
}
Great, can we close the issue then?
Yes. Thanks for Your support.
Hi,
Thanks for this handy reverse proxy.
Is it possible to manipulate subsequent mappings from the configuration? I need a way to put the port later.
Thanks, Torstem