Spring @Validated аннотация предотвращает внедрение значения @ConfigurationProproperties, почему? - PullRequest
0 голосов
/ 02 апреля 2019

Я пытаюсь с @ConfigurationProperties, и я нахожу две вещи:

  • чтобы тесты работали, я должен поместить файлы свойств конфигурации (yml) в пакет test; сеттеры и пустой конструктор обязательны.
  • Если я аннотирую класс @Validated, внедрение просто завершится неудачей со всеми значениями null.

Если вы скажете, что первое понятно, а второе? Почему?

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

У меня есть эта привязка к карте:

accertify:
  fr:
    merchant1:
      host: "sandbox.accertify.dev"
      protocol: "https"
      user: "fraud"
      password: "temporal"
      merchant: "merchant1FR"
    merchant2:
      host: "sandbox.accertify.dev"
      protocol: "https"
      user: "fraud"
      password: "temporal"
      merchant: "merchant2FR"
  es:
    merchant1:
      host: "sandbox.accertify.dev"
      protocol: "https"
      user: "fraud"
      password: "temporal"
      merchant: "merchant1ES"
    merchant2:
      host: "sandbox.accertify.dev"
      protocol: "https"
      user: "fraud"
      password: "temporal"
      merchant: "merchant2ES"

У меня есть этот класс для отображения вложенных конфигураций:

import com.westerngun.fraud.jfps.dto.provider.accertify.country.ConfigurationEs;
import com.westerngun.fraud.jfps.dto.provider.accertify.country.ConfigurationFr;
import com.westerngun.fraud.jfps.service.client.ConnectionDetailsInterface;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.annotation.Validated;

import javax.validation.Valid;

/**
 * Class to read Accertify provider connection credentials.
 */
@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "accertify")
@Validated   // <--- this seems the problem
@NoArgsConstructor
@AllArgsConstructor
public class AccertifyConnectionDetail extends ConnectionDetails {

    @Valid
    private ConfigurationFr fr;

    @Valid
    private ConfigurationEs es;
}

И, его интерфейс:

public abstract class ConnectionDetails {
    public abstract ConfigurationFr getFr();
    public abstract ConfigurationEs getEs();
}

И, ConfigurationEs и ConfigurationFr являются подклассами:

@Component
public class CountryConfigDetail {
    @Getter
    @Setter
    @Valid
    private Merchant1 merchant1;

    @Getter
    @Setter
    @Valid
    private Merchant2 merchant2;
}

Merchant1 и Merchant2 подкласс:

@Data
@Component
public class MerchantConfigDetail {

    @NotEmpty
    @NotNull
    private String user;

    @NotEmpty
    @NotNull
    private String password;

    ...
    @NotEmpty
    @NotNull
    private Map<String, String> headers;
}

Когда я пытаюсь внедрить в некоторые @Autowired тесты без @Validated в первом классе, это работает (fr и es имеют значения в файле yml)

enter image description here

Когда я добавляю @Validated, fr и es равны нулю.

Тест:

@RunWith(SpringRunner.class)
@SpringBootTest
public class AccertifyConfigurationTest {

    @Autowired
    private AccertifyConnectionDetail accertifyConnectionDetail; // <--- this field should be injected


    @Test
    public void givenAAccertifyClientService_WhenClientIsBuild_ShouldHaveTheProviderConfigurationCorrect() {
        AccertifyConfiguration accertifyConfiguration = new AccertifyConfiguration(accertifyConnectionDetail);
        accertifyConfiguration.buildConfiguration("FR", "Merchant1");

        Assert.assertEquals("fraud", accertifyConfiguration.getUser());
        Assert.assertEquals("temporal", accertifyConfiguration.getPassword());
        Assert.assertTrue(accertifyConfiguration.getHost().startsWith("sandbox.accertify."));
        Assert.assertEquals("merchant1FR", accertifyConfiguration.getMerchantCode());
    }
...
...