Отключить клиент службы конфигурации, активированный с помощью spring.config.import в SpringBootTest

avatar
Henning
8 августа 2021 в 16:03
1350
3
5

У меня есть простое приложение Spring Boot

@SpringBootApplication
public class ClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(ClientApplication.class, args);
    }
}

, который подключается к серверу конфигурации Spring Cloud со следующим application.yml

spring:
  application:
    name: client

  config:
    import: configserver:http://localhost:8888

Приложение работает нормально, когда сервер конфигурации работает, и не работает должным образом, когда сервер не работает.

Теперь я хочу написать интеграционный тест с @SpringBootTest для приложения, которое не зависит от работающего сервера конфигурации и даже не пытается подключиться к нему.

При выключенном сервере конфигурации голый тест

@SpringBootTest
class ClientApplicationTests {
    @Test
    void contextLoads() {
    }
}

не работает с java.net.ConnectException: Connection refused, что и ожидалось.

При попытке отключить клиент конфигурации с помощью

@SpringBootTest(properties = "spring.cloud.config.enabled=false")

тест не пытается подключиться к серверу, но завершается ошибкой с

Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132)
    ...
Caused by: java.lang.IllegalStateException: Unable to load config data from 'configserver:http://localhost:8888'
    at org.springframework.boot.context.config.StandardConfigDataLocationResolver.getReferences(StandardConfigDataLocationResolver.java:141)
    ...
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)

Проблема заключается в том, что свойство spring.config.import, впервые представленное в Spring Boot 2.4, работает иначе, чем все остальные свойства. Мне кажется, что в него можно только добавлять значения, но нельзя удалять.

Есть ли способ переопределить spring.config.import в SpringBootTest? Есть ли способ запретить подключения только к серверам конфигурации?

Источник

Ответы (3)

avatar
Glapa
24 марта 2022 в 18:36
0

Если вам нужен диспетчер конфигурации везде, кроме тестов, то я думаю, что лучшим решением вашей проблемы будет поместить spring.config.import=configserver:http://localhost:8888 в файл /scr/main/resources/application.properties вместо файла .yml в корневом каталоге вашего проекта. Затем вы просто отключаете его в тестах с помощью spring.cloud.config.enabled=false.

.

Еще одно решение (если вы не хотите полностью отключать его, это добавить необязательное ключевое слово к этому импорту (spring.config.import=optional:configserver:http://localhost:8888(таким образом вы можете сохранить его в .yml, но вы потеряете возможность отключить его в тестах , но он просто проигнорирует тот факт, что сервер не работает.

avatar
roookeee
27 октября 2021 в 13:47
6

Решение только для тестов

configserver.import = configserver:https://localhost:8888
spring.config.import = ${configserver.import}

Таким образом, вы можете установить для свойства configserver.import пустую строку в ваших тестах:

configserver.import = 

Теперь пустое свойство spring.config.import больше не будет рассматриваться. Это будет работать даже с -D переопределениями параметров запуска JVM в рабочих средах.

Это должно быть сопряжено с spring.cloud.config.enabled=false в тестовых сценариях, так как конфигурация весеннего облака проверяет, чтобы хотя бы одно значение spring.config.import начиналось с префикса configserver:, и не позволит вам начать, если не найдет соответствующее свойство.

Ошибка

Caused by: java.lang.IllegalStateException: File extension is not known to any PropertySourceLoader

вызвано отключением конфигурации весеннего облака через spring.cloud.config.enabled=false, так как это также удаляет его bean-компонент PropertySourceLoader, который обрабатывает все configserver: с префиксом spring.config.import.

Решение для замены URL-адресов рабочей среды (также включает исправление для тестов)

Вот еще один вариант, который позволяет отключить URL-адрес сервера конфигурации в рабочих средах, поскольку несколько определений spring.config.import не переопределяют друг друга:

configserver.import = configserver:${CONFIG_SERVER_URL:https://localhost:8888}
spring.config.import = ${configserver.import}
spring.cloud.config.import-check.enabled = false

Зачем нам нужно это дополнение spring.cloud.config.import-check.enabled? Поскольку конфигурация весеннего облака требует по крайней мере одно префиксное значение configserver: в spring.config.import, но не разрешает замены свойств перед выполнением этой проверки. Поэтому конфигурация весеннего облака видит только ${configserver.import} как строку и предотвратит запуск вашего приложения. spring.cloud.config.import-check.enabled = false предотвращает вышеупомянутую проверку. Кроме того, переменная среды CONFIG_SERVER_URL может использоваться для переопределения сервера конфигурации localhost в рабочих средах, при этом позволяя spring.config.import быть пустой строкой, если configserver.import установлено пустым в тестах.

/rant: какой кошмар

ZachOfAllTrades
14 декабря 2021 в 19:20
1

кошмар прав - я обновляю кучу приложений с Spring Boot 2.3.x до 2.6.x - и это сводит меня с ума - неудивительно, что в большинстве статей на эту тему просто указывается, что вы можете включить устаревшие обработка - кажется, никто не знает, как сделать это "правильно"

roookeee
14 декабря 2021 в 19:54
0

К сожалению, нет «правильного» пути, просто это очень расстраивает.

avatar
Henning
8 августа 2021 в 18:24
5

Проведя дополнительные исследования, я обнаружил следующую проблему github: https://github.com/spring-cloud/spring-cloud-config/issues/1877

Мне кажется, что неудовлетворительное решение состоит в том, чтобы никогда не помещать spring.config.import в application.yml, если вам нужно переопределить его в тесте.

В частности, для сервера конфигурации его следует размещать только в файле конфигурации для конкретного профиля или в документе для конкретного профиля в составе нескольких документов application.yml. Затем вы можете активировать этот профиль в рабочей среде и оставить его неактивным на этапах тестирования и разработки.

.