{"id":16618052,"url":"https://github.com/gtiwari333/spring-boot-blog-app","last_synced_at":"2025-04-07T15:06:19.386Z","repository":{"id":42501229,"uuid":"298712221","full_name":"gtiwari333/spring-boot-blog-app","owner":"gtiwari333","description":"Application to demonstrate several features of Spring Boot","archived":false,"fork":false,"pushed_at":"2025-03-09T02:22:15.000Z","size":512,"stargazers_count":73,"open_issues_count":4,"forks_count":26,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-31T14:11:15.468Z","etag":null,"topics":["groovy","hibernate","java","maven","spock-framework","spring","spring-boot","spring-mvc","spring-security","thymeleaf"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gtiwari333.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-26T01:15:41.000Z","updated_at":"2025-03-11T18:04:48.000Z","dependencies_parsed_at":"2023-12-21T19:41:40.111Z","dependency_job_id":"5835cffc-8a6e-4fd4-a4ea-2215d4de23a3","html_url":"https://github.com/gtiwari333/spring-boot-blog-app","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gtiwari333%2Fspring-boot-blog-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gtiwari333%2Fspring-boot-blog-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gtiwari333%2Fspring-boot-blog-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gtiwari333%2Fspring-boot-blog-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gtiwari333","download_url":"https://codeload.github.com/gtiwari333/spring-boot-blog-app/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247675596,"owners_count":20977376,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["groovy","hibernate","java","maven","spock-framework","spring","spring-boot","spring-mvc","spring-security","thymeleaf"],"created_at":"2024-10-12T02:18:57.114Z","updated_at":"2025-04-07T15:06:19.358Z","avatar_url":"https://github.com/gtiwari333.png","language":"Java","funding_links":[],"categories":["企业软件开发"],"sub_categories":["文件同步"],"readme":"# A BlogApp with Spring Boot\n\n#### More complex version is here: https://github.com/gtiwari333/spring-boot-web-application-seed\n\n### Intro\n\nThis is a simple micro blogging application where you can post a note/blog with attachments and other can view it.\n\nThe default username/passwords are listed on : gt.app.Application.initData, which are:\n\n- system/pass\n- user1/pass\n- user2/pass\n\n### Requirements\n\n- JDK 21+\n- Lombok configured on IDE\n    - http://ganeshtiwaridotcomdotnp.blogspot.com/2016/03/configuring-lombok-on-intellij.html\n    - For eclipse, download the lombok jar, run it, and point to eclipse installation\n- Maven (optional)\n- Docker\n\n### How to Run\n\n- Clone/Download and Import project into your IDE, compile and run Application.java\n- Update run configuration to run maven goal `wro4j:run` Before Launch. It should be after 'Build'\n  OR\n\n- ./mvnw compile spring-boot:run //if you don't have maven installed in your PC\n\nOR\n\n- ./mvnw compile spring-boot:run //if you have maven installed in your PC\n\nAnd open   `http://localhost:8080` on your browser\n\nOptionally, you can start the docker containers yourself using:\n\n`docker-compose --profile mailHog up` to start just the mailHog container(required by default 'dev' profile)\n\nOr\n\n`docker-compose --profile all up` to start both mailHog and mysql (if you want to use 'docker' or 'prod' profile)\n\n`sudo chmod 666 /var/run/docker.sock` to fix following error\n``` \norg.springframework.boot.docker.compose.core.ProcessExitException: 'docker version --format {{.Client.Version}}' failed with exit code 1.\n\nStdout:\n20.10.24\n\n\nStderr:\nGot permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: \n    Get \"http://%2Fvar%2Frun%2Fdocker.sock/v1.24/version\": dial unix /var/run/docker.sock: connect: permission denied\n```\n\n## Run Tests\n\n##### Running full tests\n\n`./mvnw clean verify`\n\n##### Running unit tests only (it uses maven surefire plugin)\n\n`./mvnw  compiler:testCompile resources:testResources  surefire:test`\n\n##### Running integration tests only (it uses maven-failsafe-plugin)\n\n`./mvnw  compiler:testCompile resources:testResources  failsafe:integration-test`\n\n## Code Quality\n\n##### The `error-prone` runs at compile time.\n\n##### The `modernizer` `checkstyle` and `spotbugs` plugin are run as part of maven `test-compile` lifecycle phase. use `mvn spotbugs:gui' to\n\n##### SonarQube scan\n\nRun sonarqube server using docker\n`docker run -e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true -p 9000:9000 sonarqube:latest`\n\nPerform scan:\n`./mvnw sonar:sonar`\n./mvnw sonar:sonar -Dsonar.login=admin -Dsonar.password=admin\n\nView Reports in SonarQube web ui:\n\n- visit http://localhost:9000\n- default login and password are `admin`, you will be asked to change password after logging in with default\n  username/password\n- (optional) change sonarqube admin password without logging\n  in: `curl -u admin:admin -X POST \"http://localhost:9000/api/users/change_password?login=admin\u0026previousPassword=admin\u0026password=NEW_PASSWORD\"`\n- if you change the password, make sure the update `-Dsonar.password=admin` when you run sonarqube next time\n\n### Dependency vulnerability scan\n\nOwasp dependency check plugin is configured. Run `./mvnw dependency-check:check` to run scan and\nopen `dependency-check-report.html` from target to see the report.\n\n### Dependency/plugin version checker\n\n    ./mvnw versions:display-dependency-updates\n    ./mvnw versions:display-plugin-updates\n\n### Included Features/Samples\n- GraalVM native image generation\n- Modular application\n- Data JPA with User/Authority/Note/ReceivedFile entities, example of EntityGraph\n- Default test data created while running the app\n- Public and internal pages\n- MVC with thymeleaf templating\n- File upload/download\n- Live update of thymeleaf templates for local development\n- HTML fragments\n- webjar - bootstrap4 + jquery\n- Custom Error page\n- Request logger filter\n- Swagger API Docs with UI  ( http://localhost:8080/swagger-ui.html)\n- @RestControllerAdvice, @ControllerAdvice demo\n- CRUD Note + File upload\n- Spring / Maven profiles for dev/prod ...\n- Dockerfile to run images\n- Docker maven plugin to publish images (follow docker-steps.md)\n- Deploy to Amazon EC2 ( follow docker-steps.md )\n- Code Generation: lombok, mapstruct\n- H2 db for local, Console enabled for local ( http://localhost:8080/h2-console/, db url: jdbc:h2:mem:testdb, username:sa)\n- MySQL or any other SQL db can be configured for prod/docker etc profiles\n- User/User_Authority entity and repository/services\n    - login, logout, home pages based on user role\n- Security with basic config\n- Domain object Access security check on update/delete using custom PermissionEvaluator\n- public home page -- view all notes by all\n- private pages based on user roles\n- Test cases - unit/integration with JUnit 5, Mockito and Spring Test\n- Tests with Spock Framework (Groovy 3, Spock 2)\n- e2e with Selenide, fixtures. default data generated using Spring\n- Architecture test using ArchUnit\n- Email\n- Account management/Signup UI\n\nFuture: do more stuff\n\n- background jobs with Quartz\n- Liquibase/Flyway change log\n- Integrate Markdown editor for writing notes\n\n### Dependency/plugin version checker\n\n    `./mvnw versions:display-dependency-updates`\n    `./mvnw versions:display-plugin-updates`\n\n## Create docker image using buildpack\n\n    ./mvnw spring-boot:build-image\n\n    docker run --rm -p 8080:8080 docker.io/library/note-app:3.2.1\n\n\n## Generate native executable:\n- Required: GraalVM 22.3+ (for Spring Boot 3) \n- Install using sdkman \n- https://docs.spring.io/spring-boot/docs/current/reference/html/native-image.html#native-image.developing-your-first-application.native-build-tools.prerequisites\n    `sdk install java  22.3.r17-nik`\n    `sdk use java  22.3.r17-nik`\n\n- Create native executable `./mvnw native:compile -Pnative,dev`\n- Run it   `./target/note-app`\n\nOR\n\n- Generate docker image with native executable `./mvnw spring-boot:build-image -Pnative,dev`\n- Run it `docker run --rm -p 8080:8080 docker.io/library/note-app:3.2.1`\n\n\n## Native Test:\n- Run with `./mvnw test -PnativeTest`\n- Spring Boot 3.0.0: native-test is not working due to spock ( and possibly other dependencies too) \n\n\n\n# Results after enabling virtual thread\n\nab -k -c 10 -n 2000 http://localhost:8080/\n\n\n\nBefore \n```\nConnection Times (ms)\n              min  mean[+/-sd] median   max\nConnect:        0    0   0.1      0       1\nProcessing:     3    4   0.9      4       9\nWaiting:        3    4   0.8      4       8\nTotal:          3    4   0.9      4       9\n\nPercentage of the requests served within a certain time (ms)\n  50%      4\n  66%      4\n  75%      5\n  80%      5\n  90%      5\n  95%      6\n  98%      7\n  99%      8\n 100%      9 (longest request)\n\n```\n\n\nAfter\n``` \nConnection Times (ms)\n              min  mean[+/-sd] median   max\nConnect:        0    0   0.1      0       1\nProcessing:     3    4   0.7      4       9\nWaiting:        3    4   0.7      4       8\nTotal:          3    5   0.7      4       9\nWARNING: The median and mean for the total time are not within a normal deviation\n        These results are probably not that reliable.\n\nPercentage of the requests served within a certain time (ms)\n  50%      4\n  66%      5\n  75%      5\n  80%      5\n  90%      5\n  95%      6\n  98%      6\n  99%      7\n 100%      9 (longest request)\n\n```\n\n\nAfter introducing a delay to simulate slow blocking API and thousand concurrent requests. Its similar for less concurrent request. Virtual thread outperforms when we have too many concurrent requests.\n\n\nab  -c 1000 -n 15000 http://localhost:8080/\n\n```java\npublic class IndexController {\n\n    @GetMapping({\"/\", \"\"})\n    public String index(Model model, Pageable pageable) throws InterruptedException {\n        Thread.sleep(1500);\n        ...\n    }\n```\n\nbefore\n\n``` \nConnection Times (ms)\n              min  mean[+/-sd] median   max\nConnect:        0   19 132.4      0    1030\nProcessing:  1529 7341 918.6   7547    7631\nWaiting:     1528 7340 918.7   7547    7630\nTotal:       1555 7359 905.6   7548    7817\n\nPercentage of the requests served within a certain time (ms)\n  50%   7548\n  66%   7552\n  75%   7556\n  80%   7558\n  90%   7570\n  95%   7585\n  98%   7611\n  99%   7628\n 100%   7817 (longest request)\n\n```\n\nafter\n\nAMAZING  !!!\n\n\n``` \n\nConnection Times (ms)\n              min  mean[+/-sd] median   max\nConnect:        0    1   4.7      0      23\nProcessing:  1503 1526  60.8   1507    1919\nWaiting:     1503 1526  60.8   1506    1918\nTotal:       1503 1528  64.4   1507    1940\n\nPercentage of the requests served within a certain time (ms)\n  50%   1507\n  66%   1510\n  75%   1514\n  80%   1519\n  90%   1559\n  95%   1664\n  98%   1804\n  99%   1867\n 100%   1940 (longest request)\n\n\n```\n \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgtiwari333%2Fspring-boot-blog-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgtiwari333%2Fspring-boot-blog-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgtiwari333%2Fspring-boot-blog-app/lists"}