From b77d70d897bbf9bc4f139dd89daa9d727202d992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADza=20O=2E=20Rosa?= Date: Tue, 28 May 2024 13:05:15 -0300 Subject: [PATCH 1/4] add blob token and upload with type --- .../api/educai/services/AzureBlobService.java | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/main/java/api/educai/services/AzureBlobService.java b/src/main/java/api/educai/services/AzureBlobService.java index eb3a25a..4b6bed7 100644 --- a/src/main/java/api/educai/services/AzureBlobService.java +++ b/src/main/java/api/educai/services/AzureBlobService.java @@ -9,12 +9,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatusCode; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import com.azure.core.http.rest.PagedIterable; import com.azure.storage.blob.BlobClient; import com.azure.storage.blob.BlobContainerClient; import com.azure.storage.blob.models.BlobItem; +import org.springframework.web.server.ResponseStatusException; @Service public class AzureBlobService { @@ -25,21 +27,41 @@ public class AzureBlobService { @Value("${azure.storage.url}") private String storageUrl; + @Value("${azure.storage.blob-token}") + private String blobToken; + public String upload(MultipartFile file) throws IOException { String uuid = String.valueOf(UUID.randomUUID()); + String[] parts; + String type = ""; + + try { + if (file.getOriginalFilename() != null) { + parts = file.getOriginalFilename().split("\\."); + type = "." + parts[parts.length - 1]; + } else { + if (file.getContentType() != null) { + parts = file.getContentType().split("/"); + type = "." + parts[parts.length - 1]; + } + } + } catch (NullPointerException ex) { + throw new ResponseStatusException(HttpStatusCode.valueOf(415), "Error while trying to upload file. Check the file type and try again."); + } + BlobClient blob = blobContainerClient - .getBlobClient(uuid); + .getBlobClient(uuid + type); blob.upload(file.getInputStream(), file.getSize(), true); - return storageUrl + uuid; + return storageUrl + uuid + type; } public String getBlobUrl(String fileName){ BlobClient blob = blobContainerClient.getBlobClient(fileName); - return blob.getBlobUrl(); + return blob.getBlobUrl() + "?%s".formatted(blobToken); } public byte[] download(String fileName) From 3679e5cfdd2d4e22a8cb706d7b957c7d971bd2d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADza=20O=2E=20Rosa?= Date: Tue, 28 May 2024 13:06:05 -0300 Subject: [PATCH 2/4] remove request param --- src/main/java/api/educai/controllers/UserController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/api/educai/controllers/UserController.java b/src/main/java/api/educai/controllers/UserController.java index 124347a..459b5d2 100644 --- a/src/main/java/api/educai/controllers/UserController.java +++ b/src/main/java/api/educai/controllers/UserController.java @@ -120,7 +120,7 @@ public ResponseEntity logoff( @Operation(summary = "Adiciona imagem de perfil do usuário") @PostMapping("/{userId}/picture") - public ResponseEntity uploadProfilePicture(@RequestParam MultipartFile file, @PathVariable ObjectId userId) { + public ResponseEntity uploadProfilePicture(MultipartFile file, @PathVariable ObjectId userId) { userService.uploadFile(file, userId); return status(200).build(); } From b6ea062fbc8477e0b50713bb6a0ac8b8d5a4a66f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADza=20O=2E=20Rosa?= Date: Tue, 28 May 2024 13:06:48 -0300 Subject: [PATCH 3/4] create and get posts with azure storage --- .../api/educai/controllers/PostController.java | 5 +++-- .../api/educai/dto/ClassroomParticipantsDTO.java | 11 ++++------- src/main/java/api/educai/entities/Post.java | 2 +- .../api/educai/services/ClassroomService.java | 7 ++++++- .../java/api/educai/services/PostService.java | 16 +++++++++++++++- 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/main/java/api/educai/controllers/PostController.java b/src/main/java/api/educai/controllers/PostController.java index df9d816..2b04589 100644 --- a/src/main/java/api/educai/controllers/PostController.java +++ b/src/main/java/api/educai/controllers/PostController.java @@ -14,6 +14,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.security.access.annotation.Secured; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -29,8 +30,8 @@ public class PostController { @Secured("ROLE_TEACHER") @Operation(summary = "Cria um post") @PostMapping - public ResponseEntity createPost(@RequestBody @Valid NewPostDTO post){ - return ResponseEntity.status(201).body(postService.createPost(post)); + public ResponseEntity createPost(@RequestBody @Valid NewPostDTO post, MultipartFile file){ + return ResponseEntity.status(201).body(postService.createPost(post, file)); } diff --git a/src/main/java/api/educai/dto/ClassroomParticipantsDTO.java b/src/main/java/api/educai/dto/ClassroomParticipantsDTO.java index 8836829..b93a221 100644 --- a/src/main/java/api/educai/dto/ClassroomParticipantsDTO.java +++ b/src/main/java/api/educai/dto/ClassroomParticipantsDTO.java @@ -4,8 +4,12 @@ import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Size; +import lombok.Getter; +@Getter public class ClassroomParticipantsDTO { + + private String id; @NotBlank @Size(max = 100) private String name; @@ -18,11 +22,4 @@ public ClassroomParticipantsDTO(User user) { this.email = user.getEmail(); } - public String getName() { - return name; - } - - public String getEmail() { - return email; - } } diff --git a/src/main/java/api/educai/entities/Post.java b/src/main/java/api/educai/entities/Post.java index a594928..634b883 100644 --- a/src/main/java/api/educai/entities/Post.java +++ b/src/main/java/api/educai/entities/Post.java @@ -21,7 +21,7 @@ public class Post { @NotBlank @Size(max = 100) private String description; - private String url; + private String file; @NotNull private LocalDate datePosting; } diff --git a/src/main/java/api/educai/services/ClassroomService.java b/src/main/java/api/educai/services/ClassroomService.java index bdd9a63..66c67ef 100644 --- a/src/main/java/api/educai/services/ClassroomService.java +++ b/src/main/java/api/educai/services/ClassroomService.java @@ -34,6 +34,9 @@ public class ClassroomService { @Autowired private ModelMapper mapper; + @Autowired + private AzureBlobService azureBlobService; + public ClassroomInfoDTO createClassroom(Classroom classroom, ObjectId ownerId) { User user = userService.getUserById(ownerId); @@ -134,7 +137,9 @@ public ReportDTO getUserReport(ObjectId classroomId, ObjectId userId) { public List getPostsByClassroom(ObjectId classroomId) { Classroom classroom = classroomRepository.findById(classroomId); - return classroom.getPosts(); + List posts = classroom.getPosts(); + posts.forEach(p -> p.setFile(azureBlobService.getBlobUrl(p.getFile()))); + return posts; } public void deleteClassroom(ObjectId id, ObjectId userId) { diff --git a/src/main/java/api/educai/services/PostService.java b/src/main/java/api/educai/services/PostService.java index 61cd1c3..8b3b721 100644 --- a/src/main/java/api/educai/services/PostService.java +++ b/src/main/java/api/educai/services/PostService.java @@ -11,8 +11,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatusCode; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; import org.springframework.web.server.ResponseStatusException; +import java.io.IOException; import java.util.List; @Service @@ -23,10 +25,22 @@ public class PostService { private ClassroomRepository classroomRepository; @Autowired private ModelMapper mapper; + @Autowired + private AzureBlobService azureBlobService; - public Post createPost(NewPostDTO newPost) { + public Post createPost(NewPostDTO newPost, MultipartFile file) { Classroom classroom = classroomRepository.findById(new ObjectId(newPost.getClassroomId())); Post post = mapper.map(newPost, Post.class); + + if (file != null) { + try { + String path = azureBlobService.upload(file); + post.setFile(path); + } catch (IOException ex) { + throw new ResponseStatusException(HttpStatusCode.valueOf(500), "Error while trying to upload file!"); + } + } + postRepository.save(post); classroom.addPost(post); From 594ac7f064e1810db911d3c6c6d96ef5d9c9403d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADza=20O=2E=20Rosa?= Date: Tue, 28 May 2024 13:14:42 -0300 Subject: [PATCH 4/4] add token azure storage blob --- .github/workflows/maven.yml | 1 + src/main/resources/application.properties | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 748ed6e..1586d6a 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -30,6 +30,7 @@ jobs: sed -i 's#\${MONGO_USERNAME}#'"${{ secrets.MONGO_USERNAME }}"'#g' src/main/resources/application.properties sed -i 's#\${MONGO_PASSWORD}#'"${{ secrets.MONGO_PASSWORD }}"'#g' src/main/resources/application.properties sed -i 's#\${AZURE_STORAGE_URL}#'"${{ secrets.AZURE_STORAGE_URL }}"'#g' src/main/resources/application.properties + sed -i 's#\${AZURE_STORAGE_BLOB_TOKEN}#'"${{ secrets.AZURE_STORAGE_BLOB_TOKEN }}"'#g' src/main/resources/application.properties - name: Display application.properties run: cat src/main/resources/application.properties diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4be2e34..9b4d114 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -23,6 +23,7 @@ spring.mvc.cors.allowed-headers=* azure.storage.connection.string=${AZURE_STORAGE_CONNECTION_STRING} azure.storage.container.name=${AZURE_STORAGE_CONTAINER_NAME} azure.storage.url=${AZURE_STORAGE_URL} +azure.storage.blob-token=${AZURE_STORAGE_BLOB_TOKEN} # JWT jwt.token.secret=07BFq1GxbCm49YnsEQte9lk0z9hte8db7rG5wSERMaPZlqM3dGwvvbAYqUZ6WDNQQLzTSUCx7elIYGiTIbDgbYt6kX4IxQ3F9Ugs