38.1 Extract Profile Image operation into separate ProfileImageService (#38 save profile images to S3)
This commit is contained in:
@ -22,7 +22,6 @@ import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.springframework.http.HttpStatus.OK;
|
||||
@ -110,7 +109,7 @@ public class UserResource {
|
||||
}
|
||||
|
||||
@GetMapping(path = "{userId}/profile-image/{filename}", produces = MediaType.IMAGE_JPEG_VALUE)
|
||||
public byte[] getProfileImageByUserId(@PathVariable UUID userId, @PathVariable String filename) throws IOException {
|
||||
public byte[] getProfileImageByUserId(@PathVariable UUID userId, @PathVariable String filename) {
|
||||
return userService.getImageByUserId(userId, filename);
|
||||
}
|
||||
|
||||
|
||||
@ -117,8 +117,8 @@ public class ExceptionHandling {
|
||||
return createHttpResponse(NOT_FOUND, exception.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(IOException.class)
|
||||
public ResponseEntity<HttpResponse> iOException(IOException exception) {
|
||||
@ExceptionHandler({IOException.class, ImageStorageException.class})
|
||||
public ResponseEntity<HttpResponse> fileRelatedException(Exception exception) {
|
||||
log.error(exception.getMessage());
|
||||
return createHttpResponse(INTERNAL_SERVER_ERROR, ERROR_PROCESSING_FILE);
|
||||
}
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
package net.shyshkin.study.fullstack.supportportal.backend.exception.domain;
|
||||
|
||||
public class ImageStorageException extends RuntimeException {
|
||||
public ImageStorageException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ImageStorageException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package net.shyshkin.study.fullstack.supportportal.backend.service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.shyshkin.study.fullstack.supportportal.backend.exception.domain.ImageStorageException;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.FileSystemUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.shyshkin.study.fullstack.supportportal.backend.constant.FileConstant.*;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@Profile("!image-s3")
|
||||
public class FileSystemProfileImageService implements ProfileImageService {
|
||||
|
||||
@Override
|
||||
public byte[] retrieveProfileImage(UUID userId, String filename) {
|
||||
|
||||
Path userProfileImagePath = Paths
|
||||
.get(USER_FOLDER, userId.toString(), filename);
|
||||
try {
|
||||
return Files.readAllBytes(userProfileImagePath);
|
||||
} catch (IOException exception) {
|
||||
throw new ImageStorageException("Can not retrieve image for user " + userId + " from file " + filename, exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String persistProfileImage(UUID userId, MultipartFile profileImage, String filename) {
|
||||
Path userFolder = Paths.get(USER_FOLDER, userId.toString());
|
||||
try {
|
||||
if (Files.notExists(userFolder)) {
|
||||
Files.createDirectories(userFolder);
|
||||
log.debug(DIRECTORY_CREATED);
|
||||
}
|
||||
profileImage.transferTo(userFolder.resolve(USER_IMAGE_FILENAME));
|
||||
log.debug(FILE_SAVED_IN_FILE_SYSTEM + profileImage.getOriginalFilename());
|
||||
|
||||
} catch (IOException exception) {
|
||||
throw new ImageStorageException("Can not persist image for user " + userId + " from file " + profileImage, exception);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearUserStorage(UUID userId) {
|
||||
Path userFolder = Paths.get(USER_FOLDER, userId.toString());
|
||||
try {
|
||||
FileSystemUtils.deleteRecursively(userFolder);
|
||||
} catch (IOException exception) {
|
||||
throw new ImageStorageException("Can not delete folder for user " + userId, exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package net.shyshkin.study.fullstack.supportportal.backend.service;
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface ProfileImageService {
|
||||
|
||||
byte[] retrieveProfileImage(UUID userId, String filename);
|
||||
|
||||
String persistProfileImage(UUID userId, MultipartFile profileImage, String filename);
|
||||
|
||||
void clearUserStorage(UUID userId);
|
||||
|
||||
}
|
||||
@ -7,7 +7,6 @@ import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface UserService extends UserDetailsService {
|
||||
@ -32,7 +31,7 @@ public interface UserService extends UserDetailsService {
|
||||
|
||||
User updateProfileImage(UUID userId, MultipartFile profileImage);
|
||||
|
||||
byte[] getImageByUserId(UUID userId, String filename) throws IOException;
|
||||
byte[] getImageByUserId(UUID userId, String filename);
|
||||
|
||||
byte[] getDefaultProfileImage(UUID userId);
|
||||
}
|
||||
|
||||
@ -19,17 +19,12 @@ import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.FileSystemUtils;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.transaction.Transactional;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@ -55,6 +50,7 @@ public class UserServiceImpl implements UserService {
|
||||
private final EmailService emailService;
|
||||
private final UserMapper userMapper;
|
||||
private final RestTemplateBuilder restTemplateBuilder;
|
||||
private final ProfileImageService profileImageService;
|
||||
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@ -188,30 +184,17 @@ public class UserServiceImpl implements UserService {
|
||||
throw new NotAnImageFileException(profileImage.getOriginalFilename() + " is not an image file. Please upload an image");
|
||||
}
|
||||
|
||||
Path userFolder = Paths.get(USER_FOLDER, user.getUserId().toString());
|
||||
try {
|
||||
if (Files.notExists(userFolder)) {
|
||||
Files.createDirectories(userFolder);
|
||||
log.debug(DIRECTORY_CREATED);
|
||||
}
|
||||
profileImage.transferTo(userFolder.resolve(USER_IMAGE_FILENAME));
|
||||
log.debug(FILE_SAVED_IN_FILE_SYSTEM + profileImage.getOriginalFilename());
|
||||
user.setProfileImageUrl(generateProfileImageUrl(user.getUserId()));
|
||||
userRepository.save(user);
|
||||
String imageUrl = profileImageService.persistProfileImage(user.getUserId(), profileImage, USER_IMAGE_FILENAME);
|
||||
|
||||
} catch (IOException exception) {
|
||||
log.error("Can't save to file", exception);
|
||||
}
|
||||
if (imageUrl == null)
|
||||
imageUrl = generateProfileImageUrl(user.getUserId());
|
||||
|
||||
user.setProfileImageUrl(imageUrl);
|
||||
userRepository.save(user);
|
||||
}
|
||||
|
||||
private void deleteProfileImageFolder(User user) {
|
||||
|
||||
Path userFolder = Paths.get(USER_FOLDER, user.getUserId().toString());
|
||||
try {
|
||||
FileSystemUtils.deleteRecursively(userFolder);
|
||||
} catch (IOException exception) {
|
||||
log.error("Can't delete folder", exception);
|
||||
}
|
||||
private void clearUserStorage(User user) {
|
||||
profileImageService.clearUserStorage(user.getUserId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -243,7 +226,7 @@ public class UserServiceImpl implements UserService {
|
||||
.findByUserId(userId)
|
||||
.orElseThrow(() -> new UserNotFoundException("User was not found"));
|
||||
|
||||
deleteProfileImageFolder(userToBeDeleted);
|
||||
clearUserStorage(userToBeDeleted);
|
||||
userRepository.delete(userToBeDeleted);
|
||||
}
|
||||
|
||||
@ -270,15 +253,12 @@ public class UserServiceImpl implements UserService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getImageByUserId(UUID userId, String filename) throws IOException {
|
||||
public byte[] getImageByUserId(UUID userId, String filename) {
|
||||
|
||||
if (!userRepository.existsByUserId(userId)) {
|
||||
throw new UserNotFoundException(USER_NOT_FOUND_MSG);
|
||||
}
|
||||
|
||||
Path userProfileImagePath = Paths
|
||||
.get(USER_FOLDER, userId.toString(), filename);
|
||||
return Files.readAllBytes(userProfileImagePath);
|
||||
return profileImageService.retrieveProfileImage(userId, filename);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user