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