Spring Mon go Populator один за другим - PullRequest
2 голосов
/ 16 марта 2020

Я использую MongoDB и Spring поверх Kotlin и хочу, чтобы мое приложение заполняло коллекцию MongoDB при запуске. (и очищайте его каждый раз, когда он запускается)

Мой вопрос: как я могу заполнить данные один за другим, чтобы обеспечить отказоустойчивость в случае проблем с некоторыми данными, которые я заполняю? c ?

мой код:

@Configuration
class IndicatorPopulator {
    @Value("classpath:indicatorData.json")
    private lateinit var data: Resource

    @Autowired
    private lateinit var indicatorRepository: IndicatorRepository

    @Bean
    @Autowired
    fun repositoryPopulator(objectMapper: ObjectMapper): Jackson2RepositoryPopulatorFactoryBean {
        val factory = Jackson2RepositoryPopulatorFactoryBean()
        indicatorRepository.deleteAll()
        factory.setMapper(objectMapper)
        factory.setResources(arrayOf(data))
        return factory
    }

Я ищу что-то вроде:

@Bean
@Autowired
fun repositoryPopulator(objectMapper: ObjectMapper): Jackson2RepositoryPopulatorFactoryBean {
    val factory = Jackson2RepositoryPopulatorFactoryBean()
    indicatorRepository.deleteAll()
    factory.setMapper(objectMapper)
    val arrayOfResources: Array<Resource> = arrayOf(data)
    for (resource in arrayOfResources){
            try{
             factory.setResources(resource)
            } catch(e: Exception){
                 logger.log(e.message)
            }

    }
    return factory
}

Любая идея о том, как сделать что-то подобное, будет полезной. .. Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 19 апреля 2020

Используя Sagar's Reader & Factory, я просто настроил его так, чтобы он соответствовал моим потребностям (Kotlin, и ресурсы для чтения из одного и того же файла JSON), и получил ответ:

@Configuration
class IndicatorPopulator {

@Value("classpath:indicatorData.json")
private lateinit var data: Resource

@Autowired
private lateinit var indicatorRepository: IndicatorRepository

@Autowired
@Bean
fun repositoryPopulator(objectMapper: ObjectMapper): Jackson2RepositoryPopulatorFactoryBean {
    val factory: Jackson2RepositoryPopulatorFactoryBean = CustomJackson2RepositoryPopulatorFactoryBean()
    factory.setMapper(objectMapper)
    // inject your Jackson Object Mapper if you need to customize it:
    indicatorRepository.deleteAll()


    val resources = mutableListOf<Resource>()
    val readTree: ArrayNode = objectMapper.readTree(data.inputStream) as ArrayNode
    for (node in readTree){
        resources.add( InputStreamResource(node.toString().byteInputStream()))
    }
    factory.setResources(resources.toTypedArray())
    return factory
}

}

1 голос
/ 10 апреля 2020

Нет встроенной поддержки для вашего запроса, но вы можете легко обеспечить, настроив несколько классов.

Добавление пользовательской программы Jackson 2 Reader

public class CustomJackson2ResourceReader implements ResourceReader {

    private static final Logger logger = LoggerFactory.getLogger(CustomJackson2ResourceReader.class);

    private final Jackson2ResourceReader resourceReader = new Jackson2ResourceReader();

    @Override
    public Object readFrom(Resource resource, ClassLoader classLoader) throws Exception {
        Object result;
        try {
            result = resourceReader.readFrom(resource, classLoader);
        } catch(Exception e) {
            logger.warn("Can't read from resource", e);
            return Collections.EMPTY_LIST;
        }
        return result;
    }
}

Добавление пользовательской программы Jackson 2 Populator

public class CustomJackson2RepositoryPopulatorFactoryBean extends Jackson2RepositoryPopulatorFactoryBean {
    @Override
    protected ResourceReader getResourceReader() {
        return new CustomJackson2ResourceReader();
    }
}

Конфигурация

@SpringBootApplication
public class DemoApplication {

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

    @Bean
    public AbstractRepositoryPopulatorFactoryBean repositoryPopulator(ObjectMapper objectMapper, KeyValueRepository keyValueRepository) {
        Jackson2RepositoryPopulatorFactoryBean factory = new CustomJackson2RepositoryPopulatorFactoryBean();
        keyValueRepository.deleteAll();
        factory.setMapper(objectMapper);
        factory.setResources(new Resource[]{new ClassPathResource("badclassname.json"), new ClassPathResource("good.json"), new ClassPathResource("malformatted.json")});
        return factory;
    }

}

Я загружаю рабочую пример здесь

...