spring-cloud / spring-cloud-config

External configuration (server and client) for Spring Cloud
Apache License 2.0
1.96k stars 1.29k forks source link

Make Spring Cloud Config Client Port Available via Property #455

Closed ulmermark closed 6 years ago

ulmermark commented 8 years ago

When discovering the Spring Cloud ConfigServer via Eureka, I would like to be able to have access to the full URL to the connected ConfigServer via properties during the bootstrap process.

Code below shows that the hostname, host ip address is available but not the port.

---snip---
package org.springframework.cloud.client;
---snip---

/**
 * @author Spencer Gibb
 */
public class HostInfoEnvironmentPostProcessor
---snip---

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment,
            SpringApplication application) {
        InetUtils.HostInfo hostInfo = getFirstNonLoopbackHostInfo(environment);
        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
        **map.put("spring.cloud.client.hostname", hostInfo.getHostname());
        map.put("spring.cloud.client.ipAddress", hostInfo.getIpAddress());**
        MapPropertySource propertySource = new MapPropertySource(
                "springCloudClientHostInfo", map);
        environment.getPropertySources().addLast(propertySource);
    }
dsyer commented 8 years ago

I think you misunderstood the feature implemented in that code snippet (it has nothing to do with a config server). I don't think it's a great idea to make data from the DiscoveryClient available as environment properties (since by design it can change at run time, and there is already a Java API to access it). Also, assuming we did add such a feature, it would also still be nothing to do with the config server. Maybe you could describe your use case in a bit more detail, so we can suggest an alternative?

ulmermark commented 8 years ago

Thanks for the reply.

The use case is when an application is wanting to "pull" plain text files from the "discovered" config server

Currently, our applications are configured as such in the config server application yml file.

Our applications discover the ConfigServer via Eureka and therefore the host/port are not configured anywhere in the application. When a plain text file is pulled from the ConfigServer on application startup, we would like the port of the discovered config server available just like the host is available with ${spring.cloud.client.hostname}

spring:
    profiles: local-cloud

# Port hardcoded for now until there is a property that contains the port
to the discovered Spring Cloud ConfigServer
# See org.springframework.cloud.client.HostInfoEnvironmentPostProcessor.java
logging:
    config: http://${spring.cloud.client.hostname}:8888/
spn-opss-svc/local-cloud/master/logback-spring.xml
dsyer commented 8 years ago

But spring.cloud.client.hostname is not the hostname of the config server, it is the hostname of the app that is running. So that config code is broken when you move the config server to a new host anyway. It would be better to autowire a ConfigClientProperties into the code where you need the URI and pull it out of that.

ulmermark commented 8 years ago

Dave,

Thanks, I will give this a whirl. I thought that property was the hostname of the "discovered" configserver.

Any recommendations on how to use the values in the ConfigClientProperties when the properties are replaced on the application yml file that is extracted from the config server?

Regards.

Mark

On Tue, Aug 16, 2016 at 9:24 AM, Dave Syer notifications@github.com wrote:

But spring.cloud.client.hostname is not the hostname of the config server, it is the hostname of the app that is running. So that config code is broken when you move the config server to a new host anyway. It would be better to autowire a ConfigClientProperties into the code where you need the URI and pull it out of that.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/spring-cloud/spring-cloud-config/issues/455#issuecomment-240117689, or mute the thread https://github.com/notifications/unsubscribe-auth/ADVJneZGv3SJB2vETFhwifOwznt8JEjRks5qgcgZgaJpZM4JWZAb .

spencergibb commented 8 years ago

You have a chicken and egg problem. If you weren't using discovery to find config server you could do it.

ulmermark commented 8 years ago

Dave,

I have attempted to implement an EnvironmentPostProcessor into spring.factories to add the discovered cloud configserver props to the environment mix so that the properties can be used during Property Replacement.

At the time postProcessEnvironment is called, configClientProperties is NULL so I do not believe this approach can work as it may be too early in the bootstrapping of the application.

The goal is to make the discovered URI of the configserver ( via Eureka) available to be used when serving up plain text files from the config server without having to hardcode host and/or port into the property value in the application yml file that is served up by the configserver.

such as when we reference the "remote" logback configuration file so that it can be pulled from the configserver.

We prefer to configure the application YML like the following when referencing "plain text" files.

logging: config: http:// ${spring.cloud.config.discovered.hostname}:${spring.cloud.config.discovered.port} /spn-opss-svc/local-cloud/master/logback-spring.xml

or even better

logging: config: http://_eureka name of configserver_ /spn-opss-svc/local-cloud/master/logback-spring.xml

The code I implemented is as such:

@Component public class SpringCloudConfigRuntimeEnvironmentPostProcessor implements EnvironmentPostProcessor {

@Autowired private ConfigClientProperties configClientProperties;

@Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { LinkedHashMap<String, Object> map = new LinkedHashMap<>(); map.put("spring.cloud.config.runtime.host", "serverGoesHere"); map.put("spring.cloud.config.runtime.port", "portGoesHere"); MapPropertySource propertySource = new MapPropertySource( "SpringCloudConfigRuntimeEnvironment", map); environment.getPropertySources().addLast(propertySource); }

}

dsyer commented 8 years ago

That's all good info. Please try to learn how to markdown to format your posts.