Home > Back-end >  Required a single bean, 2 found
Required a single bean, 2 found

Time:08-09

I am trying to build a springboot application integrated with S3 and SQS. I have an AppConfig, S3Config, SqsConfig wherein I autowire the S3Config and SqsConfig inside the AppConfig.

S3Config declares a bean s3client which I use to perform aws s3 operations. I am getting an error where in the autowiring is failing due to multiple bean definitions available but I'm not sure what part is causing what duplicacy. Attaching the snippets.

Note that I am creating a different definition of s3client bean depending on the profile ( local development vs server deployment )

AppConfig


import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Configuration
@Slf4j
@Component
@RefreshScope
@Getter
public class AppConfig {

    @Autowired
    S3Config s3Config;

    @Autowired
    SqsConfig sqsConfig;

}

S3Config


import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

@Configuration
@Slf4j
@Component
@RefreshScope
@Getter
public class S3Config {

    @Value("${aws.s3.roleArn}")
    private String s3RoleArn;

    @Value("${aws.s3.roleSessionName}")
    private String s3RoleSessionName;

    @Value("${aws.s3.region}")
    private String s3region;

    @Value("${aws.s3.inputBucketName}")
    private String inputBucketName;

    @Value("${aws.s3.outputBucketName}")
    private String outputBucketName;
    

    @Bean(name = "s3client")
    @Profile("!local")
    public AmazonS3 AmazonS3Client() {
        log.info(String.format("validating_config_repo_values: s3RoleArn=%s s3RoleSessionName=%s s3RoleSessionName=%s", s3RoleArn, s3RoleSessionName,s3region));
        AmazonS3 s3client = null;
        try {
            STSAssumeRoleSessionCredentialsProvider roleCredentialsProvider = new STSAssumeRoleSessionCredentialsProvider.Builder(
                    s3RoleArn, s3RoleSessionName).build();
            AmazonS3ClientBuilder amazonS3ClientBuilder = AmazonS3ClientBuilder.standard()
                    .withCredentials(roleCredentialsProvider);
            s3client = amazonS3ClientBuilder.withRegion(s3region).build();
        } catch (Exception e) {
            log.error(String.format("exception_while_creating_AmazonS3Client : %s", e));
        }
        return s3client;
    }

    @Bean(name = "s3client")
    @Profile("local")
    public AmazonS3 localhostAmazonS3Client() {
        AmazonS3 s3client = null;
        try {
            s3client = AmazonS3ClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).withCredentials(new DefaultAWSCredentialsProviderChain()).build();
        } catch (Exception e) {
            log.error(String.format("exception_while_creating_AmazonS3Client : %s", e));
        }
        return s3client;
    }


}

UploadServiceImpl


import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

@Service
@Slf4j
public class S3DatasetDownloadServiceImpl implements DatasetDownloadService {


    @Autowired
    AmazonS3 s3Client;

    @Autowired
    AppConfig appConfig;

    public String downloadDataset(URI uri) throws IOException {
        String key = uri.getPath();
        String outputBucketName = appConfig.getS3Config().getOutputBucketName();
        log.info(String.format("client_downloading_file : key=%s from bucket=%s",key,outputBucketName));
        try {
            
        } catch (Exception e) {            
        }
    }
}


CodePudding user response:

Kill me. Found the error, I have the bean name as s3client ( c of client small ) whereas on autowiring I am using AmazonS3 s3Client;

Fixing the casing worked!

  • Related