No se puede sondear desde S3 con una configuración de extremo de encargo

Xavier FRANCOIS:

Trato de usar spring-integration-awsal sondeo de un depósito de S3 para activar un trabajo de primavera-lote. Mi cubo S3 no está alojado en Amazon, que es en el servidor minio local, por lo que tengo una configuración personalizada:

    @Bean
    public AmazonS3 amazonS3(ConfigProperties configProperties) {

        return AmazonS3ClientBuilder.standard()
                .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://localhost:9001","eu-west-0")) // Region matches with minio region
                .withPathStyleAccessEnabled(configProperties.getS3().isPathStyle())
                .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(
                        configProperties.getS3().getAccessKey(), configProperties.getS3().getSecretKey()
                ))).build();
    }

He definido mi IntegrationFlow de esta manera:

  @Bean
    public IntegrationFlow s3InboundFlow() {

        S3RemoteFileTemplate template = new S3RemoteFileTemplate(new S3SessionFactory(amazonS3));
        S3StreamingMessageSource s3StreamingMessageSource = new S3StreamingMessageSource(template);
        s3StreamingMessageSource.setRemoteDirectory(String.format("%s/OUT/", configProperties.getS3().getBucketDataPath()));

        return IntegrationFlows.from(s3StreamingMessageSource, configurer -> configurer
                .id("s3InboundAdapter")
                .autoStartup(true)
                .poller(Pollers.fixedDelay(POLL, TimeUnit.SECONDS)))
                .handle(jobLaunchingGateway(jobRepository)) // Launch a spring-batch job
                .get();
    }

El problema es, cuando los sondeos se produjo, tengo el siguiente error:

Caused by: java.lang.IllegalStateException: S3 client with invalid S3 endpoint configured: localhost:9001
    at com.amazonaws.services.s3.AmazonS3Client.getRegion(AmazonS3Client.java:4270)

Esto sucede porque cuando se recibe el archivo, algunas cabeceras se establecen en primavera-integración-AWS:

AbstractRemoteFileStreamingMessageSource.java

return getMessageBuilderFactory()
            .withPayload(session.readRaw(remotePath))
            .setHeader(IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE, session)
            .setHeader(FileHeaders.REMOTE_DIRECTORY, file.getRemoteDirectory())
            .setHeader(FileHeaders.REMOTE_FILE, file.getFilename())
            .setHeader(FileHeaders.REMOTE_HOST_PORT, session.getHostPort())
            .setHeader(FileHeaders.REMOTE_FILE_INFO,
                                    this.fileInfoJson ? file.toJson() : file);

La REMOTE_HOST_PORTcabecera se establece gracias a getHostPort () método. El getHostPort () en S3Session.java continuación, llama al getRegion () método.

El getRegion () método en el AmazonS3Clientque no está comprobando si un valor se establece por el usuario en el campo signerRegionOverride. Sólo se comprueba si el anfitrión es vincular el "amazonaws.com" patrón.

@Override
    public String getHostPort() {
        Region region = this.amazonS3.getRegion().toAWSRegion();
        return String.format("%s.%s.%s:%d", AmazonS3.ENDPOINT_PREFIX, region.getName(), region.getDomain(), 443);
    }
   @Override
    public synchronized Region getRegion() {
        String authority = super.endpoint.getAuthority();
        if (Constants.S3_HOSTNAME.equals(authority)) {
            return Region.US_Standard;
        } else {
            Matcher m = Region.S3_REGIONAL_ENDPOINT_PATTERN.matcher(authority);
            if (m.matches()) {
                return Region.fromValue(m.group(1));
            } else {
                throw new IllegalStateException(
                    "S3 client with invalid S3 endpoint configured: " + authority);
            }
        }
    }

¿Cómo es posible pedirlos a S3 con una configuración de extremo a medida? ¿Por qué la getHostPort () método no comprobando la región de firma de valor? ¿Es posible solucionar esto?

Arteta:

Sí, es posible solución. Usted acaba de extender una S3SessionFactorypara devolver una extensión de S3Sessionla sobrescrito getHostPort()método para su punto final personalizado.

public class MyS3SessionFactory extends S3SessionFactory {

    private MyS3Session s3Session;

    @Override
    public S3Session getSession() {
        return s3Session;
    }

    public MyS3SessionFactory(AmazonS3 amazonS3) {
        super(amazonS3);
        Assert.notNull(amazonS3, "'amazonS3' must not be null.");
        this.s3Session = new MyS3Session(amazonS3);
    }
}
public class MyS3Session extends S3Session {

    public MyS3Session(AmazonS3 amazonS3) {
        super(amazonS3);
    }

    @Override
    public String getHostPort() {
        return "";
    }
}

Vamos a discutir una posible solución en el tema que usted ha planteado: https://github.com/spring-projects/spring-integration-aws/issues/160 !

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=367258&siteId=1
Recomendado
Clasificación