Skip to content

Commit

Permalink
init: add some class and config, etc (#2)
Browse files Browse the repository at this point in the history
Add some config and file
  • Loading branch information
khanhduzz authored Aug 23, 2024
1 parent a47365d commit dc7d8f6
Show file tree
Hide file tree
Showing 23 changed files with 566 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pipeline-sun.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
- main
- ci-cd
paths:
- ".github/workflows/pipeline-sun.yaml"
- ".github/workflows/pipeline-sun.yml"

jobs:
compile:
Expand Down
64 changes: 64 additions & 0 deletions src/main/java/com/fjb/sunrise/config/ApplicationConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.fjb.sunrise.config;

import com.fjb.sunrise.enums.ERole;
import com.fjb.sunrise.models.User;
import com.fjb.sunrise.repositories.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@RequiredArgsConstructor
@Slf4j
public class ApplicationConfig {

private final UserRepository userRepository;

@Value("${application.admin.default.username}")
private String adminUsername;

@Value("${application.admin.default.password}")
private String adminPassword;

@Bean
public AuthenticationManager authenticationManager (AuthenticationConfiguration configuration) throws Exception {
return configuration.getAuthenticationManager();
}

@Bean
public PasswordEncoder passwordEncoder () {
return new BCryptPasswordEncoder();
}

@Bean
@ConditionalOnProperty(
prefix = "spring",
value = "datasource.driver-class-name",
havingValue = "org.postgresql.Driver")
ApplicationRunner applicationRunner () {
log.info("Initializing application.....");
return args -> {
if (!userRepository.existsByUsername(adminUsername)) {

User user = User.builder()
.username(adminUsername)
.password(passwordEncoder().encode(adminPassword))
.role(ERole.ADMIN)
.build();
userRepository.save(user);
log.warn("admin user has been created: username = {}, password = {} ", adminUsername, adminPassword);
} else {
log.warn("admin user: username = {}, password = {} ", adminUsername, adminPassword);
}
log.info("Application initialization completed .....");
};
}
}
57 changes: 57 additions & 0 deletions src/main/java/com/fjb/sunrise/config/WebServletConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.fjb.sunrise.config;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.thymeleaf.spring6.SpringTemplateEngine;
import org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring6.view.ThymeleafViewResolver;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"com.fjb.sunrise"})
public class WebServletConfig implements WebMvcConfigurer {
@Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setPrefix("classpath:/templates/");
resolver.setSuffix(".html");
resolver.setTemplateMode("TemplateMode.HTML");
resolver.setCacheable(false);
return resolver;
}

@Bean
public SpringTemplateEngine templateEngine(@Qualifier("templateResolver") SpringResourceTemplateResolver templateResolver) {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver());
engine.setEnableSpringELCompiler(true);
return engine;
}

@Bean
public ViewResolver viewResolver(@Qualifier("templateEngine") SpringTemplateEngine templateEngine) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine);
return resolver;
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/webjars/**", "/img/**", "/css/**", "/js/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/",
"classpath:/static/img/", "classpath:/static/css/", "classpath:/static/js/");
}

@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/health").setViewName("health");
}
}
11 changes: 11 additions & 0 deletions src/main/java/com/fjb/sunrise/dtos/responses/ErrorVm.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.fjb.sunrise.dtos.responses;

import java.util.ArrayList;
import java.util.List;

public record ErrorVm(String statusCode, String title, String detail, List<String> fieldErrors) {

public ErrorVm(String statusCode, String title, String detail) {
this(statusCode, title, detail, new ArrayList<String>());
}
}
6 changes: 6 additions & 0 deletions src/main/java/com/fjb/sunrise/enums/ERole.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.fjb.sunrise.enums;

public enum ERole {
ADMIN,
USER
}
6 changes: 6 additions & 0 deletions src/main/java/com/fjb/sunrise/enums/ETrans.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.fjb.sunrise.enums;

public enum ETrans {
IN,
OUT
}
93 changes: 93 additions & 0 deletions src/main/java/com/fjb/sunrise/exceptions/ApiExceptionHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package com.fjb.sunrise.exceptions;

import com.fjb.sunrise.dtos.responses.ErrorVm;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.NestedExceptionUtils;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.WebRequest;

@ControllerAdvice
@Slf4j
public class ApiExceptionHandler {

private static final String ERROR_LOG_FORMAT = "Error: URI: {}, ErrorCode: {}, Message: {}";

@ExceptionHandler(NotFoundException.class)
public ErrorVm handleNotFoundException(NotFoundException ex, WebRequest request) {
String message = ex.getMessage();
ErrorVm errorVm = new ErrorVm(HttpStatus.NOT_FOUND.toString(),
HttpStatus.NOT_FOUND.getReasonPhrase(), message);
log.warn(ERROR_LOG_FORMAT, this.getServletPath(request), 404, message);
log.debug(ex.toString());
return errorVm;
}

@ExceptionHandler(BadRequestException.class)
public ErrorVm handleBadRequestException(BadRequestException ex,
WebRequest request) {
String message = ex.getMessage();
return new ErrorVm(HttpStatus.BAD_REQUEST.toString(),
HttpStatus.BAD_REQUEST.getReasonPhrase(), message);
}

@ExceptionHandler(MethodArgumentNotValidException.class)
protected ErrorVm handleMethodArgumentNotValid(MethodArgumentNotValidException ex) {
List<String> errors = ex.getBindingResult()
.getFieldErrors()
.stream()
.map(error -> error.getField() + " " + error.getDefaultMessage())
.toList();

return new ErrorVm(HttpStatus.BAD_REQUEST.toString(),
HttpStatus.BAD_REQUEST.getReasonPhrase(), "Request information is not valid", errors);
}

@ExceptionHandler({ConstraintViolationException.class})
public ErrorVm handleConstraintViolation(ConstraintViolationException ex) {
List<String> errors = new ArrayList<>();
for (ConstraintViolation<?> violation : ex.getConstraintViolations()) {
errors.add(violation.getRootBeanClass().getName() + " "
+ violation.getPropertyPath() + ": " + violation.getMessage());
}

return new ErrorVm(HttpStatus.BAD_REQUEST.toString(),
HttpStatus.BAD_REQUEST.getReasonPhrase(), "Request information is not valid", errors);
}

@ExceptionHandler(DataIntegrityViolationException.class)
public ErrorVm handleDataIntegrityViolationException(DataIntegrityViolationException e) {
String message = NestedExceptionUtils.getMostSpecificCause(e).getMessage();
return new ErrorVm(HttpStatus.BAD_REQUEST.toString(),
HttpStatus.BAD_REQUEST.getReasonPhrase(), message);
}

@ExceptionHandler(DuplicatedException.class)
protected ErrorVm handleDuplicated(DuplicatedException e) {
return new ErrorVm(HttpStatus.BAD_REQUEST.toString(),
HttpStatus.BAD_REQUEST.getReasonPhrase(), e.getMessage());
}

@ExceptionHandler(Exception.class)
protected ErrorVm handleOtherException(Exception ex, WebRequest request) {
String message = ex.getMessage();
ErrorVm errorVm = new ErrorVm(HttpStatus.INTERNAL_SERVER_ERROR.toString(),
HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), message);
log.warn(ERROR_LOG_FORMAT, this.getServletPath(request), 500, message);
log.debug(ex.toString());
return errorVm;
}

private String getServletPath(WebRequest webRequest) {
ServletWebRequest servletRequest = (ServletWebRequest) webRequest;
return servletRequest.getRequest().getServletPath();
}
}
21 changes: 21 additions & 0 deletions src/main/java/com/fjb/sunrise/exceptions/BadRequestException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.fjb.sunrise.exceptions;

import com.fjb.sunrise.utils.MessagesUtils;

public class BadRequestException extends RuntimeException {

private String message;

public BadRequestException(String errorCode, Object... var2) {
this.message = MessagesUtils.getMessage(errorCode, var2);
}

@Override
public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}
}
21 changes: 21 additions & 0 deletions src/main/java/com/fjb/sunrise/exceptions/DuplicatedException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.fjb.sunrise.exceptions;

import com.fjb.sunrise.utils.MessagesUtils;

public class DuplicatedException extends RuntimeException {

private String message;

public DuplicatedException(String errorCode, Object... var2) {
this.message = MessagesUtils.getMessage(errorCode, var2);
}

@Override
public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}
}
21 changes: 21 additions & 0 deletions src/main/java/com/fjb/sunrise/exceptions/NotFoundException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.fjb.sunrise.exceptions;

import com.fjb.sunrise.utils.MessagesUtils;

public class NotFoundException extends RuntimeException {

private String message;

public NotFoundException(String errorCode, Object... var2) {
this.message = MessagesUtils.getMessage(errorCode, var2);
}

@Override
public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}
}
7 changes: 7 additions & 0 deletions src/main/java/com/fjb/sunrise/mappers/UserMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.fjb.sunrise.mappers;

import org.mapstruct.Mapper;

@Mapper(componentModel = "spring")
public interface UserMapper {
}
35 changes: 35 additions & 0 deletions src/main/java/com/fjb/sunrise/models/AuditEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.fjb.sunrise.models;

import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import java.time.LocalDateTime;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

@Getter
@Setter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class AuditEntity<U> {
@CreatedBy
@Column(name = "created_by")
protected U createdBy;

@CreatedDate
@Column(name = "created_date")
protected LocalDateTime createdDate;

@LastModifiedBy
@Column(name = "last_modified_by")
protected U lastModifiedBy;

@LastModifiedDate
@Column(name = "last_modified_date")
protected LocalDateTime lastModifiedDate;
}
28 changes: 28 additions & 0 deletions src/main/java/com/fjb/sunrise/models/Category.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.fjb.sunrise.models;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Entity
@Getter
@Setter
@Builder
@Table(name = "categories")
@AllArgsConstructor
@NoArgsConstructor
public class Category extends AuditEntity<Long>{

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String name;
}
Loading

0 comments on commit dc7d8f6

Please sign in to comment.