0

I have a product controller and my goal is to receive an upload image, save the url in my database and send the image to amazonS3. In my settings I have the S3Client configuration like this:

package com.api.business_manager_api.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;

@Configuration
public class AmazonConfig {
    private final String AWS_REGION = "us-east-1";
    private final String BUCKET_NAME = "stockproducts";

    @Bean
    public S3Client s3Client() {
        return S3Client.builder()
                .region(Region.of(AWS_REGION))
                .credentialsProvider(EnvironmentVariableCredentialsProvider.create())
                .build();
    }
}

So I get it in my controller like this

package com.api.business_manager_api.Controllers;

import com.api.business_manager_api.Dtos.ProductDto;
import com.api.business_manager_api.Mappers.ProductMapper;
import com.api.business_manager_api.Models.CategoryModel;
import com.api.business_manager_api.Models.ProductModel;
import com.api.business_manager_api.Services.CategoryService;
import com.api.business_manager_api.Services.ProductService;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

@RestController
@CrossOrigin(origins = "*", maxAge = 3600)
@RequestMapping("/product")
public class ProductController {
    final ProductService productService;
    final CategoryService categoryService;
    final ProductMapper productMapper;
    final S3Client s3Client;

    private final String BUCKET_NAME = "stockproducts" + System.currentTimeMillis();
    private final String KEY = "*my secret key*";

    public ProductController(ProductService productService, ProductMapper productMapper, CategoryService categoryService, S3Client s3Client) {
        this.productService = productService;
        this.productMapper = productMapper;
        this.categoryService = categoryService;
        this.s3Client = s3Client;
    }
    @PostMapping
    public ResponseEntity<Object> saveProduct (@RequestBody @Valid ProductDto productDto, @RequestParam("file")MultipartFile file) {
        try {
            if (productService.existsByProduct(productDto.getProduct())) {
                return ResponseEntity.status(HttpStatus.CONFLICT).body("Product already exists!");
            }
            ProductModel productModel = productMapper.toProductModel(productDto);
            CategoryModel categoryModel = categoryService.findById(productDto.getProductCategory().getCategory_id())
                    .orElseThrow(() -> new RuntimeException("Category not found"));
            productModel.setProductCategory(categoryModel);

            s3Client.putObject(PutObjectRequest
                    .builder()
                    .bucket(BUCKET_NAME)
                    .key(KEY)
                    .build(),
                    RequestBody.fromString("Testing with the {sdk-java}"));

            return ResponseEntity.status(HttpStatus.CREATED).body(productService.save(productModel));
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.CONFLICT).body("Cannot create product. Check if the fields sent in your request are correct.");
        }
    }

    @GetMapping
    public ResponseEntity<List<ProductModel>> getAllProducts() {
        return ResponseEntity.status(HttpStatus.OK).body(productService.findAll());
    }

    @GetMapping("/{id}")
    public ResponseEntity<Object> getOneProduct(@PathVariable(value = "id")UUID id) {
        Optional<ProductModel> productModelOptional = productService.findById(id);
        if (!productModelOptional.isPresent()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Product not found");
        }
        return ResponseEntity.status(HttpStatus.OK).body(productModelOptional.get());
    }

    @PutMapping("/{id}")
    public ResponseEntity<Object> updateProduct(@PathVariable(value = "id") UUID id,
                                                @RequestBody @Valid ProductDto productDto) {
        Optional<ProductModel> productModelOptional = productService.findById(id);
        if (!productModelOptional.isPresent()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Product not found!");
        }
        ProductModel productModel = productModelOptional.get();
        productModel.setProduct(productDto.getProduct());
        productModel.setDescription(productDto.getDescription());
        productModel.setPrice(productDto.getPrice());
        productModel.setExtraPrice(productDto.getExtraPrice());
        productModel.setStock(productDto.getStock());
        productModel.setProductCategory(productDto.getProductCategory());

        return ResponseEntity.status(HttpStatus.OK).body(productService.save(productModel));
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Object> deleteProduct(@PathVariable(value = "id") UUID id) {
        Optional<ProductModel> productModelOptional = productService.findById(id);
        if (!productModelOptional.isPresent()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Product not found!");
        }
        productService.delete(productModelOptional.get());
        return ResponseEntity.status(HttpStatus.OK).body("Product deleted succesfully!");
    }
}

The problem is that when sending through s3Client exactly the way the documentation says, I have a syntax error

Cannot resolve method 'fromString' in 'RequestBody'

I already tried to change it to StringOf, but without success. The documentation doesn't say anything about this. Another doubt I have, "key" would be my correct IAM user key? Because the documentation doesn't specify that either

10
  • Can it happen that you use IntelliJ IDEA? Commented Mar 2, 2023 at 18:29
  • Yes. I am using Intellij IDEA Commented Mar 2, 2023 at 18:38
  • According to this older topic you may simply need to reconfigure it: stackoverflow.com/questions/4618794/… (while the question is Mac, answers and links mention encountering the problem on Windows and Linux too) Commented Mar 2, 2023 at 18:43
  • I'll read about it... About the key issue. Can you tell me if the key that must be informed is the secret Key of the IAM User of amazon s3? Commented Mar 2, 2023 at 18:47
  • No, not at all, don't put your secret there. That "key" is simply the "filename" what the object will have after uploading. Like in ..../mybucket/mykey. Commented Mar 2, 2023 at 18:53

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.