Каким образом Spring Cloud Config Server передает обычные текстовые файлы в клиентское приложение Config?

Что я реализовал до сих пор:

  1. Spring Cloud Config Server с "нативным" репо.

spring.profiles.active: native

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

  1. Config Server отправляет уведомление клиентскому приложению Config через RabbitMQ, как http://cloud.spring.io/spring-cloud-config/spring-cloud-config.html

  2. Клиентское приложение Config имеет аннотацию @RefreshScope для компонента EJB.

Итак, / config-repo имеет 3 файла - application.yaml, client.yaml и client.json. Все изменения свойств yaml будут автоматически перезагружены клиентским приложением Config. Однако client.json этого не сделал.

Основываясь на https://github.com/spring-cloud/spring-cloud-config/issues/147, я могу получить файл в клиентском приложении Config через вызов REST API для Config Server с помощью /{appname}/{profile}/{label}/client.json

Вопрос:

1) Config Server отслеживает изменения этого простого текстового файла как "нативный"?

2) как Config Client App автоматически перезагрузить этот client.json после его обновления? (У меня может быть задание по расписанию для вызова сервера Config, но это не идеально.)

2 ответа

Я слоняюсь вот так (еще не закончил): у меня есть spring.cloud.config.server.native.serach-location в виде списка URI через запятую

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

Я создал bean-компонент FileMonitorConfiguration (но у него есть некоторые проблемы, потому что он запланирован 2 раза, сам bean-компонент и экземпляр с расширенными возможностями Spring, я не знаком с этим)

И реализовал (просто черновик) 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;

    }
}

Клиент конфигурации: restTemplate.getForObject (" http://localhost:8080/application/default/master/testing-dev.json", String.class);

может получить содержимое файла суффикса.json, но я думаю, что он не получает содержимого файла, есть другой способ получить содержимое файла

Другие вопросы по тегам