Использование Spring-Cloud-Starter-AW за пределами AWS

Я пытаюсь использовать spring-cloud-starter-aws для одной цели - чтобы мой экземпляр ec2 мог получить доступ к своему узлу elasticache, используя логическое имя вместо физического имени. Моя проблема в том, что я хочу запустить этот двоичный файл в локальном контексте без AWS (без использования узла elasticache), но мне не удалось отключить. Я получаю исключение: возникла исключительная ситуация IOException при подключении к конечной точке службы: http://169.254.169.254/latest/dynamic/instance-identity/document. Исключение составляют:

Error creating bean with name 'org.springframework.cloud.aws.context.support.io.ResourceLoaderBeanPostProcessor#0': 
Cannot resolve reference to bean 'amazonS3'.

Я думаю, это связано с тем, что aws sdk вызывает конечную точку экземпляра, которая у меня не работает в локальном контексте. Как я могу это отключить?


person user2298491    schedule 30.08.2016    source источник
comment
Вы пробовали что-то подобное? stackoverflow.com/a/37162383/1199132   -  person Xtreme Biker    schedule 30.08.2016
comment
Я попытался поместить: aws: stack: auto: false в application.yml, и это не имело никакого значения. Я посмотрю раздел документации по ручной настройке. Спасибо.   -  person user2298491    schedule 31.08.2016


Ответы (2)


Благодаря предыдущему ответу @Martian приложение было изменено так

Сначала отключите компоненты автоконфигурации, связанные с AWS, в классе приложения.

@SpringBootApplication(exclude = {
org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.context.ContextCredentialsAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.context.ContextResourceLoaderAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.mail.MailSenderAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.cache.ElastiCacheAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.messaging.MessagingAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.jdbc.AmazonRdsDatabaseAutoConfiguration.class,
org.springframework.cloud.aws.autoconfigure.metrics.CloudWatchExportAutoConfiguration.class
})

Затем создайте выделенную конфигурацию загрузки Spring для AWS с соответствующими дополнительными настройками.

    /**
     * Only enable AWS related auto config when we run in AWS Cloud
     */
    @ConditionalOnAwsCloudEnvironment
    @Import({
        org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration.class,
        org.springframework.cloud.aws.autoconfigure.context.ContextCredentialsAutoConfiguration.class,
        org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration.class,
        org.springframework.cloud.aws.autoconfigure.context.ContextResourceLoaderAutoConfiguration.class,
        org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration.class,
        org.springframework.cloud.aws.autoconfigure.mail.MailSenderAutoConfiguration.class,
        org.springframework.cloud.aws.autoconfigure.cache.ElastiCacheAutoConfiguration.class,
        org.springframework.cloud.aws.autoconfigure.messaging.MessagingAutoConfiguration.class,
        org.springframework.cloud.aws.autoconfigure.jdbc.AmazonRdsDatabaseAutoConfiguration.class,
        org.springframework.cloud.aws.autoconfigure.metrics.CloudWatchExportAutoConfiguration.class
    })
    public class AwsConfig {
    }
person Sylvain    schedule 11.12.2019

spring-cloud-starter-aws использует spring-cloud-aws-autoconfigure, который предоставляет следующие конфигурации, связанные с AWS:

org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration
org.springframework.cloud.aws.autoconfigure.context.ContextCredentialsAutoConfiguration
org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration
org.springframework.cloud.aws.autoconfigure.context.ContextResourceLoaderAutoConfiguration
org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration
org.springframework.cloud.aws.autoconfigure.mail.MailSenderAutoConfiguration
org.springframework.cloud.aws.autoconfigure.cache.ElastiCacheAutoConfiguration
org.springframework.cloud.aws.autoconfigure.messaging.MessagingAutoConfiguration
org.springframework.cloud.aws.autoconfigure.jdbc.AmazonRdsDatabaseAutoConfiguration
org.springframework.cloud.aws.autoconfigure.metrics.CloudWatchExportAutoConfiguration

Все они запускаются EnableAutoConfiguration. Если вы можете жить без EnableAutoConfiguration, ваша проблема решена. Однако, поскольку вы используете spring-cloud-starter-aws, я не ожидаю, что это так.

К сожалению, только ContextInstanceDataAutoConfiguration и ContextInstanceDataAutoConfiguration используют @ConditionalOnAwsCloudEnvironment, остальные конфигурации запускаются независимо от среды. Большинство из них обусловлено только чем-то похожим на следующее (этот пример взят из ContextCredentialsAutoConfiguration):

@ConditionalOnClass(name = {"com.amazonaws.auth.AWSCredentialsProvider"})

Чтобы не запускать такую ​​конфигурацию, вам необходимо удалить класс com.amazonaws.auth.AWSCredentialsProvider из пути к классам. Этого можно достичь с помощью профилей maven или причудливой модульности, но я считаю, что это обычно неоптимальное решение, поскольку такая реструктуризация проекта имеет значительные побочные эффекты.

Я считаю, что самое простое решение - удалить spring-cloud-aws-autoconfigure из зависимостей проекта и написать собственные версии класса конфигурации. Вот версия ContextCredentialsAutoConfiguration, которая сработала для меня:

import mu.KLogging
import org.springframework.beans.factory.support.BeanDefinitionRegistry
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass
import org.springframework.cloud.aws.context.config.annotation.ContextDefaultConfigurationRegistrar
import org.springframework.cloud.aws.context.config.support.ContextConfigurationUtils
import org.springframework.context.EnvironmentAware
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Import
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar
import org.springframework.context.annotation.Profile
import org.springframework.core.env.Environment
import org.springframework.core.type.AnnotationMetadata

@Configuration
@Import(ContextDefaultConfigurationRegistrar::class, AwsContextCredentialsAutoConfiguration.Registrar::class)
@ConditionalOnClass(name = ["com.amazonaws.auth.AWSCredentialsProvider"])
@Profile("!it")
class AwsContextCredentialsAutoConfiguration {

    class Registrar : ImportBeanDefinitionRegistrar, EnvironmentAware {
        companion object: KLogging()
        private var environment: Environment? = null

        override fun setEnvironment(environment: Environment) {
            this.environment = environment
        }

        override fun registerBeanDefinitions(importingClassMetadata: AnnotationMetadata, registry: BeanDefinitionRegistry) {
            val useDefaultCredentialsChain = this.environment!!.getProperty("cloud.aws.credentials.useDefaultAwsCredentialsChain", Boolean::class.java, false)
            if (useDefaultCredentialsChain) {
                logger.debug("Using default AWS credentials provider")
                ContextConfigurationUtils.registerDefaultAWSCredentialsProvider(registry)
            } else {
                logger.debug("Using custom credentials provider (based on environment properties)")
                ContextConfigurationUtils.registerCredentialsProvider(
                        registry,
                        this.environment!!.getProperty("cloud.aws.credentials.accessKey"),
                        this.environment!!.getProperty("cloud.aws.credentials.secretKey"),
                        this.environment!!.getProperty("cloud.aws.credentials.instanceProfile", Boolean::class.java, true) as Boolean && !this.environment!!.containsProperty("cloud.aws.credentials.accessKey"),
                        this.environment!!.getProperty("cloud.aws.credentials.profileName", "default"),
                        this.environment!!.getProperty("cloud.aws.credentials.profilePath"))
            }

        }
    }
}

Обратите внимание на аннотацию @Profile ("! It"), это профиль, включенный для интеграционных тестов. Как следствие, конфигурация игнорируется во время интеграционных тестов, но вы можете заменить ее профилем, который вы используете для своего локального контекста.

person Marian    schedule 09.05.2018