├── .github └── workflows │ └── maven-publish.yml ├── .gitignore ├── LICENSE ├── README.md ├── application ├── sample-service-with-aad-auth │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── sample_service_with_aad_auth │ │ │ ├── Application.java │ │ │ ├── controller │ │ │ └── v1 │ │ │ │ ├── api │ │ │ │ └── AppControllerV1.java │ │ │ │ ├── mapper │ │ │ │ └── AppDTOMapper.java │ │ │ │ └── request │ │ │ │ └── AppRequest.java │ │ │ ├── dto │ │ │ ├── mapper │ │ │ │ └── AppModelMapper.java │ │ │ └── model │ │ │ │ └── AppModelDTO.java │ │ │ ├── model │ │ │ └── AppModel.java │ │ │ ├── repository │ │ │ └── AppRepository.java │ │ │ └── service │ │ │ └── AppService.java │ │ └── resources │ │ ├── application.yml │ │ └── bootstrap.yml └── sample-service │ ├── Dockerfile │ ├── pom.xml │ ├── sample-service-chart │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── hpa.yaml │ │ ├── ingress.yaml │ │ ├── service.yaml │ │ ├── serviceaccount.yaml │ │ └── tests │ │ │ └── test-connection.yaml │ └── values.yaml │ └── src │ └── main │ ├── java │ └── sample_service │ │ ├── Application.java │ │ ├── controller │ │ └── v1 │ │ │ ├── api │ │ │ └── AppControllerV1.java │ │ │ ├── mapper │ │ │ └── AppDTOMapper.java │ │ │ └── request │ │ │ └── AppRequest.java │ │ ├── dto │ │ ├── mapper │ │ │ └── AppModelMapper.java │ │ └── model │ │ │ └── AppModelDTO.java │ │ ├── model │ │ └── AppModel.java │ │ ├── repository │ │ └── AppRepository.java │ │ └── service │ │ └── AppService.java │ └── resources │ ├── application.yml │ └── bootstrap.yml ├── assets └── images │ ├── create_maven_module.png │ ├── json_logs.PNG │ ├── load_parent_pom.png │ └── swagger_ui.PNG ├── backend-starter └── pom.xml ├── docs ├── _config.yml ├── allclasses-index.html ├── allpackages-index.html ├── apidocs │ ├── annotations │ │ ├── EnableDocs.html │ │ ├── package-summary.html │ │ └── package-tree.html │ └── config │ │ ├── SwaggerConfig.html │ │ ├── package-summary.html │ │ └── package-tree.html ├── constant-values.html ├── deprecated-list.html ├── element-list ├── exception │ ├── annotation │ │ ├── EnableExceptionHandler.html │ │ ├── package-summary.html │ │ └── package-tree.html │ ├── constant │ │ ├── ValidationExceptionType.html │ │ ├── package-summary.html │ │ └── package-tree.html │ ├── custom │ │ ├── DuplicateRecordException.html │ │ ├── EntityNotFoundException.html │ │ ├── FileHandlingException.html │ │ ├── InvalidStateTransitionException.html │ │ ├── MultipleActionFailedException.html │ │ ├── NotificationException.html │ │ ├── OperationFailedException.html │ │ ├── OperationNotAllowedException.html │ │ ├── package-summary.html │ │ └── package-tree.html │ ├── dto │ │ ├── AuthErrorDTO.html │ │ ├── ErrorDTO.html │ │ ├── MultipleActionErrorDTO.html │ │ ├── SubErrorDTO.html │ │ ├── ValidationErrorDTO.html │ │ ├── package-summary.html │ │ └── package-tree.html │ ├── handler │ │ ├── GlobalExceptionHandler.html │ │ ├── package-summary.html │ │ └── package-tree.html │ ├── message │ │ ├── ExceptionMessages.html │ │ ├── ValidationConstraintMessage.html │ │ ├── package-summary.html │ │ └── package-tree.html │ └── util │ │ ├── LowerCaseNameResolver.html │ │ ├── package-summary.html │ │ └── package-tree.html ├── file_handler │ ├── constant │ │ ├── OperationType.html │ │ ├── package-summary.html │ │ └── package-tree.html │ └── util │ │ ├── FileUtil.html │ │ ├── package-summary.html │ │ └── package-tree.html ├── help-doc.html ├── index-files │ ├── index-1.html │ ├── index-10.html │ ├── index-11.html │ ├── index-12.html │ ├── index-13.html │ ├── index-14.html │ ├── index-15.html │ ├── index-16.html │ ├── index-17.html │ ├── index-18.html │ ├── index-19.html │ ├── index-2.html │ ├── index-20.html │ ├── index-3.html │ ├── index-4.html │ ├── index-5.html │ ├── index-6.html │ ├── index-7.html │ ├── index-8.html │ └── index-9.html ├── index.html ├── logging │ ├── annotations │ │ ├── Loggable.html │ │ ├── package-summary.html │ │ └── package-tree.html │ └── aspects │ │ ├── LoggableAspect.html │ │ ├── LoggableControllerAspect.html │ │ ├── LoggableMapperAspect.html │ │ ├── LoggableRepositoryAspect.html │ │ ├── LoggableServiceAspect.html │ │ ├── package-summary.html │ │ └── package-tree.html ├── member-search-index.js ├── member-search-index.zip ├── notification │ ├── NotificationUtil.html │ ├── SignalR │ │ ├── SignalRMessage.html │ │ ├── package-summary.html │ │ └── package-tree.html │ ├── constant │ │ ├── NotificationMethod.html │ │ ├── package-summary.html │ │ └── package-tree.html │ ├── dto │ │ ├── GetNotificationDTO.html │ │ ├── package-summary.html │ │ └── package-tree.html │ ├── mapper │ │ ├── NotificationMapper.html │ │ ├── package-summary.html │ │ └── package-tree.html │ ├── package-summary.html │ └── package-tree.html ├── overview-summary.html ├── overview-tree.html ├── package-search-index.js ├── package-search-index.zip ├── resources │ ├── glass.png │ └── x.png ├── script-dir │ ├── external │ │ └── jquery │ │ │ └── jquery.js │ ├── images │ │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ │ ├── ui-bg_glass_65_dadada_1x400.png │ │ ├── ui-bg_glass_75_dadada_1x400.png │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ │ ├── ui-bg_glass_95_fef1ec_1x400.png │ │ ├── ui-bg_highlight-soft_75_cccccc_1x100.png │ │ ├── ui-icons_222222_256x240.png │ │ ├── ui-icons_2e83ff_256x240.png │ │ ├── ui-icons_454545_256x240.png │ │ ├── ui-icons_888888_256x240.png │ │ └── ui-icons_cd0a0a_256x240.png │ ├── jquery-3.4.1.js │ ├── jquery-ui.css │ ├── jquery-ui.js │ ├── jquery-ui.min.css │ ├── jquery-ui.min.js │ ├── jquery-ui.structure.css │ ├── jquery-ui.structure.min.css │ ├── jszip-utils │ │ └── dist │ │ │ ├── jszip-utils-ie.js │ │ │ ├── jszip-utils-ie.min.js │ │ │ ├── jszip-utils.js │ │ │ └── jszip-utils.min.js │ └── jszip │ │ └── dist │ │ ├── jszip.js │ │ └── jszip.min.js ├── script.js ├── search.js ├── security │ ├── aad │ │ ├── CustomAccessDeniedHandler.html │ │ ├── CustomAuthEntryPoint.html │ │ ├── ServletExceptionHandler.html │ │ ├── WebSecurityConfig.html │ │ ├── package-summary.html │ │ └── package-tree.html │ ├── config │ │ ├── MDCLogConfig.html │ │ ├── package-summary.html │ │ └── package-tree.html │ ├── constant │ │ ├── AuthorizationPermission.html │ │ ├── package-summary.html │ │ └── package-tree.html │ └── hashing │ │ ├── MD5.html │ │ ├── package-summary.html │ │ └── package-tree.html ├── serialized-form.html ├── stylesheet.css ├── system-properties.html ├── type-search-index.js ├── type-search-index.zip └── utility │ ├── annotations │ ├── AvoidDuplicate.html │ ├── ControllerV1.html │ ├── package-summary.html │ └── package-tree.html │ ├── aspect │ ├── AvoidDuplicateAspect.html │ ├── NotNullAspect.html │ ├── package-summary.html │ └── package-tree.html │ ├── constant │ ├── ActionType.html │ ├── AppConstant.html │ ├── EntityType.html │ ├── Messages.html │ ├── Misc.html │ ├── WorkorderState.html │ ├── WorkorderTagState.html │ ├── package-summary.html │ └── package-tree.html │ ├── custom_data_type │ ├── ValidList.html │ ├── package-summary.html │ └── package-tree.html │ ├── dto │ ├── DetailDTO.html │ ├── PartialSuccessDTO.html │ ├── ResponseDTO.html │ ├── package-summary.html │ └── package-tree.html │ ├── mapper │ ├── AppObjectMapper.html │ ├── package-summary.html │ └── package-tree.html │ ├── repository │ ├── BaseRepository.html │ ├── package-summary.html │ └── package-tree.html │ ├── request │ ├── BaseRequest.html │ ├── package-summary.html │ └── package-tree.html │ └── service │ ├── BaseService.html │ ├── package-summary.html │ └── package-tree.html ├── lib ├── api-docs │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── apidocs │ │ │ ├── annotations │ │ │ └── EnableDocs.java │ │ │ └── config │ │ │ └── SwaggerConfig.java │ │ └── resources │ │ └── META-INF │ │ └── spring.factories ├── exception │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── exception │ │ │ ├── annotation │ │ │ └── EnableExceptionHandler.java │ │ │ ├── constant │ │ │ └── ValidationExceptionType.java │ │ │ ├── custom │ │ │ ├── DuplicateRecordException.java │ │ │ ├── EntityNotFoundException.java │ │ │ ├── FileHandlingException.java │ │ │ ├── InvalidStateTransitionException.java │ │ │ ├── MultipleActionFailedException.java │ │ │ ├── NotificationException.java │ │ │ ├── OperationFailedException.java │ │ │ └── OperationNotAllowedException.java │ │ │ ├── dto │ │ │ ├── AuthErrorDTO.java │ │ │ ├── ErrorDTO.java │ │ │ ├── MultipleActionErrorDTO.java │ │ │ ├── SubErrorDTO.java │ │ │ └── ValidationErrorDTO.java │ │ │ ├── handler │ │ │ └── GlobalExceptionHandler.java │ │ │ ├── message │ │ │ ├── ExceptionMessages.java │ │ │ └── ValidationConstraintMessage.java │ │ │ └── util │ │ │ └── LowerCaseNameResolver.java │ │ └── resources │ │ └── META-INF │ │ └── spring.factories ├── file-handler │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── file_handler │ │ │ ├── constant │ │ │ └── OperationType.java │ │ │ └── util │ │ │ └── FileUtil.java │ │ └── resources │ │ └── META-INF │ │ └── spring.factories ├── logging │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── logging │ │ │ ├── annotations │ │ │ └── Loggable.java │ │ │ └── aspects │ │ │ ├── LoggableAspect.java │ │ │ ├── LoggableComponentAspect.java │ │ │ ├── LoggableControllerAspect.java │ │ │ ├── LoggableMapperAspect.java │ │ │ ├── LoggableRepositoryAspect.java │ │ │ └── LoggableServiceAspect.java │ │ └── resources │ │ ├── META-INF │ │ └── spring.factories │ │ ├── aaplication.yml │ │ └── logback-spring.xml ├── notification │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── notification │ │ ├── NotificationUtil.java │ │ ├── SignalR │ │ └── SignalRMessage.java │ │ ├── constant │ │ └── NotificationMethod.java │ │ ├── dto │ │ └── GetNotificationDTO.java │ │ └── mapper │ │ └── NotificationMapper.java ├── security │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── security │ │ │ ├── aad │ │ │ ├── CustomAccessDeniedHandler.java │ │ │ ├── CustomAuthEntryPoint.java │ │ │ ├── ServletExceptionHandler.java │ │ │ └── WebSecurityConfig.java │ │ │ ├── annotations │ │ │ └── EnableSecurity.java │ │ │ ├── config │ │ │ └── MDCLogConfig.java │ │ │ ├── constant │ │ │ └── AuthorizationPermission.java │ │ │ └── hashing │ │ │ └── MD5.java │ │ └── resources │ │ └── spring.factories └── utility │ ├── pom.xml │ └── src │ └── main │ ├── java │ └── utility │ │ ├── annotations │ │ ├── AvoidDuplicate.java │ │ └── ControllerV1.java │ │ ├── aspect │ │ ├── AvoidDuplicateAspect.java │ │ └── NotNullAspect.java │ │ ├── constant │ │ ├── ActionType.java │ │ ├── AppConstant.java │ │ ├── EntityType.java │ │ └── Messages.java │ │ ├── custom_data_type │ │ └── ValidList.java │ │ ├── dto │ │ ├── DetailDTO.java │ │ ├── PartialSuccessDTO.java │ │ └── ResponseDTO.java │ │ └── mapper │ │ └── AppObjectMapper.java │ └── resources │ └── META-INF │ └── spring.factories ├── pipelines └── azure-pipeline.yaml ├── pom.xml └── scripts ├── create_new_microservice.bat └── create_new_microservice.sh /.github/workflows/maven-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a package using Maven and then publish it to GitHub packages when a release is created 2 | # For more information see: https://github.com/actions/setup-java#apache-maven-with-a-settings-path 3 | 4 | name: Maven Package 5 | 6 | on: 7 | release: 8 | types: [created] 9 | 10 | jobs: 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: Set up JDK 1.8 18 | uses: actions/setup-java@v1 19 | with: 20 | java-version: 1.8 21 | server-id: github # Value of the distributionManagement/repository/id field of the pom.xml 22 | settings-path: ${{ github.workspace }} # location for the settings.xml file 23 | 24 | - name: Build with Maven 25 | run: mvn -B package --file pom.xml 26 | 27 | - name: Publish to GitHub Packages Apache Maven 28 | run: mvn deploy -s $GITHUB_WORKSPACE/settings.xml 29 | env: 30 | GITHUB_TOKEN: ${{ github.token }} 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /application/sample-service-with-aad-auth/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | backend-parent 7 | com.app 8 | 1.0.0-SNAPSHOT 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | sample-service-with-aad-auth 14 | 15 | 16 | 17 | 18 | com.app 19 | api-docs 20 | ${project.version} 21 | 22 | 23 | 24 | 25 | com.app 26 | backend-starter 27 | ${project.version} 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-data-jpa 32 | 33 | 34 | 35 | 36 | 37 | 38 | com.app 39 | utility 40 | ${project.version} 41 | 42 | 43 | 44 | 49 | 50 | 51 | 52 | sample-service-with-aad-auth 53 | 54 | 55 | org.springframework.boot 56 | spring-boot-maven-plugin 57 | 58 | 59 | true 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /application/sample-service-with-aad-auth/src/main/java/sample_service_with_aad_auth/Application.java: -------------------------------------------------------------------------------- 1 | package sample_service_with_aad_auth; 2 | 3 | import apidocs.annotations.EnableDocs; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import security.annotations.EnableSecurity; 7 | 8 | @SpringBootApplication 9 | @EnableDocs 10 | public class Application { 11 | public static void main( String[] args ) { SpringApplication.run(Application.class, args);} 12 | } 13 | -------------------------------------------------------------------------------- /application/sample-service-with-aad-auth/src/main/java/sample_service_with_aad_auth/controller/v1/api/AppControllerV1.java: -------------------------------------------------------------------------------- 1 | package sample_service_with_aad_auth.controller.v1.api; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.http.HttpStatus; 5 | import org.springframework.http.ResponseEntity; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.PostMapping; 8 | import org.springframework.web.bind.annotation.RequestBody; 9 | import org.springframework.web.bind.annotation.RequestParam; 10 | import sample_service_with_aad_auth.controller.v1.mapper.AppDTOMapper; 11 | import sample_service_with_aad_auth.controller.v1.request.AppRequest; 12 | import sample_service_with_aad_auth.service.AppService; 13 | import utility.annotations.ControllerV1; 14 | import utility.constant.ActionType; 15 | import utility.constant.EntityType; 16 | import utility.constant.Messages; 17 | import utility.custom_data_type.ValidList; 18 | import utility.dto.ResponseDTO; 19 | 20 | import javax.validation.Valid; 21 | import javax.validation.constraints.NotNull; 22 | 23 | @ControllerV1 24 | public class AppControllerV1 { 25 | 26 | @Autowired 27 | private AppService service; 28 | 29 | @GetMapping(path = "/greet") 30 | public ResponseEntity greetUser( @NotNull @RequestParam String name) { 31 | return ResponseEntity.ok(service.greetService(name)); 32 | } 33 | 34 | @PostMapping(path = "/user") 35 | public ResponseEntity setUserDetail(@Valid @RequestBody AppRequest request) { 36 | service.saveUser(new AppDTOMapper().convertToDTO(request)); 37 | return new ResponseEntity( ResponseDTO.setResponseDTO( 38 | Messages.setMessage(EntityType.USER, ActionType.CREATED, String.valueOf(request.getId()))), 39 | HttpStatus.CREATED 40 | ); 41 | } 42 | 43 | @PostMapping(path = "/users") 44 | public ResponseEntity setUsersDetail(@Valid @RequestBody ValidList request) { 45 | 46 | return new ResponseEntity( ResponseDTO.setResponseDTO( 47 | Messages.setMessage(EntityType.USER, ActionType.CREATED, "")), 48 | HttpStatus.CREATED 49 | ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /application/sample-service-with-aad-auth/src/main/java/sample_service_with_aad_auth/controller/v1/mapper/AppDTOMapper.java: -------------------------------------------------------------------------------- 1 | package sample_service_with_aad_auth.controller.v1.mapper; 2 | 3 | import logging.annotations.Loggable; 4 | import sample_service_with_aad_auth.controller.v1.request.AppRequest; 5 | import sample_service_with_aad_auth.dto.model.AppModelDTO; 6 | 7 | public class AppDTOMapper { 8 | 9 | @Loggable 10 | public AppModelDTO convertToDTO(AppRequest request) { 11 | AppModelDTO appModel = new AppModelDTO(); 12 | appModel.setId(request.getId()); 13 | appModel.setName(request.getName()); 14 | return appModel; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /application/sample-service-with-aad-auth/src/main/java/sample_service_with_aad_auth/controller/v1/request/AppRequest.java: -------------------------------------------------------------------------------- 1 | package sample_service_with_aad_auth.controller.v1.request; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import lombok.Setter; 6 | import lombok.experimental.Accessors; 7 | 8 | import javax.validation.constraints.NotNull; 9 | 10 | @Getter 11 | @Setter 12 | @NoArgsConstructor 13 | @Accessors(chain = true) 14 | public class AppRequest { 15 | 16 | @NotNull 17 | private Integer id; 18 | 19 | @NotNull 20 | private String name; 21 | } 22 | -------------------------------------------------------------------------------- /application/sample-service-with-aad-auth/src/main/java/sample_service_with_aad_auth/dto/mapper/AppModelMapper.java: -------------------------------------------------------------------------------- 1 | package sample_service_with_aad_auth.dto.mapper; 2 | 3 | import logging.annotations.Loggable; 4 | import sample_service_with_aad_auth.dto.model.AppModelDTO; 5 | import sample_service_with_aad_auth.model.AppModel; 6 | 7 | public class AppModelMapper { 8 | 9 | @Loggable(valueAfter = "Value After", valueAfterReturning = "Value After Returning", valueAround = "Value Around", valueBefore = "Value Before") 10 | public AppModel convertToModel(AppModelDTO modelDTO) { 11 | AppModel model = new AppModel(); 12 | model.setId(modelDTO.getId()); 13 | model.setName(modelDTO.getName()); 14 | return model; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /application/sample-service-with-aad-auth/src/main/java/sample_service_with_aad_auth/dto/model/AppModelDTO.java: -------------------------------------------------------------------------------- 1 | package sample_service_with_aad_auth.dto.model; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import lombok.Setter; 6 | 7 | @Setter 8 | @Getter 9 | @NoArgsConstructor 10 | public class AppModelDTO { 11 | 12 | private Integer id; 13 | 14 | private String name; 15 | } 16 | -------------------------------------------------------------------------------- /application/sample-service-with-aad-auth/src/main/java/sample_service_with_aad_auth/model/AppModel.java: -------------------------------------------------------------------------------- 1 | package sample_service_with_aad_auth.model; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import lombok.Setter; 6 | 7 | @Getter 8 | @Setter 9 | @NoArgsConstructor 10 | public class AppModel { 11 | private Integer id; 12 | 13 | private String name; 14 | } 15 | -------------------------------------------------------------------------------- /application/sample-service-with-aad-auth/src/main/java/sample_service_with_aad_auth/repository/AppRepository.java: -------------------------------------------------------------------------------- 1 | package sample_service_with_aad_auth.repository; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.jdbc.core.JdbcTemplate; 5 | import org.springframework.jdbc.core.simple.SimpleJdbcCall; 6 | import org.springframework.stereotype.Repository; 7 | import sample_service_with_aad_auth.model.AppModel; 8 | 9 | import javax.annotation.PostConstruct; 10 | 11 | @Repository 12 | public class AppRepository { 13 | 14 | @Autowired 15 | private JdbcTemplate jdbcTemplate; 16 | 17 | private SimpleJdbcCall simpleJdbcCall; 18 | 19 | 20 | public String greetRepository( String name ) { 21 | return name; 22 | } 23 | 24 | public void saveUser(AppModel model) { 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /application/sample-service-with-aad-auth/src/main/java/sample_service_with_aad_auth/service/AppService.java: -------------------------------------------------------------------------------- 1 | package sample_service_with_aad_auth.service; 2 | 3 | 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | import sample_service_with_aad_auth.dto.model.AppModelDTO; 8 | import sample_service_with_aad_auth.repository.AppRepository; 9 | 10 | @Service 11 | public class AppService { 12 | 13 | @Autowired 14 | private AppRepository repository; 15 | 16 | 17 | 18 | public String greetService( String name ) { 19 | return repository.greetRepository(name); 20 | } 21 | 22 | public void saveUser(AppModelDTO model) { 23 | 24 | } 25 | /* 26 | public ResponseEntity download(String url, String blobName) { 27 | return fileUtil.downloadBlob(url, blobName); 28 | } 29 | 30 | public void delete(String url, String blobName) { 31 | fileUtil.deleteBlob(url, blobName); 32 | } 33 | 34 | public URI uploadBlob(MultipartFile file, String blobName) { 35 | return fileUtil.uploadFile(file, blobName); 36 | } 37 | 38 | */ 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /application/sample-service-with-aad-auth/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: sample-service-with-aad-auth 4 | profiles.active: dev 5 | 6 | security.oauth2.client.registration.azure: 7 | client-id: c29fa5aa-6518-45ce-ad32-52fbc4b18abf 8 | client-secret: 9 | client-name: Azure 10 | 11 | datasource: 12 | type: com.zaxxer.hikari.HikariDataSource 13 | hikari: 14 | connection-timeout: 30000 15 | minimum-idle: 1 16 | maximum-pool-size: 10 17 | idle-timeout: 600000 18 | max-lifetime: 1800000 19 | auto-commit: true 20 | driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver 21 | jdbc-url: jdbc:sqlserver://localhost:1435;DatabaseName=practice 22 | username: 23 | password: 24 | leak-detection-threshold: 60000 25 | 26 | 27 | 28 | 29 | 30 | azure: 31 | activedirectory: 32 | client-id: c29fa5aa-6518-45ce-ad32-52fbc4b18abf 33 | allow-telemetry: true 34 | client-secret: 35 | user-group.allowed-groups: spring_boot_demo 36 | tenant-id: 37 | 38 | server: 39 | port: 8080 40 | servlet: 41 | session: 42 | cookie: 43 | http-only: true 44 | secure: true 45 | 46 | app: 47 | version: 1.0.0 48 | security: 49 | enabled: true 50 | 51 | swagger: 52 | enable-auth: true 53 | oauth: 54 | client-id: 05a5d9a5-f2c3-4f4b-9ea6-5f35adc0b902 55 | client-key: 56 | resource: api://c29fa5aa-6518-45ce-ad32-52fbc4b18abf 57 | login-endpoint: https://login.microsoftonline.com//oauth2/authorize 58 | title: Sample Service With AAD Enabled 59 | desc: Helps to interact with Backend 60 | version: v1 61 | path-mapping: / 62 | contact: 63 | name: Backend Team 64 | email: test@test.com 65 | url: "" 66 | license: null 67 | license-uri: null 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /application/sample-service-with-aad-auth/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/application/sample-service-with-aad-auth/src/main/resources/bootstrap.yml -------------------------------------------------------------------------------- /application/sample-service/Dockerfile: -------------------------------------------------------------------------------- 1 | ## STAGE 1 2 | FROM maven:3.6.3-adoptopenjdk-11 AS MAVEN_BUILD 3 | COPY . /backend/ 4 | WORKDIR /backend/ 5 | RUN mvn package 6 | 7 | ## STAGE 2 8 | FROM adoptopenjdk:11-jre-hotspot 9 | WORKDIR /app 10 | COPY --from=MAVEN_BUILD /backend/application/sample-service/target/sample-service.jar /app/ 11 | ENTRYPOINT ["java", "-jar", "sample-service.jar"] -------------------------------------------------------------------------------- /application/sample-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | backend-parent 7 | com.app 8 | 1.0.0-SNAPSHOT 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | sample-service 14 | 15 | 16 | 17 | 18 | com.app 19 | api-docs 20 | ${project.version} 21 | 22 | 23 | 24 | 25 | com.app 26 | backend-starter 27 | ${project.version} 28 | 29 | 30 | 31 | 32 | com.app 33 | utility 34 | ${project.version} 35 | 36 | 37 | 38 | 43 | 44 | 45 | 46 | 47 | 48 | sample-service 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-maven-plugin 53 | 54 | 55 | true 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /application/sample-service/sample-service-chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /application/sample-service/sample-service-chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: sample-service-chart 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | appVersion: 1.16.0 24 | -------------------------------------------------------------------------------- /application/sample-service/sample-service-chart/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range $host := .Values.ingress.hosts }} 4 | {{- range .paths }} 5 | http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }} 6 | {{- end }} 7 | {{- end }} 8 | {{- else if contains "NodePort" .Values.service.type }} 9 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "sample-service-chart.fullname" . }}) 10 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 11 | echo http://$NODE_IP:$NODE_PORT 12 | {{- else if contains "LoadBalancer" .Values.service.type }} 13 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 14 | You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "sample-service-chart.fullname" . }}' 15 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "sample-service-chart.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") 16 | echo http://$SERVICE_IP:{{ .Values.service.port }} 17 | {{- else if contains "ClusterIP" .Values.service.type }} 18 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "sample-service-chart.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 19 | export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") 20 | echo "Visit http://127.0.0.1:8080 to use your application" 21 | kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT 22 | {{- end }} 23 | -------------------------------------------------------------------------------- /application/sample-service/sample-service-chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "sample-service-chart.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "sample-service-chart.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "sample-service-chart.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "sample-service-chart.labels" -}} 37 | helm.sh/chart: {{ include "sample-service-chart.chart" . }} 38 | {{ include "sample-service-chart.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "sample-service-chart.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "sample-service-chart.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "sample-service-chart.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "sample-service-chart.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /application/sample-service/sample-service-chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "sample-service-chart.fullname" . }} 5 | labels: 6 | {{- include "sample-service-chart.labels" . | nindent 4 }} 7 | spec: 8 | {{- if not .Values.autoscaling.enabled }} 9 | replicas: {{ .Values.replicaCount }} 10 | {{- end }} 11 | selector: 12 | matchLabels: 13 | {{- include "sample-service-chart.selectorLabels" . | nindent 6 }} 14 | template: 15 | metadata: 16 | {{- with .Values.podAnnotations }} 17 | annotations: 18 | {{- toYaml . | nindent 8 }} 19 | {{- end }} 20 | labels: 21 | {{- include "sample-service-chart.selectorLabels" . | nindent 8 }} 22 | spec: 23 | {{- with .Values.imagePullSecrets }} 24 | imagePullSecrets: 25 | {{- toYaml . | nindent 8 }} 26 | {{- end }} 27 | serviceAccountName: {{ include "sample-service-chart.serviceAccountName" . }} 28 | securityContext: 29 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 30 | containers: 31 | - name: {{ .Chart.Name }} 32 | securityContext: 33 | {{- toYaml .Values.securityContext | nindent 12 }} 34 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" 35 | imagePullPolicy: {{ .Values.image.pullPolicy }} 36 | ports: 37 | - name: http 38 | containerPort: 80 39 | protocol: TCP 40 | livenessProbe: 41 | httpGet: 42 | path: / 43 | port: http 44 | readinessProbe: 45 | httpGet: 46 | path: / 47 | port: http 48 | resources: 49 | {{- toYaml .Values.resources | nindent 12 }} 50 | {{- with .Values.nodeSelector }} 51 | nodeSelector: 52 | {{- toYaml . | nindent 8 }} 53 | {{- end }} 54 | {{- with .Values.affinity }} 55 | affinity: 56 | {{- toYaml . | nindent 8 }} 57 | {{- end }} 58 | {{- with .Values.tolerations }} 59 | tolerations: 60 | {{- toYaml . | nindent 8 }} 61 | {{- end }} 62 | -------------------------------------------------------------------------------- /application/sample-service/sample-service-chart/templates/hpa.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.autoscaling.enabled }} 2 | apiVersion: autoscaling/v2beta1 3 | kind: HorizontalPodAutoscaler 4 | metadata: 5 | name: {{ include "sample-service-chart.fullname" . }} 6 | labels: 7 | {{- include "sample-service-chart.labels" . | nindent 4 }} 8 | spec: 9 | scaleTargetRef: 10 | apiVersion: apps/v1 11 | kind: Deployment 12 | name: {{ include "sample-service-chart.fullname" . }} 13 | minReplicas: {{ .Values.autoscaling.minReplicas }} 14 | maxReplicas: {{ .Values.autoscaling.maxReplicas }} 15 | metrics: 16 | {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} 17 | - type: Resource 18 | resource: 19 | name: cpu 20 | targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} 21 | {{- end }} 22 | {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} 23 | - type: Resource 24 | resource: 25 | name: memory 26 | targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} 27 | {{- end }} 28 | {{- end }} 29 | -------------------------------------------------------------------------------- /application/sample-service/sample-service-chart/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $fullName := include "sample-service-chart.fullname" . -}} 3 | {{- $svcPort := .Values.service.port -}} 4 | {{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} 5 | apiVersion: networking.k8s.io/v1beta1 6 | {{- else -}} 7 | apiVersion: extensions/v1beta1 8 | {{- end }} 9 | kind: Ingress 10 | metadata: 11 | name: {{ $fullName }} 12 | labels: 13 | {{- include "sample-service-chart.labels" . | nindent 4 }} 14 | {{- with .Values.ingress.annotations }} 15 | annotations: 16 | {{- toYaml . | nindent 4 }} 17 | {{- end }} 18 | spec: 19 | {{- if .Values.ingress.tls }} 20 | tls: 21 | {{- range .Values.ingress.tls }} 22 | - hosts: 23 | {{- range .hosts }} 24 | - {{ . | quote }} 25 | {{- end }} 26 | secretName: {{ .secretName }} 27 | {{- end }} 28 | {{- end }} 29 | rules: 30 | {{- range .Values.ingress.hosts }} 31 | - host: {{ .host | quote }} 32 | http: 33 | paths: 34 | {{- range .paths }} 35 | - path: {{ . }} 36 | backend: 37 | serviceName: {{ $fullName }} 38 | servicePort: {{ $svcPort }} 39 | {{- end }} 40 | {{- end }} 41 | {{- end }} 42 | -------------------------------------------------------------------------------- /application/sample-service/sample-service-chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "sample-service-chart.fullname" . }} 5 | labels: 6 | {{- include "sample-service-chart.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.port }} 11 | targetPort: http 12 | protocol: TCP 13 | name: http 14 | selector: 15 | {{- include "sample-service-chart.selectorLabels" . | nindent 4 }} 16 | -------------------------------------------------------------------------------- /application/sample-service/sample-service-chart/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "sample-service-chart.serviceAccountName" . }} 6 | labels: 7 | {{- include "sample-service-chart.labels" . | nindent 4 }} 8 | {{- with .Values.serviceAccount.annotations }} 9 | annotations: 10 | {{- toYaml . | nindent 4 }} 11 | {{- end }} 12 | {{- end }} 13 | -------------------------------------------------------------------------------- /application/sample-service/sample-service-chart/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "sample-service-chart.fullname" . }}-test-connection" 5 | labels: 6 | {{- include "sample-service-chart.labels" . | nindent 4 }} 7 | annotations: 8 | "helm.sh/hook": test 9 | spec: 10 | containers: 11 | - name: wget 12 | image: busybox 13 | command: ['wget'] 14 | args: ['{{ include "sample-service-chart.fullname" . }}:{{ .Values.service.port }}'] 15 | restartPolicy: Never 16 | -------------------------------------------------------------------------------- /application/sample-service/sample-service-chart/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for sample-service-chart. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: nginx 9 | pullPolicy: IfNotPresent 10 | # Overrides the image tag whose default is the chart appVersion. 11 | tag: "" 12 | 13 | imagePullSecrets: [] 14 | nameOverride: "" 15 | fullnameOverride: "" 16 | 17 | serviceAccount: 18 | # Specifies whether a service account should be created 19 | create: true 20 | # Annotations to add to the service account 21 | annotations: {} 22 | # The name of the service account to use. 23 | # If not set and create is true, a name is generated using the fullname template 24 | name: "" 25 | 26 | podAnnotations: {} 27 | 28 | podSecurityContext: {} 29 | # fsGroup: 2000 30 | 31 | securityContext: {} 32 | # capabilities: 33 | # drop: 34 | # - ALL 35 | # readOnlyRootFilesystem: true 36 | # runAsNonRoot: true 37 | # runAsUser: 1000 38 | 39 | service: 40 | type: ClusterIP 41 | port: 80 42 | 43 | ingress: 44 | enabled: false 45 | annotations: {} 46 | # kubernetes.io/ingress.class: nginx 47 | # kubernetes.io/tls-acme: "true" 48 | hosts: 49 | - host: chart-example.local 50 | paths: [] 51 | tls: [] 52 | # - secretName: chart-example-tls 53 | # hosts: 54 | # - chart-example.local 55 | 56 | resources: {} 57 | # We usually recommend not to specify default resources and to leave this as a conscious 58 | # choice for the user. This also increases chances charts run on environments with little 59 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 60 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 61 | # limits: 62 | # cpu: 100m 63 | # memory: 128Mi 64 | # requests: 65 | # cpu: 100m 66 | # memory: 128Mi 67 | 68 | autoscaling: 69 | enabled: false 70 | minReplicas: 1 71 | maxReplicas: 100 72 | targetCPUUtilizationPercentage: 80 73 | # targetMemoryUtilizationPercentage: 80 74 | 75 | nodeSelector: {} 76 | 77 | tolerations: [] 78 | 79 | affinity: {} 80 | -------------------------------------------------------------------------------- /application/sample-service/src/main/java/sample_service/Application.java: -------------------------------------------------------------------------------- 1 | package sample_service; 2 | 3 | import apidocs.annotations.EnableDocs; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import security.annotations.EnableSecurity; 7 | 8 | @SpringBootApplication 9 | @EnableDocs 10 | public class Application { 11 | public static void main( String[] args ) { SpringApplication.run(Application.class, args);} 12 | } 13 | -------------------------------------------------------------------------------- /application/sample-service/src/main/java/sample_service/controller/v1/api/AppControllerV1.java: -------------------------------------------------------------------------------- 1 | package sample_service.controller.v1.api; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.http.HttpStatus; 5 | import org.springframework.http.ResponseEntity; 6 | import org.springframework.security.access.prepost.PreAuthorize; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.PostMapping; 9 | import org.springframework.web.bind.annotation.RequestBody; 10 | import org.springframework.web.bind.annotation.RequestParam; 11 | import sample_service.controller.v1.mapper.AppDTOMapper; 12 | import sample_service.controller.v1.request.AppRequest; 13 | import sample_service.service.AppService; 14 | import utility.annotations.ControllerV1; 15 | import utility.constant.ActionType; 16 | import utility.constant.EntityType; 17 | import utility.constant.Messages; 18 | import utility.custom_data_type.ValidList; 19 | import utility.dto.ResponseDTO; 20 | 21 | import javax.validation.Valid; 22 | import javax.validation.constraints.NotNull; 23 | 24 | @ControllerV1 25 | public class AppControllerV1 { 26 | 27 | @Autowired 28 | private AppService service; 29 | 30 | @GetMapping(path = "/greet") 31 | public ResponseEntity greetUser( @NotNull @RequestParam String name) { 32 | return ResponseEntity.ok(service.greetService(name)); 33 | } 34 | 35 | @PostMapping(path = "/user") 36 | public ResponseEntity setUserDetail(@Valid @RequestBody AppRequest request) { 37 | service.saveUser(new AppDTOMapper().convertToDTO(request)); 38 | return new ResponseEntity( ResponseDTO.setResponseDTO( 39 | Messages.setMessage(EntityType.USER, ActionType.CREATED, String.valueOf(request.getId()))), 40 | HttpStatus.CREATED 41 | ); 42 | } 43 | 44 | @PostMapping(path = "/users") 45 | public ResponseEntity setUsersDetail(@Valid @RequestBody ValidList request) { 46 | 47 | return new ResponseEntity( ResponseDTO.setResponseDTO( 48 | Messages.setMessage(EntityType.USER, ActionType.CREATED, "")), 49 | HttpStatus.CREATED 50 | ); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /application/sample-service/src/main/java/sample_service/controller/v1/mapper/AppDTOMapper.java: -------------------------------------------------------------------------------- 1 | package sample_service.controller.v1.mapper; 2 | 3 | // import logging.annotations.Loggable; 4 | import sample_service.controller.v1.request.AppRequest; 5 | import sample_service.dto.model.AppModelDTO; 6 | 7 | public class AppDTOMapper { 8 | 9 | // @Loggable 10 | public AppModelDTO convertToDTO(AppRequest request) { 11 | AppModelDTO appModel = new AppModelDTO(); 12 | appModel.setId(request.getId()); 13 | appModel.setName(request.getName()); 14 | return appModel; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /application/sample-service/src/main/java/sample_service/controller/v1/request/AppRequest.java: -------------------------------------------------------------------------------- 1 | package sample_service.controller.v1.request; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import lombok.Setter; 6 | import lombok.experimental.Accessors; 7 | 8 | import javax.validation.constraints.NotNull; 9 | 10 | @Getter 11 | @Setter 12 | @NoArgsConstructor 13 | @Accessors(chain = true) 14 | public class AppRequest { 15 | 16 | @NotNull 17 | private Integer id; 18 | 19 | @NotNull 20 | private String name; 21 | } 22 | -------------------------------------------------------------------------------- /application/sample-service/src/main/java/sample_service/dto/mapper/AppModelMapper.java: -------------------------------------------------------------------------------- 1 | package sample_service.dto.mapper; 2 | 3 | //import logging.annotations.Loggable; 4 | import sample_service.dto.model.AppModelDTO; 5 | import sample_service.model.AppModel; 6 | 7 | public class AppModelMapper { 8 | 9 | // @Loggable(valueAfter = "Value After", valueAfterReturning = "Value After Returning", valueAround = "Value Around", valueBefore = "Value Before") 10 | public AppModel convertToModel(AppModelDTO modelDTO) { 11 | AppModel model = new AppModel(); 12 | model.setId(modelDTO.getId()); 13 | model.setName(modelDTO.getName()); 14 | return model; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /application/sample-service/src/main/java/sample_service/dto/model/AppModelDTO.java: -------------------------------------------------------------------------------- 1 | package sample_service.dto.model; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import lombok.Setter; 6 | 7 | @Setter 8 | @Getter 9 | @NoArgsConstructor 10 | public class AppModelDTO { 11 | 12 | private Integer id; 13 | 14 | private String name; 15 | } 16 | -------------------------------------------------------------------------------- /application/sample-service/src/main/java/sample_service/model/AppModel.java: -------------------------------------------------------------------------------- 1 | package sample_service.model; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import lombok.Setter; 6 | 7 | @Getter 8 | @Setter 9 | @NoArgsConstructor 10 | public class AppModel { 11 | private Integer id; 12 | 13 | private String name; 14 | } 15 | -------------------------------------------------------------------------------- /application/sample-service/src/main/java/sample_service/repository/AppRepository.java: -------------------------------------------------------------------------------- 1 | package sample_service.repository; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.jdbc.core.JdbcTemplate; 5 | import org.springframework.jdbc.core.simple.SimpleJdbcCall; 6 | import org.springframework.stereotype.Repository; 7 | import sample_service.model.AppModel; 8 | 9 | 10 | @Repository 11 | public class AppRepository { 12 | 13 | private JdbcTemplate jdbcTemplate; 14 | 15 | @Autowired 16 | AppRepository(JdbcTemplate template) { 17 | jdbcTemplate = template; 18 | } 19 | // private SimpleJdbcCall simpleJdbcCall; 20 | 21 | 22 | public String greetRepository( String name ) { 23 | return name; 24 | } 25 | 26 | public void saveUser(AppModel model) { 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /application/sample-service/src/main/java/sample_service/service/AppService.java: -------------------------------------------------------------------------------- 1 | package sample_service.service; 2 | 3 | 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.core.io.Resource; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.stereotype.Service; 9 | import org.springframework.web.multipart.MultipartFile; 10 | import sample_service.dto.model.AppModelDTO; 11 | import sample_service.repository.AppRepository; 12 | 13 | 14 | import java.net.URI; 15 | 16 | @Service 17 | public class AppService { 18 | 19 | @Autowired 20 | private AppRepository repository; 21 | 22 | 23 | 24 | public String greetService( String name ) { 25 | return repository.greetRepository(name); 26 | } 27 | 28 | public void saveUser(AppModelDTO model) { } 29 | /* 30 | public ResponseEntity download(String url, String blobName) { 31 | return fileUtil.downloadBlob(url, blobName); 32 | } 33 | 34 | public void delete(String url, String blobName) { 35 | fileUtil.deleteBlob(url, blobName); 36 | } 37 | 38 | public URI uploadBlob(MultipartFile file, String blobName) { 39 | return fileUtil.uploadFile(file, blobName); 40 | } 41 | 42 | */ 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /application/sample-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: sample-service 4 | 5 | datasource: 6 | type: com.zaxxer.hikari.HikariDataSource 7 | driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver 8 | username: sa 9 | password: 10 | url: jdbc:sqlserver://localhost:1433;DatabaseName=code_with_nk_db 11 | 12 | autoconfigure: 13 | exclude: 14 | - org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration 15 | - org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration 16 | 17 | 18 | server: 19 | port: 8080 20 | servlet: 21 | session: 22 | cookie: 23 | http-only: true 24 | secure: true 25 | 26 | app: 27 | version: 1.0.0 28 | security: 29 | enabled: true 30 | swagger: 31 | enable-auth: false 32 | title: Sample Service 33 | desc: Helps to interact with Backend 34 | version: v1 35 | path-mapping: / 36 | contact: 37 | name: Backend Team 38 | email: test@test.com 39 | url: "" 40 | license: null 41 | license-uri: null 42 | 43 | logging: 44 | level: 45 | com: 46 | zaxxer: 47 | hikari: debug 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /application/sample-service/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/application/sample-service/src/main/resources/bootstrap.yml -------------------------------------------------------------------------------- /assets/images/create_maven_module.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/assets/images/create_maven_module.png -------------------------------------------------------------------------------- /assets/images/json_logs.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/assets/images/json_logs.PNG -------------------------------------------------------------------------------- /assets/images/load_parent_pom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/assets/images/load_parent_pom.png -------------------------------------------------------------------------------- /assets/images/swagger_ui.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/assets/images/swagger_ui.PNG -------------------------------------------------------------------------------- /backend-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | backend-parent 7 | com.app 8 | 1.0.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | backend-starter 13 | jar 14 | 15 | 16 | 17 | com.app 18 | security 19 | ${project.version} 20 | 21 | 22 | com.app 23 | logging 24 | ${project.version} 25 | 26 | 27 | com.app 28 | exception 29 | ${project.version} 30 | 31 | 32 | 33 | 37 | 38 | 39 | 40 | com.konghq 41 | unirest-java 42 | ${unirest.version} 43 | 44 | 45 | 46 | 47 | org.springframework.security 48 | spring-security-oauth2-jose 49 | 5.4.5 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-hacker -------------------------------------------------------------------------------- /docs/apidocs/annotations/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | apidocs.annotations Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Hierarchy For Package apidocs.annotations

65 | Package Hierarchies: 66 | 69 |
70 |
71 |
72 |

Annotation Type Hierarchy

73 |
    74 |
  • apidocs.annotations.EnableDocs (implements java.lang.annotation.Annotation)
  • 75 |
76 |
77 |
78 |
79 | 105 |
106 |
107 | 108 | 109 | -------------------------------------------------------------------------------- /docs/apidocs/config/package-summary.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | apidocs.config 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Package apidocs.config

65 |
66 |
67 |
68 |
    69 |
  • 70 |
    71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 |
    Class Summary 
    ClassDescription
    SwaggerConfig 
    86 |
    87 |
  • 88 |
89 |
90 |
91 |
92 | 118 |
119 |
120 | 121 | 122 | -------------------------------------------------------------------------------- /docs/apidocs/config/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | apidocs.config Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Hierarchy For Package apidocs.config

65 | Package Hierarchies: 66 | 69 |
70 |
71 |
72 |

Class Hierarchy

73 |
    74 |
  • java.lang.Object 75 | 78 |
  • 79 |
80 |
81 |
82 |
83 | 109 |
110 |
111 | 112 | 113 | -------------------------------------------------------------------------------- /docs/deprecated-list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Deprecated List 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Deprecated API

65 |

Contents

66 |
67 |
68 | 94 |
95 |
96 | 97 | 98 | -------------------------------------------------------------------------------- /docs/element-list: -------------------------------------------------------------------------------- 1 | apidocs.annotations 2 | apidocs.config 3 | exception.annotation 4 | exception.constant 5 | exception.custom 6 | exception.dto 7 | exception.handler 8 | exception.message 9 | exception.util 10 | file_handler.constant 11 | file_handler.util 12 | logging.annotations 13 | logging.aspects 14 | notification 15 | notification.constant 16 | notification.dto 17 | notification.mapper 18 | notification.SignalR 19 | security.aad 20 | security.config 21 | security.constant 22 | security.hashing 23 | utility.annotations 24 | utility.aspect 25 | utility.constant 26 | utility.custom_data_type 27 | utility.dto 28 | utility.mapper 29 | utility.repository 30 | utility.request 31 | utility.service 32 | -------------------------------------------------------------------------------- /docs/exception/annotation/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | exception.annotation Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Hierarchy For Package exception.annotation

65 | Package Hierarchies: 66 | 69 |
70 |
71 |
72 |

Annotation Type Hierarchy

73 | 76 |
77 |
78 |
79 | 105 |
106 |
107 | 108 | 109 | -------------------------------------------------------------------------------- /docs/file_handler/util/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | file_handler.util Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Hierarchy For Package file_handler.util

65 | Package Hierarchies: 66 | 69 |
70 |
71 |
72 |

Class Hierarchy

73 |
    74 |
  • java.lang.Object 75 | 78 |
  • 79 |
80 |
81 |
82 |
83 | 109 |
110 |
111 | 112 | 113 | -------------------------------------------------------------------------------- /docs/logging/annotations/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | logging.annotations Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Hierarchy For Package logging.annotations

65 | Package Hierarchies: 66 | 69 |
70 |
71 |
72 |

Annotation Type Hierarchy

73 |
    74 |
  • logging.annotations.Loggable (implements java.lang.annotation.Annotation)
  • 75 |
76 |
77 |
78 |
79 | 105 |
106 |
107 | 108 | 109 | -------------------------------------------------------------------------------- /docs/member-search-index.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/docs/member-search-index.zip -------------------------------------------------------------------------------- /docs/notification/SignalR/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | notification.SignalR Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Hierarchy For Package notification.SignalR

65 | Package Hierarchies: 66 | 69 |
70 |
71 |
72 |

Class Hierarchy

73 |
    74 |
  • java.lang.Object 75 | 78 |
  • 79 |
80 |
81 |
82 |
83 | 109 |
110 |
111 | 112 | 113 | -------------------------------------------------------------------------------- /docs/notification/dto/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | notification.dto Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Hierarchy For Package notification.dto

65 | Package Hierarchies: 66 | 69 |
70 |
71 |
72 |

Class Hierarchy

73 | 80 |
81 |
82 |
83 | 109 |
110 |
111 | 112 | 113 | -------------------------------------------------------------------------------- /docs/notification/mapper/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | notification.mapper Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Hierarchy For Package notification.mapper

65 | Package Hierarchies: 66 | 69 |
70 |
71 |
72 |

Class Hierarchy

73 | 80 |
81 |
82 |
83 | 109 |
110 |
111 | 112 | 113 | -------------------------------------------------------------------------------- /docs/notification/package-summary.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | notification 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Package notification

65 |
66 |
67 |
68 |
    69 |
  • 70 |
    71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 |
    Class Summary 
    ClassDescription
    NotificationUtil 
    86 |
    87 |
  • 88 |
89 |
90 |
91 |
92 | 118 |
119 |
120 | 121 | 122 | -------------------------------------------------------------------------------- /docs/notification/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | notification Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Hierarchy For Package notification

65 | Package Hierarchies: 66 | 69 |
70 |
71 |
72 |

Class Hierarchy

73 | 80 |
81 |
82 |
83 | 109 |
110 |
111 | 112 | 113 | -------------------------------------------------------------------------------- /docs/overview-summary.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Generated Documentation (Untitled) 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 19 |
20 | 23 |

index.html

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /docs/package-search-index.js: -------------------------------------------------------------------------------- 1 | packageSearchIndex = [{"l":"All Packages","url":"allpackages-index.html"},{"l":"apidocs.annotations"},{"l":"apidocs.config"},{"l":"exception.annotation"},{"l":"exception.constant"},{"l":"exception.custom"},{"l":"exception.dto"},{"l":"exception.handler"},{"l":"exception.message"},{"l":"exception.util"},{"l":"file_handler.constant"},{"l":"file_handler.util"},{"l":"logging.annotations"},{"l":"logging.aspects"},{"l":"notification"},{"l":"notification.constant"},{"l":"notification.dto"},{"l":"notification.mapper"},{"l":"notification.SignalR"},{"l":"security.aad"},{"l":"security.config"},{"l":"security.constant"},{"l":"security.hashing"},{"l":"utility.annotations"},{"l":"utility.aspect"},{"l":"utility.constant"},{"l":"utility.custom_data_type"},{"l":"utility.dto"},{"l":"utility.mapper"},{"l":"utility.repository"},{"l":"utility.request"},{"l":"utility.service"}] -------------------------------------------------------------------------------- /docs/package-search-index.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/docs/package-search-index.zip -------------------------------------------------------------------------------- /docs/resources/glass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/docs/resources/glass.png -------------------------------------------------------------------------------- /docs/resources/x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/docs/resources/x.png -------------------------------------------------------------------------------- /docs/script-dir/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/docs/script-dir/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /docs/script-dir/images/ui-bg_glass_65_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/docs/script-dir/images/ui-bg_glass_65_dadada_1x400.png -------------------------------------------------------------------------------- /docs/script-dir/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/docs/script-dir/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /docs/script-dir/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/docs/script-dir/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /docs/script-dir/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/docs/script-dir/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /docs/script-dir/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/docs/script-dir/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /docs/script-dir/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/docs/script-dir/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /docs/script-dir/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/docs/script-dir/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /docs/script-dir/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/docs/script-dir/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /docs/script-dir/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/docs/script-dir/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /docs/script-dir/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/docs/script-dir/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /docs/script-dir/jquery-ui.structure.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery UI CSS Framework 1.12.1 3 | * http://jqueryui.com 4 | * 5 | * Copyright jQuery Foundation and other contributors 6 | * Released under the MIT license. 7 | * http://jquery.org/license 8 | * 9 | * http://api.jqueryui.com/category/theming/ 10 | */ 11 | /* Layout helpers 12 | ----------------------------------*/ 13 | .ui-helper-hidden { 14 | display: none; 15 | } 16 | .ui-helper-hidden-accessible { 17 | border: 0; 18 | clip: rect(0 0 0 0); 19 | height: 1px; 20 | margin: -1px; 21 | overflow: hidden; 22 | padding: 0; 23 | position: absolute; 24 | width: 1px; 25 | } 26 | .ui-helper-reset { 27 | margin: 0; 28 | padding: 0; 29 | border: 0; 30 | outline: 0; 31 | line-height: 1.3; 32 | text-decoration: none; 33 | font-size: 100%; 34 | list-style: none; 35 | } 36 | .ui-helper-clearfix:before, 37 | .ui-helper-clearfix:after { 38 | content: ""; 39 | display: table; 40 | border-collapse: collapse; 41 | } 42 | .ui-helper-clearfix:after { 43 | clear: both; 44 | } 45 | .ui-helper-zfix { 46 | width: 100%; 47 | height: 100%; 48 | top: 0; 49 | left: 0; 50 | position: absolute; 51 | opacity: 0; 52 | filter:Alpha(Opacity=0); /* support: IE8 */ 53 | } 54 | 55 | .ui-front { 56 | z-index: 100; 57 | } 58 | 59 | 60 | /* Interaction Cues 61 | ----------------------------------*/ 62 | .ui-state-disabled { 63 | cursor: default !important; 64 | pointer-events: none; 65 | } 66 | 67 | 68 | /* Icons 69 | ----------------------------------*/ 70 | .ui-icon { 71 | display: inline-block; 72 | vertical-align: middle; 73 | margin-top: -.25em; 74 | position: relative; 75 | text-indent: -99999px; 76 | overflow: hidden; 77 | background-repeat: no-repeat; 78 | } 79 | 80 | .ui-widget-icon-block { 81 | left: 50%; 82 | margin-left: -8px; 83 | display: block; 84 | } 85 | 86 | /* Misc visuals 87 | ----------------------------------*/ 88 | 89 | /* Overlays */ 90 | .ui-widget-overlay { 91 | position: fixed; 92 | top: 0; 93 | left: 0; 94 | width: 100%; 95 | height: 100%; 96 | } 97 | .ui-autocomplete { 98 | position: absolute; 99 | top: 0; 100 | left: 0; 101 | cursor: default; 102 | } 103 | .ui-menu { 104 | list-style: none; 105 | padding: 0; 106 | margin: 0; 107 | display: block; 108 | outline: 0; 109 | } 110 | .ui-menu .ui-menu { 111 | position: absolute; 112 | } 113 | .ui-menu .ui-menu-item { 114 | margin: 0; 115 | cursor: pointer; 116 | /* support: IE10, see #8844 */ 117 | list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"); 118 | } 119 | .ui-menu .ui-menu-item-wrapper { 120 | position: relative; 121 | padding: 3px 1em 3px .4em; 122 | } 123 | .ui-menu .ui-menu-divider { 124 | margin: 5px 0; 125 | height: 0; 126 | font-size: 0; 127 | line-height: 0; 128 | border-width: 1px 0 0 0; 129 | } 130 | .ui-menu .ui-state-focus, 131 | .ui-menu .ui-state-active { 132 | margin: -1px; 133 | } 134 | 135 | /* icon support */ 136 | .ui-menu-icons { 137 | position: relative; 138 | } 139 | .ui-menu-icons .ui-menu-item-wrapper { 140 | padding-left: 2em; 141 | } 142 | 143 | /* left-aligned */ 144 | .ui-menu .ui-icon { 145 | position: absolute; 146 | top: 0; 147 | bottom: 0; 148 | left: .2em; 149 | margin: auto 0; 150 | } 151 | 152 | /* right-aligned */ 153 | .ui-menu .ui-menu-icon { 154 | left: auto; 155 | right: 0; 156 | } 157 | -------------------------------------------------------------------------------- /docs/script-dir/jquery-ui.structure.min.css: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.12.1 - 2018-12-06 2 | * http://jqueryui.com 3 | * Copyright jQuery Foundation and other contributors; Licensed MIT */ 4 | 5 | .ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:0}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{margin:0;cursor:pointer;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-item-wrapper{position:relative;padding:3px 1em 3px .4em}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item-wrapper{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0} -------------------------------------------------------------------------------- /docs/script-dir/jszip-utils/dist/jszip-utils-ie.js: -------------------------------------------------------------------------------- 1 | /*! 2 | 3 | JSZipUtils - A collection of cross-browser utilities to go along with JSZip. 4 | 5 | 6 | (c) 2014 Stuart Knightley, David Duponchel 7 | Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip-utils/master/LICENSE.markdown. 8 | 9 | */ 10 | ;(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o\r\n"+ 18 | "\r\n"; 32 | 33 | // inject VBScript 34 | document.write(IEBinaryToArray_ByteStr_Script); 35 | 36 | global.JSZipUtils._getBinaryFromXHR = function (xhr) { 37 | var binary = xhr.responseBody; 38 | var byteMapping = {}; 39 | for ( var i = 0; i < 256; i++ ) { 40 | for ( var j = 0; j < 256; j++ ) { 41 | byteMapping[ String.fromCharCode( i + (j << 8) ) ] = 42 | String.fromCharCode(i) + String.fromCharCode(j); 43 | } 44 | } 45 | var rawBytes = IEBinaryToArray_ByteStr(binary); 46 | var lastChr = IEBinaryToArray_ByteStr_Last(binary); 47 | return rawBytes.replace(/[\s\S]/g, function( match ) { 48 | return byteMapping[match]; 49 | }) + lastChr; 50 | }; 51 | 52 | // enforcing Stuk's coding style 53 | // vim: set shiftwidth=4 softtabstop=4: 54 | 55 | },{}]},{},[1]) 56 | ; 57 | -------------------------------------------------------------------------------- /docs/script-dir/jszip-utils/dist/jszip-utils-ie.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | 3 | JSZipUtils - A collection of cross-browser utilities to go along with JSZip. 4 | 5 | 6 | (c) 2014 Stuart Knightley, David Duponchel 7 | Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip-utils/master/LICENSE.markdown. 8 | 9 | */ 10 | !function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g\r\n";document.write(b),a.JSZipUtils._getBinaryFromXHR=function(a){for(var b=a.responseBody,c={},d=0;256>d;d++)for(var e=0;256>e;e++)c[String.fromCharCode(d+(e<<8))]=String.fromCharCode(d)+String.fromCharCode(e);var f=IEBinaryToArray_ByteStr(b),g=IEBinaryToArray_ByteStr_Last(b);return f.replace(/[\s\S]/g,function(a){return c[a]})+g}},{}]},{},[1]); 11 | -------------------------------------------------------------------------------- /docs/script-dir/jszip-utils/dist/jszip-utils.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | 3 | JSZipUtils - A collection of cross-browser utilities to go along with JSZip. 4 | 5 | 6 | (c) 2014 Stuart Knightley, David Duponchel 7 | Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip-utils/master/LICENSE.markdown. 8 | 9 | */ 10 | !function(a){"object"==typeof exports?module.exports=a():"function"==typeof define&&define.amd?define(a):"undefined"!=typeof window?window.JSZipUtils=a():"undefined"!=typeof global?global.JSZipUtils=a():"undefined"!=typeof self&&(self.JSZipUtils=a())}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g 2 | 3 | 4 | 5 | 6 | security.constant Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Hierarchy For Package security.constant

65 | Package Hierarchies: 66 | 69 |
70 |
71 |
72 |

Class Hierarchy

73 | 80 |
81 |
82 |
83 | 109 |
110 |
111 | 112 | 113 | -------------------------------------------------------------------------------- /docs/security/hashing/package-summary.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | security.hashing 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Package security.hashing

65 |
66 |
67 |
68 |
    69 |
  • 70 |
    71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 |
    Class Summary 
    ClassDescription
    MD5 
    86 |
    87 |
  • 88 |
89 |
90 |
91 |
92 | 118 |
119 |
120 | 121 | 122 | -------------------------------------------------------------------------------- /docs/security/hashing/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | security.hashing Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Hierarchy For Package security.hashing

65 | Package Hierarchies: 66 | 69 |
70 |
71 |
72 |

Class Hierarchy

73 |
    74 |
  • java.lang.Object 75 |
      76 |
    • security.hashing.MD5
    • 77 |
    78 |
  • 79 |
80 |
81 |
82 |
83 | 109 |
110 |
111 | 112 | 113 | -------------------------------------------------------------------------------- /docs/system-properties.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | System Properties 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 59 |
60 |
61 |
62 |

System Properties

63 |
64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 |
System Properties Summary 
PropertyReferenced In
75 |
76 |
77 |
78 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /docs/type-search-index.js: -------------------------------------------------------------------------------- 1 | typeSearchIndex = [{"p":"utility.constant","l":"ActionType"},{"l":"All Classes","url":"allclasses-index.html"},{"p":"utility.constant","l":"AppConstant"},{"p":"utility.mapper","l":"AppObjectMapper"},{"p":"exception.dto","l":"AuthErrorDTO"},{"p":"security.constant","l":"AuthorizationPermission"},{"p":"utility.annotations","l":"AvoidDuplicate"},{"p":"utility.aspect","l":"AvoidDuplicateAspect"},{"p":"utility.repository","l":"BaseRepository"},{"p":"utility.request","l":"BaseRequest"},{"p":"utility.service","l":"BaseService"},{"p":"utility.annotations","l":"ControllerV1"},{"p":"security.aad","l":"CustomAccessDeniedHandler"},{"p":"security.aad","l":"CustomAuthEntryPoint"},{"p":"utility.dto","l":"DetailDTO"},{"p":"exception.custom","l":"DuplicateRecordException"},{"p":"apidocs.annotations","l":"EnableDocs"},{"p":"exception.annotation","l":"EnableExceptionHandler"},{"p":"exception.custom","l":"EntityNotFoundException"},{"p":"utility.constant","l":"EntityType"},{"p":"exception.dto","l":"ErrorDTO"},{"p":"exception.message","l":"ExceptionMessages"},{"p":"exception.custom","l":"FileHandlingException"},{"p":"file_handler.util","l":"FileUtil"},{"p":"notification.dto","l":"GetNotificationDTO"},{"p":"exception.handler","l":"GlobalExceptionHandler"},{"p":"exception.custom","l":"InvalidStateTransitionException"},{"p":"logging.annotations","l":"Loggable"},{"p":"logging.aspects","l":"LoggableAspect"},{"p":"logging.aspects","l":"LoggableControllerAspect"},{"p":"logging.aspects","l":"LoggableMapperAspect"},{"p":"logging.aspects","l":"LoggableRepositoryAspect"},{"p":"logging.aspects","l":"LoggableServiceAspect"},{"p":"exception.util","l":"LowerCaseNameResolver"},{"p":"security.hashing","l":"MD5"},{"p":"security.config","l":"MDCLogConfig"},{"p":"utility.constant","l":"Messages"},{"p":"utility.constant","l":"Misc"},{"p":"exception.dto","l":"MultipleActionErrorDTO"},{"p":"exception.custom","l":"MultipleActionFailedException"},{"p":"exception.custom","l":"NotificationException"},{"p":"notification.mapper","l":"NotificationMapper"},{"p":"notification.constant","l":"NotificationMethod"},{"p":"notification","l":"NotificationUtil"},{"p":"utility.aspect","l":"NotNullAspect"},{"p":"exception.custom","l":"OperationFailedException"},{"p":"exception.custom","l":"OperationNotAllowedException"},{"p":"file_handler.constant","l":"OperationType"},{"p":"utility.dto","l":"PartialSuccessDTO"},{"p":"utility.dto","l":"ResponseDTO"},{"p":"security.aad","l":"ServletExceptionHandler"},{"p":"notification.SignalR","l":"SignalRMessage"},{"p":"exception.dto","l":"SubErrorDTO"},{"p":"apidocs.config","l":"SwaggerConfig"},{"p":"exception.message","l":"ValidationConstraintMessage"},{"p":"exception.dto","l":"ValidationErrorDTO"},{"p":"exception.constant","l":"ValidationExceptionType"},{"p":"utility.custom_data_type","l":"ValidList"},{"p":"security.aad","l":"WebSecurityConfig"},{"p":"utility.constant","l":"WorkorderState"},{"p":"utility.constant","l":"WorkorderTagState"}] -------------------------------------------------------------------------------- /docs/type-search-index.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/docs/type-search-index.zip -------------------------------------------------------------------------------- /docs/utility/custom_data_type/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | utility.custom_data_type Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Hierarchy For Package utility.custom_data_type

65 | Package Hierarchies: 66 | 69 |
70 |
71 |
72 |

Class Hierarchy

73 |
    74 |
  • java.lang.Object 75 |
      76 |
    • utility.custom_data_type.ValidList<E> (implements java.util.List<E>)
    • 77 |
    78 |
  • 79 |
80 |
81 |
82 |
83 | 109 |
110 |
111 | 112 | 113 | -------------------------------------------------------------------------------- /docs/utility/mapper/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | utility.mapper Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Hierarchy For Package utility.mapper

65 | Package Hierarchies: 66 | 69 |
70 |
71 |
72 |

Class Hierarchy

73 |
    74 |
  • java.lang.Object 75 | 78 |
  • 79 |
80 |
81 |
82 |
83 | 109 |
110 |
111 | 112 | 113 | -------------------------------------------------------------------------------- /docs/utility/repository/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | utility.repository Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Hierarchy For Package utility.repository

65 | Package Hierarchies: 66 | 69 |
70 |
71 |
72 |

Class Hierarchy

73 |
    74 |
  • java.lang.Object 75 | 78 |
  • 79 |
80 |
81 |
82 |
83 | 109 |
110 |
111 | 112 | 113 | -------------------------------------------------------------------------------- /docs/utility/request/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | utility.request Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Hierarchy For Package utility.request

65 | Package Hierarchies: 66 | 69 |
70 |
71 |
72 |

Class Hierarchy

73 |
    74 |
  • java.lang.Object 75 | 78 |
  • 79 |
80 |
81 |
82 |
83 | 109 |
110 |
111 | 112 | 113 | -------------------------------------------------------------------------------- /docs/utility/service/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | utility.service Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 25 | 28 |
29 | 61 |
62 |
63 |
64 |

Hierarchy For Package utility.service

65 | Package Hierarchies: 66 | 69 |
70 |
71 |
72 |

Interface Hierarchy

73 | 76 |
77 |
78 |
79 | 105 |
106 |
107 | 108 | 109 | -------------------------------------------------------------------------------- /lib/api-docs/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | backend-parent 7 | com.app 8 | 1.0.0-SNAPSHOT 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | api-docs 14 | 15 | 16 | 17 | 18 | io.springfox 19 | springfox-boot-starter 20 | ${springfox-swagger2.version} 21 | 22 | 23 | 24 | 25 | 26 | jcenter-snapshots 27 | jcenter 28 | https://jcenter.bintray.com/ 29 | 30 | 31 | -------------------------------------------------------------------------------- /lib/api-docs/src/main/java/apidocs/annotations/EnableDocs.java: -------------------------------------------------------------------------------- 1 | package apidocs.annotations; 2 | 3 | import apidocs.config.SwaggerConfig; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.context.annotation.Import; 6 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 7 | 8 | import java.lang.annotation.*; 9 | 10 | @Retention (RetentionPolicy.RUNTIME) 11 | @Target ({ ElementType.TYPE}) 12 | @Documented 13 | @Import ({SwaggerConfig.class}) 14 | public @interface EnableDocs { 15 | 16 | public String title() default "Swagger API Documentation"; 17 | public String desc() default "Allows to interact with Backend"; 18 | public String ver() default "v1"; 19 | public String pathMapping() default "/"; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /lib/api-docs/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nadeem4/spring_boot_multi_module_framework/a07adb095d759730d24af48c69b8125759f3d24d/lib/api-docs/src/main/resources/META-INF/spring.factories -------------------------------------------------------------------------------- /lib/exception/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | backend-parent 7 | com.app 8 | 1.0.0-SNAPSHOT 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | exception 14 | 15 | jar 16 | 17 | -------------------------------------------------------------------------------- /lib/exception/src/main/java/exception/annotation/EnableExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package exception.annotation; 2 | 3 | import exception.handler.GlobalExceptionHandler; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.context.annotation.Import; 6 | 7 | import java.lang.annotation.*; 8 | 9 | @Retention (RetentionPolicy.RUNTIME) 10 | @Target ({ ElementType.TYPE}) 11 | @Documented 12 | @Import (GlobalExceptionHandler.class) 13 | @Configuration 14 | public @interface EnableExceptionHandler { 15 | } 16 | -------------------------------------------------------------------------------- /lib/exception/src/main/java/exception/constant/ValidationExceptionType.java: -------------------------------------------------------------------------------- 1 | package exception.constant; 2 | 3 | 4 | public enum ValidationExceptionType { 5 | MISSING_FIELD_ERROR, 6 | EMPTY_PROPERTY_ERROR, 7 | NEGATIVE_NOT_ALLOWED_ERROR, 8 | INVALID_LENGTH_ERROR, 9 | INVALID_DATA_ERROR, 10 | INVALID_REQUEST_BODY 11 | } 12 | -------------------------------------------------------------------------------- /lib/exception/src/main/java/exception/custom/DuplicateRecordException.java: -------------------------------------------------------------------------------- 1 | package exception.custom; 2 | 3 | import lombok.Getter; 4 | 5 | public class DuplicateRecordException extends RuntimeException { 6 | 7 | @Getter 8 | String type = "DuplicateRecordException"; 9 | 10 | public DuplicateRecordException( String entity, Object id ) { 11 | 12 | super(entity + ": "+ id + " is already present"); 13 | } 14 | 15 | public DuplicateRecordException( String entity ) { 16 | 17 | super(entity + " is already present"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/exception/src/main/java/exception/custom/EntityNotFoundException.java: -------------------------------------------------------------------------------- 1 | package exception.custom; 2 | 3 | import lombok.Getter; 4 | 5 | public class EntityNotFoundException extends RuntimeException { 6 | 7 | @Getter 8 | String type = "EntityNotFoundException"; 9 | 10 | 11 | public EntityNotFoundException( String entity, Object id ) { 12 | super(entity + ": " + id + " is not found."); 13 | } 14 | 15 | public EntityNotFoundException(String s) { 16 | super(s); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/exception/src/main/java/exception/custom/FileHandlingException.java: -------------------------------------------------------------------------------- 1 | package exception.custom; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | public class FileHandlingException extends RuntimeException { 7 | 8 | @Getter 9 | @Setter 10 | private String fileName; 11 | 12 | @Getter 13 | @Setter 14 | private String operation; 15 | 16 | @Getter 17 | private String type = "FileHandlingException"; 18 | 19 | @Getter 20 | @Setter 21 | private String detailError; 22 | 23 | public FileHandlingException(String fileName, String operation, String detailError) { 24 | super( String.format("Error occurred while % file: %", operation, fileName)); 25 | this.fileName = fileName; 26 | this.operation = operation; 27 | this.detailError =detailError; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lib/exception/src/main/java/exception/custom/InvalidStateTransitionException.java: -------------------------------------------------------------------------------- 1 | package exception.custom; 2 | 3 | import lombok.Getter; 4 | 5 | public class InvalidStateTransitionException extends RuntimeException { 6 | 7 | @Getter 8 | String type = "InvalidStateTransitionException"; 9 | 10 | public InvalidStateTransitionException( String currentState, String nextState ) { 11 | 12 | super("Transition from " + currentState + " to " + nextState + " is not allowed"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/exception/src/main/java/exception/custom/MultipleActionFailedException.java: -------------------------------------------------------------------------------- 1 | package exception.custom; 2 | 3 | import exception.dto.MultipleActionErrorDTO; 4 | import lombok.Getter; 5 | 6 | import java.util.List; 7 | 8 | public class MultipleActionFailedException extends RuntimeException { 9 | 10 | @Getter 11 | private String type = "MultipleActionFailedException"; 12 | 13 | @Getter 14 | private List actionErrorDTOS; 15 | 16 | public MultipleActionFailedException( String message, List actionErrorDTOS ) { 17 | super(message ); 18 | this.actionErrorDTOS = actionErrorDTOS; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /lib/exception/src/main/java/exception/custom/NotificationException.java: -------------------------------------------------------------------------------- 1 | package exception.custom; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | public class NotificationException extends RuntimeException{ 7 | 8 | @Getter 9 | @Setter 10 | private String source; 11 | 12 | @Getter 13 | private String type = "NotificationException"; 14 | 15 | public NotificationException( String src, String message) { super(message + " Unable to send notification via "+ src); } 16 | 17 | 18 | } 19 | -------------------------------------------------------------------------------- /lib/exception/src/main/java/exception/custom/OperationFailedException.java: -------------------------------------------------------------------------------- 1 | package exception.custom; 2 | 3 | import lombok.Getter; 4 | 5 | public class OperationFailedException extends RuntimeException { 6 | 7 | @Getter 8 | String type = "OperationFailedException"; 9 | 10 | public OperationFailedException( String operationName, String reason ) { 11 | 12 | super("Unable to perform "+ operationName + ". " + reason); 13 | } 14 | 15 | public OperationFailedException(String message) { 16 | super(message); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/exception/src/main/java/exception/custom/OperationNotAllowedException.java: -------------------------------------------------------------------------------- 1 | package exception.custom; 2 | 3 | import lombok.Getter; 4 | 5 | public class OperationNotAllowedException extends RuntimeException { 6 | 7 | @Getter 8 | String type = "OperationNotAllowedException"; 9 | 10 | public OperationNotAllowedException( String operationName, String reason ) { 11 | super("Operation failed: "+ operationName + ". " + reason); 12 | } 13 | public OperationNotAllowedException( String message ) { 14 | super(message); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/exception/src/main/java/exception/dto/AuthErrorDTO.java: -------------------------------------------------------------------------------- 1 | package exception.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | @AllArgsConstructor 8 | public class AuthErrorDTO extends SubErrorDTO { 9 | private String message; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /lib/exception/src/main/java/exception/dto/MultipleActionErrorDTO.java: -------------------------------------------------------------------------------- 1 | package exception.dto; 2 | 3 | import lombok.*; 4 | 5 | @Data 6 | @Getter 7 | @Setter 8 | @AllArgsConstructor 9 | @EqualsAndHashCode (callSuper = false) 10 | public class MultipleActionErrorDTO extends SubErrorDTO { 11 | private String entity; 12 | 13 | private String entityId; 14 | 15 | private String message; 16 | 17 | private String remedy; 18 | } 19 | -------------------------------------------------------------------------------- /lib/exception/src/main/java/exception/dto/SubErrorDTO.java: -------------------------------------------------------------------------------- 1 | package exception.dto; 2 | 3 | public abstract class SubErrorDTO { 4 | } 5 | -------------------------------------------------------------------------------- /lib/exception/src/main/java/exception/dto/ValidationErrorDTO.java: -------------------------------------------------------------------------------- 1 | package exception.dto; 2 | 3 | import lombok.*; 4 | 5 | @Data 6 | @AllArgsConstructor 7 | @Getter 8 | @Setter 9 | @EqualsAndHashCode (callSuper = false) 10 | public class ValidationErrorDTO extends SubErrorDTO { 11 | private String object; 12 | private String field; 13 | private Object rejectedValue; 14 | private String message; 15 | 16 | ValidationErrorDTO(String object, String message) { 17 | this.object = object; 18 | this.message = message; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /lib/exception/src/main/java/exception/message/ExceptionMessages.java: -------------------------------------------------------------------------------- 1 | package exception.message; 2 | 3 | import exception.constant.ValidationExceptionType; 4 | 5 | import javax.validation.ConstraintValidatorContext; 6 | 7 | public class ExceptionMessages { 8 | 9 | public static void setValidationErrorMessage( ConstraintValidatorContext context, ValidationExceptionType exceptionType, String key ) { 10 | switch ( exceptionType) { 11 | case MISSING_FIELD_ERROR: 12 | context.buildConstraintViolationWithTemplate( 13 | ValidationConstraintMessage.setFieldMissingErrorMessage(key)) 14 | .addConstraintViolation(); 15 | break; 16 | case EMPTY_PROPERTY_ERROR: 17 | context.buildConstraintViolationWithTemplate( 18 | ValidationConstraintMessage.setEmptyPropertyMessage(key)) 19 | .addConstraintViolation(); 20 | break; 21 | 22 | case NEGATIVE_NOT_ALLOWED_ERROR: 23 | context.buildConstraintViolationWithTemplate( 24 | ValidationConstraintMessage.setNegativeNotAllowedErrorMessage(key)) 25 | .addConstraintViolation(); 26 | break; 27 | } 28 | 29 | } 30 | 31 | public static void setValidationErrorMessage( ConstraintValidatorContext context, ValidationExceptionType exceptionType, String key, int allowedLength ) { 32 | switch ( exceptionType) { 33 | case INVALID_LENGTH_ERROR: 34 | context.buildConstraintViolationWithTemplate( 35 | ValidationConstraintMessage.setInvalidLengthErrorMessage(key, allowedLength)) 36 | .addConstraintViolation(); 37 | } 38 | 39 | } 40 | 41 | public static void setValidationErrorMessage( ConstraintValidatorContext context, ValidationExceptionType exceptionType, String key, String additionalMsg ){ 42 | switch ( exceptionType) { 43 | case INVALID_DATA_ERROR: 44 | context.buildConstraintViolationWithTemplate( 45 | ValidationConstraintMessage.setInvalidDataErrorMessage(key, additionalMsg)) 46 | .addConstraintViolation(); 47 | break; 48 | } 49 | 50 | } 51 | 52 | public static String setValidationErrorMessage(String key, ValidationExceptionType exceptionType) { 53 | switch ( exceptionType ) { 54 | case INVALID_REQUEST_BODY: 55 | return ValidationConstraintMessage.setInvalidRequestBody(key); 56 | 57 | default: 58 | return ""; 59 | 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lib/exception/src/main/java/exception/message/ValidationConstraintMessage.java: -------------------------------------------------------------------------------- 1 | package exception.message; 2 | 3 | public class ValidationConstraintMessage { 4 | 5 | public static String setInvalidLengthErrorMessage( String key, int allowedLength ) { 6 | return String.format("Max allowed length of %s is %d.", key, allowedLength); 7 | } 8 | 9 | public static String setFieldMissingErrorMessage(String key) { 10 | return String.format("Key Missing: %s", key); 11 | } 12 | 13 | public static String setInvalidDataErrorMessage(String key, String message) { 14 | return String.format("Invalid Key: %s; %s", key, message); 15 | } 16 | 17 | public static String setNegativeNotAllowedErrorMessage(String key) { 18 | return String.format("%s does not allow negative.", key); 19 | } 20 | 21 | public static String setEmptyPropertyMessage( String key ) { 22 | return String.format("Please provide %s", key); 23 | } 24 | 25 | public static String setInvalidRequestBody( String key ) { 26 | return String.format("%s request body is invalid", key); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lib/exception/src/main/java/exception/util/LowerCaseNameResolver.java: -------------------------------------------------------------------------------- 1 | package exception.util; 2 | 3 | import com.fasterxml.jackson.annotation.JsonTypeInfo; 4 | import com.fasterxml.jackson.databind.jsontype.impl.TypeIdResolverBase; 5 | 6 | public class LowerCaseNameResolver extends TypeIdResolverBase { 7 | 8 | @Override 9 | public String idFromValue(Object value) { 10 | return value.getClass().getSimpleName().toLowerCase(); 11 | } 12 | 13 | @Override 14 | public String idFromValueAndType(Object value, Class suggestedType) { 15 | return idFromValue(value); 16 | } 17 | 18 | @Override 19 | public JsonTypeInfo.Id getMechanism() { 20 | return JsonTypeInfo.Id.CUSTOM; 21 | } 22 | } -------------------------------------------------------------------------------- /lib/exception/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | exception.handler.GlobalExceptionHandler -------------------------------------------------------------------------------- /lib/file-handler/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | backend-parent 7 | com.app 8 | 1.0.0-SNAPSHOT 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | file-handler 14 | 15 | 16 | 17 | com.app 18 | exception 19 | ${project.version} 20 | 21 | 22 | 23 | com.microsoft.azure 24 | azure-storage 25 | 8.6.5 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /lib/file-handler/src/main/java/file_handler/constant/OperationType.java: -------------------------------------------------------------------------------- 1 | package file_handler.constant; 2 | 3 | public enum OperationType { 4 | UPLOAD("Upload"), 5 | FETCH("Fetch"), 6 | DOWNLOAD("Download"), 7 | DELETE("Delete"); 8 | 9 | private String values; 10 | 11 | public String getValues() { 12 | return this.values; 13 | } 14 | 15 | private OperationType( String values) { 16 | this.values = values; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/file-handler/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | file_handler.util.FileUtil -------------------------------------------------------------------------------- /lib/logging/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | backend-parent 7 | com.app 8 | 1.0.0-SNAPSHOT 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | logging 14 | jar 15 | 16 | 17 | 18 | 19 | 20 | com.microsoft.azure 21 | applicationinsights-spring-boot-starter 22 | ${ai-spring-boot-starter.version} 23 | 24 | 25 | com.microsoft.azure 26 | applicationinsights-logging-logback 27 | ${ai-logging-logback.version} 28 | 29 | 30 | 31 | 32 | com.app 33 | utility 34 | ${project.version} 35 | 36 | 37 | 38 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /lib/logging/src/main/java/logging/annotations/Loggable.java: -------------------------------------------------------------------------------- 1 | package logging.annotations; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target ({ElementType.METHOD, ElementType.CONSTRUCTOR}) 9 | @Retention (RetentionPolicy.RUNTIME) 10 | public @interface Loggable { 11 | 12 | public String valueBefore() default ""; 13 | public String valueAfter() default ""; 14 | public String valueAfterReturning() default ""; 15 | public String valueAround() default ""; 16 | } 17 | -------------------------------------------------------------------------------- /lib/logging/src/main/java/logging/aspects/LoggableMapperAspect.java: -------------------------------------------------------------------------------- 1 | package logging.aspects; 2 | 3 | import org.aspectj.lang.JoinPoint; 4 | import org.aspectj.lang.annotation.After; 5 | import org.aspectj.lang.annotation.AfterReturning; 6 | import org.aspectj.lang.annotation.Aspect; 7 | import org.aspectj.lang.annotation.Before; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | @Aspect 11 | @Configuration 12 | public class LoggableMapperAspect { 13 | 14 | @Before ("execution(*.mapper.*)") 15 | public void logBefore( JoinPoint joinPoint ) throws Throwable { 16 | 17 | } 18 | 19 | @After ("execution(*.mapper.*)") 20 | public void logAfter( JoinPoint joinPoint ) throws Throwable { 21 | 22 | } 23 | 24 | 25 | @AfterReturning ("execution(*.mapper.*)") 26 | public void logAfterReturning( JoinPoint joinPoint ) throws Throwable { 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lib/logging/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | logging.aspects.LoggableControllerAspect,\ 3 | logging.aspects.LoggableRepositoryAspect,\ 4 | logging.aspects.LoggableComponentAspect,\ 5 | logging.aspects.LoggableServiceAspect -------------------------------------------------------------------------------- /lib/logging/src/main/resources/aaplication.yml: -------------------------------------------------------------------------------- 1 | azure: 2 | application-insights: 3 | enabled: false 4 | quick-pulse.enabled: true 5 | heart-beat: 6 | enabled: true 7 | heart-beat-interval: 900 8 | jmx: 9 | jmx-counters[0]: java.lang:type=ClassLoading/LoadedClassCount/Current Loaded Class Count 10 | jmx-counters[1]: java.lang:type=Memory/HeapMemoryUsage.init/Initial Heap Memory Usage/Composite 11 | jmx-counters[2]: java.lang:name=PS MarkSweep,type=GarbageCollector/CollectionTime/GC MarkSweep Time 12 | 13 | default-modules: 14 | ProcessPerformanceCountersModule.enabled: true 15 | JvmPerformanceCountersModule.enabled: true 16 | WebRequestTrackingTelemetryModule.enabled: true 17 | WebSessionTrackingTelemetryModule.enabled: true 18 | WebUserTrackingTelemetryModule.enabled: true 19 | WebPerformanceCounterModule.enabled: true 20 | WebOperationIdTelemetryInitializer.enabled: true 21 | WebOperationNameTelemetryInitializer.enabled: true 22 | WebSessionTelemetryInitializer.enabled: true 23 | WebUserTelemetryInitializer.enabled: true 24 | WebUserAgentTelemetryInitializer.enabled: true -------------------------------------------------------------------------------- /lib/logging/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %-4relative [%thread] %-5level %logger{35} - %msg %n 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /lib/notification/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | backend-parent 7 | com.app 8 | 1.0.0-SNAPSHOT 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | notification 14 | 15 | 16 | 17 | io.jsonwebtoken 18 | jjwt-api 19 | ${jsonwebtoken.version} 20 | 21 | 22 | io.jsonwebtoken 23 | jjwt-impl 24 | ${jsonwebtoken.version} 25 | runtime 26 | 27 | 28 | io.jsonwebtoken 29 | jjwt-jackson 30 | ${jsonwebtoken.version} 31 | runtime 32 | 33 | 34 | 35 | com.konghq 36 | unirest-java 37 | 3.3.00 38 | 39 | 40 | com.app 41 | exception 42 | ${project.version} 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /lib/notification/src/main/java/notification/NotificationUtil.java: -------------------------------------------------------------------------------- 1 | 2 | package notification; 3 | 4 | 5 | import exception.custom.NotificationException; 6 | import notification.constant.NotificationMethod; 7 | import notification.mapper.NotificationMapper; 8 | import notification.dto.GetNotificationDTO; 9 | import io.jsonwebtoken.JwtBuilder; 10 | import io.jsonwebtoken.Jwts; 11 | import io.jsonwebtoken.SignatureAlgorithm; 12 | import kong.unirest.Unirest; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.beans.factory.annotation.Value; 15 | import org.springframework.boot.configurationprocessor.json.JSONException; 16 | import org.springframework.boot.configurationprocessor.json.JSONObject; 17 | import org.springframework.stereotype.Component; 18 | import notification.SignalR.SignalRMessage; 19 | import javax.crypto.spec.SecretKeySpec; 20 | import java.nio.charset.StandardCharsets; 21 | import java.security.Key; 22 | import java.util.Date; 23 | import java.util.List; 24 | 25 | 26 | @Component 27 | public class NotificationUtil { 28 | 29 | @Value("${app.notification.signal-r.hub-name}") 30 | private String HUB_NAME; 31 | 32 | @Value("${app.url}") 33 | private String url; 34 | 35 | @Value("${app.notification.signal-r.name}") 36 | private String signalRName; 37 | 38 | @Value("${app.notification.signal-r.key}") 39 | private String signalRServiceKey; 40 | 41 | @Autowired 42 | private NotificationMapper notificationMapper; 43 | 44 | public void broadcastMessage(List getNotificationObjs) { 45 | 46 | String signalRServiceBaseEndpoint = "https://" + signalRName + ".service.signalr.net"; 47 | for (Object getNotificationObj : getNotificationObjs) { 48 | GetNotificationDTO getNotificationDTO = notificationMapper.convertToDTO(getNotificationObj); 49 | JSONObject bodyJsonObject = new JSONObject(); 50 | try { 51 | bodyJsonObject.put("message", getNotificationDTO.getMessage()); 52 | bodyJsonObject.put("id", getNotificationDTO.getId()); 53 | bodyJsonObject.put("status", getNotificationDTO.getStatus()); 54 | bodyJsonObject.put("timestamp", getNotificationDTO.getTimestamp()); 55 | bodyJsonObject.put("entity", getNotificationDTO.getEntityKey()); 56 | 57 | } catch (JSONException e) { 58 | throw new NotificationException("Error occurred while broadcasting notification", NotificationMethod.SIGNALR.getValue()); 59 | } 60 | String hubUrl = signalRServiceBaseEndpoint + "/api/v1/hubs/" + HUB_NAME + "/users/" + getNotificationDTO.getUserId(); 61 | String accessKey = generateJwt(hubUrl, getNotificationDTO.getUserId()); 62 | 63 | Unirest.post(hubUrl) 64 | .header("Content-Type", "application/json") 65 | .header("Authorization", "Bearer " + accessKey) 66 | .body(new SignalRMessage("newMessage", new Object[]{bodyJsonObject})) 67 | .asEmpty(); 68 | } 69 | 70 | } 71 | 72 | public String generateJwt(String audience, Integer userId) { 73 | long nowMillis = System.currentTimeMillis(); 74 | Date now = new Date(nowMillis); 75 | 76 | long expMillis = nowMillis + (12 * 60 * 60 * 1000); 77 | Date exp = new Date(expMillis); 78 | 79 | byte[] apiKeySecretBytes = signalRServiceKey.getBytes(StandardCharsets.UTF_8); 80 | SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; 81 | Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName()); 82 | 83 | JwtBuilder builder = Jwts.builder() 84 | .setAudience(audience) 85 | .setIssuedAt(now) 86 | .setExpiration(exp) 87 | .signWith(signingKey); 88 | 89 | if (userId != null) { 90 | builder.claim("nameid", userId); 91 | } 92 | 93 | return builder.compact(); 94 | } 95 | } 96 | 97 | -------------------------------------------------------------------------------- /lib/notification/src/main/java/notification/SignalR/SignalRMessage.java: -------------------------------------------------------------------------------- 1 | package notification.SignalR; 2 | 3 | public class SignalRMessage { 4 | 5 | public String target; 6 | public Object[] arguments; 7 | 8 | public SignalRMessage(String target, Object[] arguments) { 9 | this.target = target; 10 | this.arguments = arguments; 11 | } 12 | } -------------------------------------------------------------------------------- /lib/notification/src/main/java/notification/constant/NotificationMethod.java: -------------------------------------------------------------------------------- 1 | package notification.constant; 2 | 3 | public enum NotificationMethod { 4 | 5 | SIGNALR("Signal-R"), 6 | EMAIL("Email"), 7 | PUSH("Push"), 8 | TEXT("Text"); 9 | 10 | private String values; 11 | 12 | public String getValue() { 13 | return this.values; 14 | } 15 | 16 | private NotificationMethod( String values) { 17 | this.values = values; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/notification/src/main/java/notification/dto/GetNotificationDTO.java: -------------------------------------------------------------------------------- 1 | package notification.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import lombok.Setter; 6 | import lombok.ToString; 7 | import lombok.experimental.Accessors; 8 | 9 | @Getter 10 | @Setter 11 | @NoArgsConstructor 12 | @Accessors(chain = true) 13 | @ToString 14 | public class GetNotificationDTO { 15 | 16 | private Integer id; 17 | 18 | private String message; 19 | 20 | private Integer status; 21 | 22 | private String timestamp; 23 | 24 | private String entity; 25 | 26 | private String entityKey; 27 | 28 | private Integer userId; 29 | } 30 | -------------------------------------------------------------------------------- /lib/notification/src/main/java/notification/mapper/NotificationMapper.java: -------------------------------------------------------------------------------- 1 | package notification.mapper; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import notification.dto.GetNotificationDTO; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.util.Map; 8 | 9 | @Component 10 | public class NotificationMapper { 11 | 12 | public GetNotificationDTO convertToDTO(Object notificationObj) { 13 | 14 | ObjectMapper mapper = new ObjectMapper(); 15 | Map notificationMap = mapper.convertValue(notificationObj, Map.class); 16 | GetNotificationDTO getNotificationDTO = new GetNotificationDTO(); 17 | getNotificationDTO.setEntity((String) notificationMap.get("entity")) 18 | .setEntityKey((String) notificationMap.get("entityKey")) 19 | .setId((Integer) notificationMap.get("id")) 20 | .setMessage((String) notificationMap.get("message")) 21 | .setStatus((Integer) notificationMap.get("status")) 22 | .setTimestamp(String.valueOf(notificationMap.get("timestamp"))) 23 | .setUserId((Integer) notificationMap.get("userId")); 24 | return getNotificationDTO; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/security/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | backend-parent 7 | com.app 8 | 1.0.0-SNAPSHOT 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | security 14 | jar 15 | 16 | 17 | 0.10.7 18 | 19 | 20 | 21 | 22 | 23 | 24 | com.microsoft.azure 25 | azure-active-directory-spring-boot-starter 26 | 27 | 28 | com.microsoft.azure 29 | azure-keyvault-secrets-spring-boot-starter 30 | 31 | 32 | com.app 33 | utility 34 | ${project.version} 35 | 36 | 37 | com.app 38 | exception 39 | ${project.version} 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /lib/security/src/main/java/security/aad/CustomAccessDeniedHandler.java: -------------------------------------------------------------------------------- 1 | package security.aad; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import exception.dto.ErrorDTO; 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.security.access.AccessDeniedException; 7 | import org.springframework.security.web.access.AccessDeniedHandler; 8 | import org.springframework.stereotype.Component; 9 | 10 | import javax.servlet.ServletException; 11 | import javax.servlet.http.HttpServletRequest; 12 | import javax.servlet.http.HttpServletResponse; 13 | import java.io.IOException; 14 | import java.io.OutputStream; 15 | 16 | @Component 17 | public class CustomAccessDeniedHandler implements AccessDeniedHandler { 18 | 19 | @Override 20 | public void handle(HttpServletRequest request, HttpServletResponse response, 21 | AccessDeniedException accessDeniedException) throws IOException, ServletException { 22 | ErrorDTO error = new ErrorDTO(HttpStatus.FORBIDDEN, "User is not allowed to access this resource."); 23 | OutputStream out = response.getOutputStream(); 24 | ObjectMapper mapper = new ObjectMapper(); 25 | mapper.writeValue(out, error); 26 | out.flush(); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /lib/security/src/main/java/security/aad/CustomAuthEntryPoint.java: -------------------------------------------------------------------------------- 1 | package security.aad; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import exception.dto.ErrorDTO; 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.http.MediaType; 7 | import org.springframework.security.core.AuthenticationException; 8 | import org.springframework.security.web.AuthenticationEntryPoint; 9 | import org.springframework.stereotype.Component; 10 | 11 | import javax.servlet.ServletException; 12 | import javax.servlet.http.HttpServletRequest; 13 | import javax.servlet.http.HttpServletResponse; 14 | import java.io.IOException; 15 | import java.io.OutputStream; 16 | 17 | @Component 18 | public class CustomAuthEntryPoint implements AuthenticationEntryPoint { 19 | 20 | @Override 21 | public void commence(HttpServletRequest request, HttpServletResponse response, 22 | AuthenticationException authException) throws IOException, ServletException { 23 | ErrorDTO error = new ErrorDTO(HttpStatus.UNAUTHORIZED, "User is not allowed to access this resource"); 24 | response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 25 | response.setContentType(MediaType.APPLICATION_JSON_VALUE); 26 | OutputStream out = response.getOutputStream(); 27 | ObjectMapper mapper = new ObjectMapper(); 28 | mapper.writeValue(out, error); 29 | out.flush(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /lib/security/src/main/java/security/aad/ServletExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package security.aad; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import exception.dto.ErrorDTO; 6 | import org.slf4j.MDC; 7 | import org.springframework.beans.factory.annotation.Value; 8 | import org.springframework.http.HttpStatus; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.stereotype.Component; 11 | import org.springframework.web.filter.GenericFilterBean; 12 | import utility.constant.AppConstant; 13 | 14 | import javax.servlet.FilterChain; 15 | import javax.servlet.ServletException; 16 | import javax.servlet.ServletRequest; 17 | import javax.servlet.ServletResponse; 18 | import javax.servlet.http.HttpServletRequest; 19 | import javax.servlet.http.HttpServletResponse; 20 | import java.io.IOException; 21 | import java.util.ArrayList; 22 | import java.util.Arrays; 23 | import java.util.List; 24 | import java.util.UUID; 25 | 26 | @Component 27 | public class ServletExceptionHandler extends GenericFilterBean { 28 | 29 | private static final String TOKEN_HEADER = "Authorization"; 30 | private static final String TOKEN_TYPE = "Bearer "; 31 | 32 | @Value ("${spring.application.name}") 33 | private String appName; 34 | 35 | @Value("${app.version}") 36 | private String version; 37 | 38 | @Value("${spring.profiles.active:dev}") 39 | private String env; 40 | 41 | private List excludedUrls = new ArrayList<>(); 42 | 43 | @Override 44 | public void doFilter( ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain ) throws IOException, ServletException { 45 | 46 | HttpServletRequest request = (HttpServletRequest) servletRequest; 47 | HttpServletResponse response = (HttpServletResponse) servletResponse; 48 | 49 | String authHeader = request.getHeader(TOKEN_HEADER); 50 | UUID uuid = UUID.randomUUID(); 51 | String requestId = uuid.toString(); 52 | MDC.put(AppConstant.REQUEST_ID, requestId); 53 | MDC.put("microservice", appName); 54 | MDC.put("version", version); 55 | MDC.put("env", env); 56 | MDC.put("request_uri", request.getRequestURI()); 57 | 58 | if( !isExcludedUrl(request)) { 59 | if ( authHeader == null || authHeader.isEmpty() ) { 60 | setError(response, "Token is missing"); 61 | return; 62 | } 63 | if( ! authHeader.startsWith(TOKEN_TYPE)) { 64 | setError(response, "Bearer token is required"); 65 | return; 66 | } 67 | } 68 | 69 | try { 70 | filterChain.doFilter(request, response); 71 | } catch( ServletException e) { 72 | setError(response, "Token is invalid"); 73 | return; 74 | } 75 | } 76 | 77 | private String convertObjectToJson(Object object) throws JsonProcessingException { 78 | if (object == null) { 79 | return null; 80 | } 81 | ObjectMapper mapper = new ObjectMapper(); 82 | return mapper.writeValueAsString(object); 83 | } 84 | 85 | private boolean isExcludedUrl(HttpServletRequest request ) { 86 | return Arrays.stream( 87 | "/swagger-ui,/v2/api-docs,/swagger-resources,/api/v1/negotiate,/api/v1/api/messages,/health" 88 | .split(",") 89 | ).anyMatch(s -> request.getRequestURI().contains(s)); 90 | } 91 | 92 | private void setError( HttpServletResponse response , String errMsg) throws IOException { 93 | ErrorDTO error = new ErrorDTO(HttpStatus.UNAUTHORIZED, errMsg); 94 | response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 95 | response.setContentType(MediaType.APPLICATION_JSON_VALUE); 96 | response.getWriter().write(convertObjectToJson(error)); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /lib/security/src/main/java/security/aad/WebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package security.aad; 2 | 3 | import com.microsoft.azure.spring.autoconfigure.aad.AADAuthenticationFilter; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.core.annotation.Order; 8 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 9 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 10 | import org.springframework.security.config.annotation.web.builders.WebSecurity; 11 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 12 | import org.springframework.security.config.http.SessionCreationPolicy; 13 | import org.springframework.security.web.AuthenticationEntryPoint; 14 | import org.springframework.security.web.access.AccessDeniedHandler; 15 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 16 | import org.springframework.security.web.authentication.logout.LogoutFilter; 17 | 18 | import javax.servlet.Filter; 19 | 20 | @EnableGlobalMethodSecurity (securedEnabled = true, 21 | prePostEnabled = true) 22 | @Configuration 23 | @Order(1) 24 | public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 25 | 26 | @Autowired 27 | private AADAuthenticationFilter aadAuthFilter; 28 | 29 | private static final String[] AUTH_WHITELIST = { 30 | "/swagger-resources/**", 31 | "/swagger-ui.html", 32 | "/v2/api-docs", 33 | "/webjars/**", 34 | "/swagger-ui/**", 35 | "/api/v1/negotiate", 36 | "/api/v1/api/messages" 37 | }; 38 | 39 | @Override 40 | protected void configure( HttpSecurity http) throws Exception { 41 | http.authorizeRequests().antMatchers(AUTH_WHITELIST).permitAll(); 42 | http.authorizeRequests().antMatchers("/api/**").authenticated(); 43 | http.csrf().disable(); 44 | http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); 45 | http.authorizeRequests().anyRequest().permitAll(); 46 | 47 | http.addFilterBefore(servletExceptionHandler(), LogoutFilter.class); 48 | http.addFilterBefore(aadAuthFilter, UsernamePasswordAuthenticationFilter.class); 49 | 50 | http.exceptionHandling().accessDeniedHandler(accessDeniedHandler()); 51 | http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint()); 52 | } 53 | 54 | 55 | 56 | @Bean 57 | public AuthenticationEntryPoint authenticationEntryPoint() { 58 | return new CustomAuthEntryPoint(); 59 | } 60 | 61 | @Bean 62 | public AccessDeniedHandler accessDeniedHandler() { 63 | return new CustomAccessDeniedHandler(); 64 | } 65 | 66 | @Bean 67 | public ServletExceptionHandler servletExceptionHandler() { return new ServletExceptionHandler();} 68 | 69 | } -------------------------------------------------------------------------------- /lib/security/src/main/java/security/annotations/EnableSecurity.java: -------------------------------------------------------------------------------- 1 | package security.annotations; 2 | 3 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.context.annotation.Import; 7 | import security.aad.WebSecurityConfig; 8 | import security.config.MDCLogConfig; 9 | 10 | import java.lang.annotation.*; 11 | 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target({ ElementType.TYPE}) 14 | @Documented 15 | @Import({WebSecurityConfig.class, MDCLogConfig.class}) 16 | public @interface EnableSecurity { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /lib/security/src/main/java/security/config/MDCLogConfig.java: -------------------------------------------------------------------------------- 1 | package security.config; 2 | 3 | 4 | import org.slf4j.MDC; 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 7 | import org.springframework.context.annotation.ComponentScan; 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.web.filter.OncePerRequestFilter; 10 | 11 | import javax.servlet.FilterChain; 12 | import javax.servlet.ServletException; 13 | import javax.servlet.http.HttpServletRequest; 14 | import javax.servlet.http.HttpServletResponse; 15 | import java.util.UUID; 16 | import com.microsoft.azure.spring.autoconfigure.aad.UserPrincipal; 17 | import utility.constant.AppConstant; 18 | 19 | @Component 20 | public class MDCLogConfig extends OncePerRequestFilter { 21 | 22 | 23 | 24 | @Override 25 | public void doFilterInternal( final HttpServletRequest request, final HttpServletResponse response, final FilterChain filterChain) 26 | throws java.io.IOException, ServletException { 27 | 28 | UserPrincipal userPrincipal = ((UserPrincipal) request.getSession().getAttribute("CURRENT_USER_PRINCIPAL")); 29 | 30 | 31 | MDC.put(AppConstant.USER_PRINCIPLE, userPrincipal == null ? "" : userPrincipal.getUniqueName()); 32 | 33 | 34 | 35 | filterChain.doFilter(request, response); 36 | } 37 | } -------------------------------------------------------------------------------- /lib/security/src/main/java/security/constant/AuthorizationPermission.java: -------------------------------------------------------------------------------- 1 | package security.constant; 2 | 3 | public class AuthorizationPermission { 4 | } 5 | -------------------------------------------------------------------------------- /lib/security/src/main/java/security/hashing/MD5.java: -------------------------------------------------------------------------------- 1 | package security.hashing; 2 | 3 | import java.math.BigInteger; 4 | import java.security.MessageDigest; 5 | import java.security.NoSuchAlgorithmException; 6 | import java.security.SecureRandom; 7 | import java.util.Date; 8 | 9 | public class MD5 { 10 | 11 | public static String generateHash(String value) throws NoSuchAlgorithmException { 12 | 13 | Date currentTimeInMillis = new Date(); 14 | SecureRandom secureRandom = new SecureRandom(); 15 | String secureString = value 16 | .concat(String.valueOf(currentTimeInMillis.getTime())) 17 | .concat(String.valueOf(secureRandom.nextLong())); 18 | MessageDigest md5 = MessageDigest.getInstance("MD5"); 19 | 20 | byte[] messageDigest = md5.digest(secureString.getBytes()); 21 | BigInteger no = new BigInteger(1, messageDigest); 22 | String hashedText = no.toString(16); 23 | while (hashedText.length() < 32) { 24 | hashedText = "0" + hashedText; 25 | } 26 | return hashedText; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lib/security/src/main/resources/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | security.config.MDCLogConfig,\ 3 | security.aad.WebSecurityConfig -------------------------------------------------------------------------------- /lib/utility/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | backend-parent 7 | com.app 8 | 1.0.0-SNAPSHOT 9 | ../../pom.xml 10 | 11 | 4.0.0 12 | 13 | utility 14 | 15 | 16 | 17 | com.app 18 | exception 19 | ${project.version} 20 | 21 | 22 | -------------------------------------------------------------------------------- /lib/utility/src/main/java/utility/annotations/AvoidDuplicate.java: -------------------------------------------------------------------------------- 1 | package utility.annotations; 2 | 3 | 4 | import javax.validation.constraints.NotNull; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | 8 | @Retention (RetentionPolicy.RUNTIME) 9 | public @interface AvoidDuplicate { 10 | 11 | public @NotNull String tableName(); 12 | public @NotNull String columnName(); 13 | public @NotNull String value(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /lib/utility/src/main/java/utility/annotations/ControllerV1.java: -------------------------------------------------------------------------------- 1 | package utility.annotations; 2 | 3 | 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | import java.lang.annotation.ElementType; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.RetentionPolicy; 10 | import java.lang.annotation.Target; 11 | 12 | @Target({ ElementType.TYPE, ElementType.METHOD}) 13 | @Retention (RetentionPolicy.RUNTIME) 14 | @RestController 15 | // @PreAuthorize ("isAuthenticated()") 16 | @RequestMapping ("/api/v1") 17 | public @interface ControllerV1 { 18 | } 19 | -------------------------------------------------------------------------------- /lib/utility/src/main/java/utility/aspect/AvoidDuplicateAspect.java: -------------------------------------------------------------------------------- 1 | package utility.aspect; 2 | 3 | import exception.custom.DuplicateRecordException; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.aspectj.lang.JoinPoint; 6 | import org.aspectj.lang.annotation.Aspect; 7 | import org.aspectj.lang.annotation.Before; 8 | import org.aspectj.lang.annotation.Pointcut; 9 | import org.aspectj.lang.reflect.FieldSignature; 10 | import org.aspectj.lang.reflect.MethodSignature; 11 | import org.slf4j.MDC; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.jdbc.core.JdbcTemplate; 15 | import org.springframework.jdbc.core.simple.SimpleJdbcCall; 16 | import org.springframework.stereotype.Component; 17 | import utility.annotations.AvoidDuplicate; 18 | 19 | import java.lang.reflect.Field; 20 | import java.lang.reflect.Method; 21 | 22 | @Aspect 23 | @Slf4j 24 | @Configuration 25 | @Component 26 | public class AvoidDuplicateAspect { 27 | 28 | @Autowired 29 | private JdbcTemplate jdbcTemplate; 30 | 31 | private SimpleJdbcCall simpleJdbcCall; 32 | 33 | @Before("avoidDuplicate()") 34 | public void runBefore( JoinPoint joinPoint ) { 35 | FieldSignature methodSignature = (FieldSignature) joinPoint.getSignature(); 36 | Field field = methodSignature.getField(); 37 | AvoidDuplicate avoidDuplicate = field.getDeclaredAnnotation(AvoidDuplicate.class); 38 | 39 | String sqlQuery = String.format("SELECT COUNT(*) FROM %s WHERE %s = ?", avoidDuplicate.tableName(), avoidDuplicate.columnName()); 40 | Integer cnt = jdbcTemplate.queryForObject( 41 | sqlQuery, 42 | new Object[] {avoidDuplicate.value()}, 43 | Integer.class 44 | ); 45 | if( cnt > 0) { 46 | MDC.put("table_name", avoidDuplicate.tableName()); 47 | MDC.put("column_name", avoidDuplicate.columnName()); 48 | MDC.put("value", avoidDuplicate.value()); 49 | log.error("{}: {} already exist in {}", avoidDuplicate.columnName(), field, avoidDuplicate.tableName()); 50 | throw new DuplicateRecordException(avoidDuplicate.columnName(), avoidDuplicate.value()); 51 | } 52 | } 53 | 54 | @Pointcut ( 55 | "@annotation(utility.annotations.AvoidDuplicate)" 56 | ) 57 | public void avoidDuplicate() {} 58 | } 59 | -------------------------------------------------------------------------------- /lib/utility/src/main/java/utility/aspect/NotNullAspect.java: -------------------------------------------------------------------------------- 1 | package utility.aspect; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.aspectj.lang.JoinPoint; 5 | import org.aspectj.lang.annotation.Aspect; 6 | import org.aspectj.lang.annotation.Before; 7 | import org.aspectj.lang.reflect.CodeSignature; 8 | import org.aspectj.lang.reflect.MethodSignature; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.stereotype.Component; 11 | 12 | import javax.validation.constraints.NotNull; 13 | import java.lang.annotation.Annotation; 14 | import java.util.ArrayList; 15 | import java.util.Arrays; 16 | import java.util.Collections; 17 | import java.util.List; 18 | 19 | @Aspect 20 | @Slf4j 21 | @Configuration 22 | public class NotNullAspect { 23 | @Before ("execution(* *(.., @javax.validation.constraints.NotNull (*), ..))") 24 | public void nullCheck( JoinPoint joinPoint ) { 25 | MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); 26 | for (MethodArgument argument : MethodArgument.of(joinPoint)) 27 | if (argument.hasAnnotation(NotNull.class) && argument.getValue() == null) { 28 | String msg = String.format("%s: argument \"%s\" (at position %d) cannot be null", 29 | methodSignature.getMethod(), 30 | argument.getName(), 31 | argument.getIndex() 32 | ); 33 | log.error(msg); 34 | throw new NullPointerException(msg); 35 | } 36 | 37 | } 38 | 39 | private static class MethodArgument { 40 | 41 | private final int index; 42 | private final String name; 43 | private final List annotations; 44 | private final Object value; 45 | 46 | private MethodArgument( int index, String name, List annotations, Object value ) { 47 | this.index = index; 48 | this.name = name; 49 | this.annotations = Collections.unmodifiableList(annotations); 50 | this.value = value; 51 | } 52 | 53 | public static List of( JoinPoint joinPoint ) { 54 | List arguments = new ArrayList<>(); 55 | CodeSignature codeSignature = (CodeSignature) joinPoint.getSignature(); 56 | String[] names = codeSignature.getParameterNames(); 57 | MethodSignature methodSignature = (MethodSignature) joinPoint.getStaticPart().getSignature(); 58 | Annotation[][] annotations = methodSignature.getMethod().getParameterAnnotations(); 59 | Object[] values = joinPoint.getArgs(); 60 | for (int i = 0; i < values.length; i++) 61 | arguments.add(new MethodArgument(i, names[ i ], Arrays.asList(annotations[ i ]), values[ i ])); 62 | return Collections.unmodifiableList(arguments); 63 | } 64 | 65 | public int getIndex() { return index; } 66 | 67 | public String getName() { return name; } 68 | 69 | public List getAnnotations() { return annotations; } 70 | 71 | public boolean hasAnnotation( Class type ) { 72 | for (Annotation annotation : annotations) 73 | if (annotation.annotationType().equals(type)) 74 | return true; 75 | return false; 76 | } 77 | 78 | public Object getValue() { return value; } 79 | 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /lib/utility/src/main/java/utility/constant/ActionType.java: -------------------------------------------------------------------------------- 1 | package utility.constant; 2 | 3 | public enum ActionType { 4 | 5 | CREATED ("Created"), 6 | UPDATED ("Updated"), 7 | DELETED ("Deleted"), 8 | DEACTIVATED("Deactivated"), 9 | ACTIVATED("Activated"), 10 | INVITED("Invited"), 11 | ASSIGNED("Assigned"); 12 | 13 | private String values; 14 | 15 | public String getValues() { 16 | return this.values; 17 | } 18 | 19 | private ActionType( String values) { 20 | this.values = values; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/utility/src/main/java/utility/constant/AppConstant.java: -------------------------------------------------------------------------------- 1 | package utility.constant; 2 | 3 | public class AppConstant { 4 | 5 | public static final String REQUEST_ID = "request_id"; 6 | public static final String USER_PRINCIPLE = "user_principle"; 7 | private AppConstant() {} 8 | } 9 | -------------------------------------------------------------------------------- /lib/utility/src/main/java/utility/constant/EntityType.java: -------------------------------------------------------------------------------- 1 | package utility.constant; 2 | 3 | public enum EntityType { 4 | 5 | TEST_ENTITY("Test Entity"), 6 | USER("User"); 7 | 8 | private String values; 9 | 10 | public String getValue() { 11 | return this.values; 12 | } 13 | 14 | private EntityType( String values) { 15 | this.values = values; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/utility/src/main/java/utility/constant/Messages.java: -------------------------------------------------------------------------------- 1 | package utility.constant; 2 | 3 | public class Messages { 4 | 5 | public static String setMessage( String message) { return message; } 6 | 7 | public static String setMessage( EntityType entityType, ActionType actionType, String id ) { 8 | return entityType.getValue() + "# " + id + " has been " + actionType.getValues() + " successfully"; 9 | } 10 | 11 | public static String setMessage( EntityType entityType, String actionType, String id ) { 12 | return entityType.getValue() + "# " + id + " has been " + actionType + " successfully"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/utility/src/main/java/utility/custom_data_type/ValidList.java: -------------------------------------------------------------------------------- 1 | package utility.custom_data_type; 2 | 3 | import lombok.Data; 4 | import lombok.experimental.Delegate; 5 | 6 | import javax.validation.Valid; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | @Data 11 | public class ValidList implements List { 12 | 13 | @Valid 14 | @Delegate 15 | private List list = new ArrayList<>(); 16 | } -------------------------------------------------------------------------------- /lib/utility/src/main/java/utility/dto/DetailDTO.java: -------------------------------------------------------------------------------- 1 | package utility.dto; 2 | 3 | import exception.dto.MultipleActionErrorDTO; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import lombok.Setter; 7 | import lombok.experimental.Accessors; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | @Getter 13 | @Setter 14 | @NoArgsConstructor 15 | @Accessors(chain = true) 16 | public class DetailDTO { 17 | 18 | private String message; 19 | private List partialSuccessDTOList; 20 | 21 | public void addPartialSuccessDTOs( List actionErrorDTOS) { actionErrorDTOS.forEach(this::addPartialSuccessDTO);} 22 | 23 | private void addPartialSuccessDTO( MultipleActionErrorDTO actionErrorDTO) { 24 | this.addPartialSuccessDTO( 25 | actionErrorDTO.getEntity(), 26 | actionErrorDTO.getEntityId(), 27 | actionErrorDTO.getMessage(), 28 | actionErrorDTO.getRemedy() 29 | ); 30 | } 31 | 32 | 33 | private void addPartialSuccessDTO( String entity, String entityId, String message, String remedy) { 34 | if( partialSuccessDTOList == null) { 35 | partialSuccessDTOList = new ArrayList<>(); 36 | } 37 | partialSuccessDTOList.add(new PartialSuccessDTO(entity, entityId, message, remedy)); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/utility/src/main/java/utility/dto/PartialSuccessDTO.java: -------------------------------------------------------------------------------- 1 | package utility.dto; 2 | 3 | import exception.dto.MultipleActionErrorDTO; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | 9 | @Getter 10 | @Setter 11 | public class PartialSuccessDTO extends MultipleActionErrorDTO { 12 | 13 | public PartialSuccessDTO( String entity, String entityId, String message, String remedy ) { 14 | super(entity, entityId, message, remedy); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/utility/src/main/java/utility/dto/ResponseDTO.java: -------------------------------------------------------------------------------- 1 | package utility.dto; 2 | 3 | import com.fasterxml.jackson.annotation.JsonFormat; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import lombok.experimental.Accessors; 7 | import org.jboss.logging.MDC; 8 | import org.springframework.http.HttpStatus; 9 | import utility.constant.AppConstant; 10 | 11 | import java.util.Date; 12 | import java.util.List; 13 | 14 | 15 | 16 | @Accessors (chain = true) 17 | @Getter 18 | public class ResponseDTO { 19 | 20 | private HttpStatus status; 21 | 22 | @Setter 23 | private String message; 24 | 25 | @JsonFormat (shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss Z") 26 | private Date timestamp; 27 | 28 | private String requestId; 29 | 30 | @Setter 31 | private List detailMessage; 32 | 33 | public ResponseDTO() { 34 | this.requestId = (String) MDC.get(AppConstant.REQUEST_ID); 35 | this.status = HttpStatus.CREATED; 36 | this.timestamp = new Date(); 37 | } 38 | 39 | public static ResponseDTO setResponseDTO( String message ) { return new ResponseDTO().setMessage(message); } 40 | 41 | public static ResponseDTO setResponseDTO( String message, List details ) { 42 | return new ResponseDTO().setMessage(message).setDetailMessage(details); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/utility/src/main/java/utility/mapper/AppObjectMapper.java: -------------------------------------------------------------------------------- 1 | package utility.mapper; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import exception.custom.OperationFailedException; 6 | 7 | public class AppObjectMapper { 8 | public static String convertObjectToJson(Object object) { 9 | if (object == null) { 10 | return null; 11 | } 12 | ObjectMapper mapper = new ObjectMapper(); 13 | try { 14 | return mapper.writeValueAsString(object); 15 | } catch (JsonProcessingException e) { 16 | throw new OperationFailedException("UnableToConvertException","Unable to convert to JSON"); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/utility/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | utility.aspect.NotNullAspect 3 | utility.aspect.AvoidDuplicateAspect -------------------------------------------------------------------------------- /scripts/create_new_microservice.sh: -------------------------------------------------------------------------------- 1 | :: need to implement --------------------------------------------------------------------------------