Note that the detail message associated with {@code cause} is not automatically 45 | * incorporated in this runtime exception's detail message. 46 | * 47 | * @param message the detail message (which is saved for later retrieval by the {@link 48 | * #getMessage()} method). 49 | * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method). 50 | * @since 1.4 51 | */ 52 | public EncryptionException(final String message, Throwable cause) { 53 | super(message, cause); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/developersboard/exception/InvalidFileFormatException.java: -------------------------------------------------------------------------------- 1 | package com.developersboard.exception; 2 | 3 | import com.developersboard.constant.StorageConstants; 4 | import java.io.Serial; 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.web.bind.annotation.ResponseStatus; 7 | 8 | /** 9 | * Processes invalidFileFormat exception. 10 | * 11 | * @author Eric Opoku 12 | * @version 1.0 13 | * @since 1.0 14 | */ 15 | @ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = StorageConstants.PATH_CANNOT_BE_NULL) 16 | public class InvalidFileFormatException extends RuntimeException { 17 | @Serial private static final long serialVersionUID = 3736658997506675274L; 18 | 19 | /** 20 | * Constructs a new runtime exception with the specified detail message. The cause is not 21 | * initialized, and may subsequently be initialized by a call to {@link #initCause}. 22 | * 23 | * @param message the detail message. The detail message is saved for later retrieval by the 24 | * {@link #getMessage()} method. 25 | */ 26 | public InvalidFileFormatException(String message) { 27 | super(message); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/developersboard/exception/InvalidServiceRequestException.java: -------------------------------------------------------------------------------- 1 | package com.developersboard.exception; 2 | 3 | import java.io.Serial; 4 | import org.springframework.http.HttpStatus; 5 | import org.springframework.web.bind.annotation.ResponseStatus; 6 | 7 | /** 8 | * Handles all generic exceptions for the application. 9 | * 10 | * @author Eric Opoku 11 | * @version 1.0 12 | * @since 1.0 13 | */ 14 | @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR, reason = "Error processing your request") 15 | public class InvalidServiceRequestException extends RuntimeException { 16 | @Serial private static final long serialVersionUID = 4518149233942557017L; 17 | 18 | /** 19 | * Constructs a new runtime exception with the specified detail message. The cause is not 20 | * initialized, and may subsequently be initialized by a call to {@link #initCause}. 21 | * 22 | * @param message the detail message. The detail message is saved for later retrieval by the 23 | * {@link #getMessage()} method. 24 | */ 25 | public InvalidServiceRequestException(final String message) { 26 | super(message); 27 | } 28 | 29 | /** 30 | * Constructs a new runtime exception with the specified cause and a detail message. This 31 | * constructor is useful for runtime exceptions that are little more than wrappers for other 32 | * throwables. 33 | * 34 | * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method) 35 | * @since 1.4 36 | */ 37 | public InvalidServiceRequestException(final Throwable cause) { 38 | super(cause); 39 | } 40 | 41 | /** 42 | * Constructs a new runtime exception with the specified detail message and cause. 43 | * 44 | *
Note that the detail message associated with {@code cause} is not automatically
45 | * incorporated in this runtime exception's detail message.
46 | *
47 | * @param message the detail message (which is saved for later retrieval by the {@link
48 | * #getMessage()} method).
49 | * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method).
50 | * @since 1.4
51 | */
52 | public InvalidServiceRequestException(final String message, Throwable cause) {
53 | super(message, cause);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/com/developersboard/exception/ResourceUnavailableException.java:
--------------------------------------------------------------------------------
1 | package com.developersboard.exception;
2 |
3 | import java.io.Serial;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.ResponseStatus;
6 |
7 | /**
8 | * Responsible for resource not found exception.
9 | *
10 | * @author Eric Opoku
11 | * @version 1.0
12 | * @since 1.0
13 | */
14 | @ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Resource not available")
15 | public class ResourceUnavailableException extends RuntimeException {
16 | @Serial private static final long serialVersionUID = -5085037505229603034L;
17 |
18 | /**
19 | * Constructs a new runtime exception with the specified detail message. The cause is not
20 | * initialized, and may subsequently be initialized by a call to {@link #initCause}.
21 | *
22 | * @param message the detail message. The detail message is saved for later retrieval by the
23 | * {@link #getMessage()} method.
24 | */
25 | public ResourceUnavailableException(String message) {
26 | super(message);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/developersboard/exception/SecurityException.java:
--------------------------------------------------------------------------------
1 | package com.developersboard.exception;
2 |
3 | import java.io.Serial;
4 |
5 | /**
6 | * Used in storage service related exceptions.
7 | *
8 | * @author Eric Opoku
9 | * @version 1.0
10 | * @since 1.0
11 | */
12 | public class SecurityException extends RuntimeException {
13 | @Serial private static final long serialVersionUID = 2292821525781156962L;
14 |
15 | /**
16 | * Constructs a new runtime exception with the specified detail message. The cause is not
17 | * initialized, and may subsequently be initialized by a call to {@link #initCause}.
18 | *
19 | * @param message the detail message. The detail message is saved for later retrieval by the
20 | * {@link #getMessage()} method.
21 | */
22 | public SecurityException(String message) {
23 | super(message);
24 | }
25 |
26 | /**
27 | * A convenient way to initialize with a given message and exception.
28 | *
29 | * @param message the message
30 | * @param cause the exception
31 | */
32 | public SecurityException(String message, Throwable cause) {
33 | super(message, cause);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/developersboard/exception/StorageException.java:
--------------------------------------------------------------------------------
1 | package com.developersboard.exception;
2 |
3 | import java.io.Serial;
4 |
5 | /**
6 | * Used in storage service related exceptions.
7 | *
8 | * @author Eric Opoku
9 | * @version 1.0
10 | * @since 1.0
11 | */
12 | public class StorageException extends RuntimeException {
13 | @Serial private static final long serialVersionUID = 2292821525781156962L;
14 |
15 | /**
16 | * Constructs a new runtime exception with the specified detail message. The cause is not
17 | * initialized, and may subsequently be initialized by a call to {@link #initCause}.
18 | *
19 | * @param message the detail message. The detail message is saved for later retrieval by the
20 | * {@link #getMessage()} method.
21 | */
22 | public StorageException(String message) {
23 | super(message);
24 | }
25 |
26 | /**
27 | * A convenient way to initialize with a given message and exception.
28 | *
29 | * @param message the message
30 | * @param cause the exception
31 | */
32 | public StorageException(String message, Throwable cause) {
33 | super(message, cause);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/developersboard/exception/UnAuthorizedActionException.java:
--------------------------------------------------------------------------------
1 | package com.developersboard.exception;
2 |
3 | import java.io.Serial;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.ResponseStatus;
6 |
7 | /**
8 | * Processes unauthorized exception.
9 | *
10 | * @author Eric Opoku
11 | * @version 1.0
12 | * @since 1.0
13 | */
14 | @ResponseStatus(value = HttpStatus.UNAUTHORIZED, reason = "You do not have access to this resource")
15 | public class UnAuthorizedActionException extends RuntimeException {
16 | @Serial private static final long serialVersionUID = -6375585304859610399L;
17 |
18 | /**
19 | * Constructs a new runtime exception with the specified detail message. The cause is not
20 | * initialized, and may subsequently be initialized by a call to {@link #initCause}.
21 | *
22 | * @param message the detail message. The detail message is saved for later retrieval by the
23 | * {@link #getMessage()} method.
24 | */
25 | public UnAuthorizedActionException(String message) {
26 | super(message);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/developersboard/exception/package-info.java:
--------------------------------------------------------------------------------
1 | /** Package containing custom exceptions for the application. */
2 | package com.developersboard.exception;
3 |
--------------------------------------------------------------------------------
/src/main/java/com/developersboard/exception/user/InvalidTokenException.java:
--------------------------------------------------------------------------------
1 | package com.developersboard.exception.user;
2 |
3 | import java.io.Serial;
4 |
5 | /**
6 | * This is an exception for invalid token exceptions.
7 | *
8 | * @author Eric Opoku
9 | * @version 1.0
10 | * @since 1.0
11 | */
12 | public class InvalidTokenException extends RuntimeException {
13 | @Serial private static final long serialVersionUID = -4814040831176808554L;
14 |
15 | /**
16 | * Constructs a new runtime exception with the specified detail message. The cause is not
17 | * initialized, and may subsequently be initialized by a call to {@link #initCause}.
18 | *
19 | * @param message the detail message. The detail message is saved for later retrieval by the
20 | * {@link #getMessage()} method.
21 | */
22 | public InvalidTokenException(final String message) {
23 | super(message);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/developersboard/exception/user/UserAlreadyExistsException.java:
--------------------------------------------------------------------------------
1 | package com.developersboard.exception.user;
2 |
3 | import java.io.Serial;
4 |
5 | /**
6 | * Responsible for user already exists an exception specifically.
7 | *
8 | * @author Eric Opoku
9 | * @version 1.0
10 | * @since 1.0
11 | */
12 | public class UserAlreadyExistsException extends RuntimeException {
13 | @Serial private static final long serialVersionUID = -2959136757722416883L;
14 |
15 | /**
16 | * Constructs a new runtime exception with the specified detail message. The cause is not
17 | * initialized, and may subsequently be initialized by a call to {@link #initCause}.
18 | *
19 | * @param message the detail message. The detail message is saved for later retrieval by the
20 | * {@link #getMessage()} method.
21 | */
22 | public UserAlreadyExistsException(String message) {
23 | super(message);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/developersboard/exception/user/UserNotFoundException.java:
--------------------------------------------------------------------------------
1 | package com.developersboard.exception.user;
2 |
3 | import java.io.Serial;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.ResponseStatus;
6 |
7 | /**
8 | * Responsible for user not found exception specifically.
9 | *
10 | * @author Eric Opoku
11 | * @version 1.0
12 | * @since 1.0
13 | */
14 | @ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "User does not exist")
15 | public class UserNotFoundException extends RuntimeException {
16 | @Serial private static final long serialVersionUID = 4992489948815528687L;
17 |
18 | /**
19 | * Constructs a new runtime exception with the specified detail message. The cause is not
20 | * initialized, and may subsequently be initialized by a call to {@link #initCause}.
21 | *
22 | * @param message the detail message. The detail message is saved for later retrieval by the
23 | * {@link #getMessage()} method.
24 | */
25 | public UserNotFoundException(String message) {
26 | super(message);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/developersboard/exception/user/package-info.java:
--------------------------------------------------------------------------------
1 | /** Package containing custom user exceptions for the application. */
2 | package com.developersboard.exception.user;
3 |
--------------------------------------------------------------------------------
/src/main/java/com/developersboard/lombok.config:
--------------------------------------------------------------------------------
1 | lombok.log.fieldName = LOG
2 | config.stopBubbling = true
3 | lombok.addLombokGeneratedAnnotation = true
4 |
--------------------------------------------------------------------------------
/src/main/java/com/developersboard/package-info.java:
--------------------------------------------------------------------------------
1 | /** The root package contains the classes that are used to create the application. */
2 | package com.developersboard;
3 |
--------------------------------------------------------------------------------
/src/main/java/com/developersboard/shared/dto/BaseDto.java:
--------------------------------------------------------------------------------
1 | package com.developersboard.shared.dto;
2 |
3 | import java.time.LocalDateTime;
4 | import lombok.Data;
5 | import lombok.EqualsAndHashCode;
6 |
7 | /**
8 | * The BaseDto provides base fields to be extended.
9 | *
10 | * @author Eric Opoku
11 | * @version 1.0
12 | * @since 1.0
13 | */
14 | @Data
15 | @EqualsAndHashCode(onlyExplicitlyIncluded = true)
16 | public class BaseDto {
17 | private Long id;
18 |
19 | @EqualsAndHashCode.Include private int version;
20 | private LocalDateTime createdAt;
21 | private String createdBy;
22 | private LocalDateTime updatedAt;
23 | private String updatedBy;
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/developersboard/shared/dto/UserHistoryDto.java:
--------------------------------------------------------------------------------
1 | package com.developersboard.shared.dto;
2 |
3 | import com.developersboard.enums.UserHistoryType;
4 | import com.developersboard.web.payload.pojo.SeparateDateFormat;
5 | import java.io.Serial;
6 | import java.io.Serializable;
7 | import lombok.Data;
8 | import lombok.EqualsAndHashCode;
9 |
10 | /**
11 | * The UserHistoryDto transfers user history from outside into the application and vice versa.
12 | *
13 | * @author Eric Opoku
14 | * @version 1.0
15 | * @since 1.0
16 | */
17 | @Data
18 | @EqualsAndHashCode(callSuper = true)
19 | public final class UserHistoryDto extends BaseDto implements Serializable {
20 | @Serial private static final long serialVersionUID = -8842211126703873453L;
21 |
22 | private UserHistoryType userHistoryType;
23 | private String timeElapsedDescription;
24 | private SeparateDateFormat separateDateFormat;
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/developersboard/shared/dto/mapper/UserHistoryDtoMapper.java:
--------------------------------------------------------------------------------
1 | package com.developersboard.shared.dto.mapper;
2 |
3 | import com.developersboard.backend.persistent.domain.user.UserHistory;
4 | import com.developersboard.shared.dto.UserHistoryDto;
5 | import java.util.List;
6 | import java.util.Set;
7 | import org.mapstruct.Mapper;
8 | import org.mapstruct.Mapping;
9 | import org.mapstruct.ReportingPolicy;
10 | import org.mapstruct.factory.Mappers;
11 |
12 | /**
13 | * The UserDtoMapper class outlines the supported conversions between User and other objects.
14 | *
15 | * @author Eric Opoku
16 | * @version 1.0
17 | * @since 1.0
18 | */
19 | @Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
20 | public interface UserHistoryDtoMapper {
21 |
22 | UserHistoryDtoMapper MAPPER = Mappers.getMapper(UserHistoryDtoMapper.class);
23 |
24 | /**
25 | * Convert and populate a userHistories to userHistoryDto object.
26 | *
27 | * @param userHistories the userHistories
28 | * @return the userHistoryDto
29 | */
30 | List
30 | * Format is:
31 | * second minute hour day-of-month month day-of-week year command
32 | * # 1. Entry: Minute when the process will be started [0-60]
33 | * # 2. Entry: Hour when the process will be started [0-23]
34 | * # 3. Entry: Day of the month when the process will be started [1-28/29/30/31]
35 | * # 4. Entry: Month of the year when the process will be started [1-12]
36 | * # 5. Entry: Weekday when the process will be started [0-6] [0 is Sunday]
37 | * #
38 | * # all x min = *\/x.
39 | * '0 0 0 ? * SUN' for every Sunday.
40 | * '0 * * * * *' for every minute.
41 | *
42 | *
43 | * fixedRate = 300000 in milliseconds (5 minutes)
44 | */
45 | @Loggable(level = "trace")
46 | @Scheduled(fixedRate = EVICT_ALL_CACHE_INTERVAL)
47 | public void evictAllCaches() {
48 | cacheManager
49 | .getCacheNames()
50 | .forEach(
51 | cacheName -> {
52 | var cache = cacheManager.getCache(cacheName);
53 | if (Objects.nonNull(cache)) {
54 | cache.clear();
55 | }
56 | });
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/com/developersboard/task/UserPruningScheduler.java:
--------------------------------------------------------------------------------
1 | package com.developersboard.task;
2 |
3 | import com.developersboard.annotation.Loggable;
4 | import com.developersboard.backend.service.user.UserService;
5 | import com.developersboard.shared.dto.UserDto;
6 | import java.util.List;
7 | import java.util.stream.Stream;
8 | import lombok.RequiredArgsConstructor;
9 | import lombok.extern.slf4j.Slf4j;
10 | import org.springframework.scheduling.annotation.Scheduled;
11 | import org.springframework.stereotype.Component;
12 |
13 | /**
14 | * Removes all users not enabled. That is users that do not verify their account after some time.
15 | *
16 | * @author Eric Opoku
17 | * @version 1.0
18 | * @since 1.0
19 | */
20 | @Slf4j
21 | @Component
22 | @RequiredArgsConstructor
23 | public class UserPruningScheduler {
24 |
25 | private final UserService userService;
26 |
27 | /**
28 | * Every user that does not verify email after a certain time is deleted from the database.
29 | *
30 | *
31 | * Format is:
32 | * second minute hour day-of-month month day-of-week year command
33 | * # 1. Entry: Minute when the process will be started [0-60]
34 | * # 2. Entry: Hour when the process will be started [0-23]
35 | * # 3. Entry: Day of the month when the process will be started [1-28/29/30/31]
36 | * # 4. Entry: Month of the year when the process will be started [1-12]
37 | * # 5. Entry: Weekday when the process will be started [0-6] [0 is Sunday]
38 | * #
39 | * # all x min = *\/x.
40 | * '0 0 0 ? * SUN' for every Sunday.
41 | * '0 * * * * *' for every minute.
42 | *
43 | */
44 | @Loggable
45 | @Scheduled(cron = "0 0 0 ? * SUN")
46 | public void pruneUsers() {
47 | List