How Spring Cloud Config Server PUSH plain text files to Config Client Application?

最后都变了- 提交于 2019-12-08 08:52:50

问题


What I have implemented so far are:

  1. Spring Cloud Config Server with "native" repo.

spring.profiles.active: native

spring.cloud.config.server.native.searchLocations: file:/path/to/config-repo

  1. Config Server is pushing notification to Config Client App through RabbitMQ, as http://cloud.spring.io/spring-cloud-config/spring-cloud-config.html#_push_notifications_and_spring_cloud_bus

  2. Config Client App has @RefreshScope annotated on Service bean.

So /config-repo has 3 files - application.yaml, client.yaml and client.json All yaml properties changes will be auto reloaded by Config Client App for sure. However, client.json didn't.

Based on https://github.com/spring-cloud/spring-cloud-config/issues/147, I can fetch the file on Config Client App through REST api call to Config Server, with /{appname}/{profile}/{label}/client.json

Question are:

1) Is Config Server monitoring this plain text file changes by "native"?

2) how can Config Client App auto reload this client.json once it's updated? (I can have schedule task to call Config server, but this isn't ideal.)


回答1:


i am sloving like this way (not finnished yet): i have spring.cloud.config.server.native.serach-locations in form of comma separated list of URIs

file:/c:/repo/a,file:/c:/repo/b

I created FileMonitorConfiguration bean (but it have some problem, because it is scheduled 2 times, a bean itself and a spring enhaced instance, I am not fammiliar with this)

And implemented (just draft) NativePropertyPathNotificationExtractor

@Configuration
@EnableAutoConfiguration
@EnableConfigServer
public class ConfigServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }

    @Bean
    NativePropertyPathNotificationExtractor nativePropertyPathNotificationExtractor(@Autowired(required = false) NativeEnvironmentRepository nativeRepo) {
        return new NativePropertyPathNotificationExtractor(nativeRepo);
    }

    @Bean
    FileMonitorConfiguration fileMonitorConfiguration() {
        return new FileMonitorConfiguration();
    }
}

@Order(Ordered.LOWEST_PRECEDENCE - 500)
public class NativePropertyPathNotificationExtractor implements PropertyPathNotificationExtractor {
    private final Set<Path> searchPaths;

    public NativePropertyPathNotificationExtractor(NativeEnvironmentRepository nativeRepo) {
        searchPaths = searchLocations(nativeRepo);
    }

    @Override
    public PropertyPathNotification extract(MultiValueMap<String, String> headers, Map<String, Object> payload) {

        // FileMonitor with empty headers, so if some there, ignore
        if (false == headers.isEmpty()) {
            return null;
        }
        if (null == searchPaths) {
            return null;
        }

        Path path = pathFromPayload(payload);
        if (null == path) {
            return null;
        }

        for (Path searchPath : searchPaths) {
            Path relative = searchPath.relativize(path);
            // just a try ;-)
            if (true == relative.startsWith("..")) {
                continue;
            }

            return new PropertyPathNotification(relative.toString());
        }

        return null;
    }

    private Path pathFromPayload(Map<String, Object> payload) {
        if (null == payload) {
            return null;
        }
        if (true == payload.isEmpty()) {
            return null;
        }
        if (false == payload.containsKey("path")) {
            return null;
        }
        if (null == payload.get("path")) {
            return null;
        }
        if (true == StringUtils.isEmpty(payload.get("path").toString())) {
            return null;
        }
        return Paths.get(payload.get("path").toString()).normalize().toAbsolutePath();
    }

    private Set<Path> searchLocations(NativeEnvironmentRepository nativeRepo) {
        if (null == nativeRepo) {
            return null;
        }
        if (null == nativeRepo.getSearchLocations()) {
            return null;
        }

        final Set<Path> paths = new LinkedHashSet<>();
        for (String location : nativeRepo.getSearchLocations()) {
            try {
                paths.add(Paths.get(new URI(location)).normalize().toAbsolutePath());
            } catch (Exception e) {
                System.err.println("Nevalidne search location uri: " + location);
            }
        }
        return paths;

    }
}



回答2:


the Config client: restTemplate.getForObject("http://localhost:8080/application/default/master/testing-dev.json",String.class);

can get the .json suffix file content ,but i think it don't get the file content ,have other way to get the file content



来源:https://stackoverflow.com/questions/40608323/how-spring-cloud-config-server-push-plain-text-files-to-config-client-applicatio

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!