{"id":25828155,"url":"https://github.com/rapter1990/pdfcompare","last_synced_at":"2025-02-28T17:23:59.363Z","repository":{"id":279857567,"uuid":"938541326","full_name":"Rapter1990/pdfcompare","owner":"Rapter1990","description":"Pdf Comparison (Java21, Spring Boot, JUnit, Jacoco, Prometheus,Grafana, AlertManager, Docker, Kubernetes, Github Action (CI/CD))","archived":false,"fork":false,"pushed_at":"2025-02-27T20:46:07.000Z","size":10811,"stargazers_count":3,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-28T05:23:22.060Z","etag":null,"topics":["alertmanager","cicd","docker","github-actions","grafana","jacoco","java","java21","junit","kubernetes","pdf","prometh","spring-boot"],"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/Rapter1990.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":"2025-02-25T05:45:57.000Z","updated_at":"2025-02-27T23:57:37.000Z","dependencies_parsed_at":"2025-02-28T05:36:44.136Z","dependency_job_id":null,"html_url":"https://github.com/Rapter1990/pdfcompare","commit_stats":null,"previous_names":["rapter1990/pdfcompare"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rapter1990%2Fpdfcompare","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rapter1990%2Fpdfcompare/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rapter1990%2Fpdfcompare/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rapter1990%2Fpdfcompare/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Rapter1990","download_url":"https://codeload.github.com/Rapter1990/pdfcompare/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241189644,"owners_count":19924852,"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":["alertmanager","cicd","docker","github-actions","grafana","jacoco","java","java21","junit","kubernetes","pdf","prometh","spring-boot"],"created_at":"2025-02-28T17:23:58.671Z","updated_at":"2025-02-28T17:23:59.346Z","avatar_url":"https://github.com/Rapter1990.png","language":"Java","readme":"# Case Study - PDF Comparison\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"screenshots/main.png\" alt=\"Main Information\" width=\"800\" height=\"500\"\u003e\n\u003c/p\u003e\n\n### 📖 Information\n\n\u003cul style=\"list-style-type:disc\"\u003e\n   \u003cli\u003e\n      This project provides a \u003cb\u003eSpring Boot API\u003c/b\u003e for \u003cb\u003ePDF Comparison\u003c/b\u003e, allowing users to compare two PDF documents and download a resulting comparison report in \u003cb\u003ePDF format\u003c/b\u003e.\n   \u003c/li\u003e\n   \u003cli\u003e\n      \u003cb\u003ePDF Comparison API:\u003c/b\u003e\n      \u003cul\u003e\n         \u003cli\u003e\n            \u003cb\u003eEndpoint:\u003c/b\u003e \u003ccode\u003e/api/v1/pdf/compare\u003c/code\u003e\n         \u003c/li\u003e\n         \u003cli\u003e\n            \u003cb\u003eHTTP Method:\u003c/b\u003e POST\n         \u003c/li\u003e\n         \u003cli\u003e\n            \u003cb\u003eConsumes:\u003c/b\u003e \u003ccode\u003emultipart/form-data\u003c/code\u003e\n         \u003c/li\u003e\n         \u003cli\u003e\n            \u003cb\u003eParameters:\u003c/b\u003e\n            \u003cul\u003e\n               \u003cli\u003e\n                  \u003cb\u003efile1:\u003c/b\u003e First PDF file (\u003cb\u003erequired\u003c/b\u003e)\n               \u003c/li\u003e\n               \u003cli\u003e\n                  \u003cb\u003efile2:\u003c/b\u003e Second PDF file (\u003cb\u003erequired\u003c/b\u003e)\n               \u003c/li\u003e\n               \u003cli\u003e\n                  \u003cb\u003eisMultiple:\u003c/b\u003e Boolean flag (\u003cb\u003eoptional\u003c/b\u003e, default is \u003ccode\u003efalse\u003c/code\u003e) indicating whether to perform multiple comparisons.\n               \u003c/li\u003e\n            \u003c/ul\u003e\n         \u003c/li\u003e\n         \u003cli\u003e\n            \u003cb\u003eResponse:\u003c/b\u003e Returns a PDF file (\u003ccode\u003ecomparison.pdf\u003c/code\u003e) containing the comparison results.\n         \u003c/li\u003e\n         \u003cli\u003e\n            \u003cb\u003eExample Request:\u003c/b\u003e\n            \u003cul\u003e \n                \u003cli\u003e\u003ccode\u003ePOST /api/v1/pdf/compare\u003c/code\u003e\n            with two PDF files and an optional \u003ccode\u003eisMultiple\u003c/code\u003e flag.\n         \u003c/li\u003e\n      \u003c/ul\u003e\n   \u003c/li\u003e\n   \u003cli\u003e\n      \u003cb\u003eImplementation Details:\u003c/b\u003e\n      \u003cul\u003e\n         \u003cli\u003e\n            Utilizes a dedicated \u003cb\u003ePDFComparisonService\u003c/b\u003e to process and compare the contents of the uploaded PDF files.\n         \u003c/li\u003e\n         \u003cli\u003e\n            The service generates a comparison report as a PDF document, highlighting differences and similarities.\n         \u003c/li\u003e\n         \u003cli\u003e\n            Errors during the comparison process are managed via exception handling, ensuring reliable API responses.\n         \u003c/li\u003e\n      \u003c/ul\u003e\n   \u003c/li\u003e\n   \u003cli\u003e\n      \u003cb\u003eDownloadable Output:\u003c/b\u003e\n      \u003cul\u003e\n         \u003cli\u003e\n            The response sets \u003cb\u003eContent-Type\u003c/b\u003e to \u003ccode\u003eapplication/pdf\u003c/code\u003e and uses \u003cb\u003eContent-Disposition\u003c/b\u003e to prompt the download of the file named \u003ccode\u003ecomparison.pdf\u003c/code\u003e.\n         \u003c/li\u003e\n      \u003c/ul\u003e\n   \u003c/li\u003e\n\u003c/ul\u003e\n\n\n### Explore Rest APIs\n\nEndpoints Summary\n\u003ctable style=\"width:100%;\"\u003e\n    \u003ctr\u003e\n        \u003cth\u003eMethod\u003c/th\u003e\n        \u003cth\u003eUrl\u003c/th\u003e\n        \u003cth\u003eDescription\u003c/th\u003e\n        \u003cth\u003eRequest Body\u003c/th\u003e\n        \u003cth\u003ePath Variable\u003c/th\u003e\n        \u003cth\u003eResponse\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003ePOST\u003c/td\u003e\n        \u003ctd\u003e/api/v1/pdf/compare\u003c/td\u003e\n        \u003ctd\u003eCompare two PDF files and return a comparison report\u003c/td\u003e\n        \u003ctd\u003e\n            \u003cul\u003e\n                \u003cli\u003e\u003cb\u003efile1:\u003c/b\u003e First PDF file (required)\u003c/li\u003e\n                \u003cli\u003e\u003cb\u003efile2:\u003c/b\u003e Second PDF file (required)\u003c/li\u003e\n                \u003cli\u003e\u003cb\u003eisMultiple:\u003c/b\u003e Boolean flag (optional, default is false)\u003c/li\u003e\n            \u003c/ul\u003e\n        \u003c/td\u003e\n        \u003ctd\u003eNone\u003c/td\u003e\n        \u003ctd\u003ePDF file (comparison.pdf)\u003c/td\u003e\n    \u003c/tr\u003e\n\u003c/table\u003e\n\n\n\n\n### Technologies\n\n---\n- Java 21\n- Spring Boot 3.0\n- Restful API\n- Open Api (Swagger)\n- Maven\n- Junit5\n- Mockito\n- Integration Tests\n- Docker\n- Docker Compose\n- CI/CD (Github Actions)\n- Postman\n- Prometheus\n- Grafana\n- Kubernetes\n- JaCoCo (Test Report)\n- Alert Manager\n\n### Postman\n\n```\nImport postman collection under postman_collection folder\n```\n\n\n### Prerequisites\n\n#### Define Variable in .env file\n\n```\nGF_SMTP_ENABLED=true\nGF_SMTP_HOST=smtp.gmail.com:587\nGF_SMTP_USER={your_gmail_email}\nGF_SMTP_PASSWORD={gmail_authentication_password}\nGF_SMTP_SKIP_VERIFY=true\nGF_SMTP_FROM_ADDRESS={your_gmail_email}\n\n\nALERT_RESOLVE_TIMEOUT=5m\nSMTP_SMARTHOST=smtp.gmail.com:587\nSMTP_FROM={your_gmail_email}\nSMTP_AUTH_USERNAME={your_gmail_email}\nSMTP_AUTH_PASSWORD={gmail_authentication_password}\nSMTP_REQUIRE_TLS=true\nALERT_EMAIL_TO={your_gmail_email}\n```\n\n### Open Api (Swagger)\n\n```\nhttp://localhost:3333/swagger-ui/index.html\n```\n\n---\n\n### JaCoCo (Test Report)\n\nAfter the command named `mvn clean install` completes, the JaCoCo report will be available at:\n```\ntarget/site/jacoco/index.html\n```\nNavigate to the `target/site/jacoco/` directory.\n\nOpen the `index.html` file in your browser to view the detailed coverage report.\n\n---\n\n### Maven, Docker and Kubernetes Running Process\n\n\n### Maven Run\nTo build and run the application with `Maven`, please follow the directions shown below;\n\n```sh\n$ cd pdfcompare\n$ mvn clean install\n$ mvn spring-boot:run\n```\n\n---\n\n### Docker Run\nThe application can be built and run by the `Docker` engine. The `Dockerfile` has multistage build, so you do not need to build and run separately.\n\nPlease follow directions shown below in order to build and run the application with Docker Compose file;\n\n```sh\n$ cd pdfcompare\n$ docker-compose up -d\n```\n\nIf you change anything in the project and run it on Docker, you can also use this command shown below\n\n```sh\n$ cd pdfcompare\n$ docker-compose up --build\n```\n\nTo monitor the application, you can use the following tools:\n\n- **Prometheus**:  \n  Open in your browser at [http://localhost:9090](http://localhost:9090)  \n  Prometheus collects and stores application metrics.\n\n  Alert is alrealdy defined in Alert tab\n\n\n- **Grafana**:  \n  Open in your browser at [http://localhost:3000](http://localhost:3000)  \n  Grafana provides a dashboard for visualizing the metrics.  \n  **Default credentials**:\n    - Username: `admin`\n    - Password: `admin`\n\n\n- **AlertManager**:  \n  Open in your browser at [http://localhost:9093](http://localhost:9093)  \n\nDefine prometheus data source url, use this link shown below\n\n```\nhttp://prometheus:9090\n```\n\nDefine alertManager data source url, use this link shown below\n\n```\nhttp://alertmanager:9093\n```\n\n---\n\n\n### Kubernetes Run\nTo build and run the application with `Maven`, please follow the directions shown below;\n\n- Start Minikube\n\n```sh\n$ minikube start\n```\n\n- Open Minikube Dashboard\n\n```sh\n$ minikube dashboard\n```\n\n- To deploy the application on Kubernetes, apply the Kubernetes configuration file underneath k8s folder\n\n```sh\n$ kubectl apply -f k8s\n```\n\n- To open Prometheus, click tunnel url link provided by the command shown below to reach out Prometheus\n\n```sh\nminikube service prometheus-service\n```\n\n- To open Grafana, click tunnel url link provided by the command shown below to reach out Prometheus\n\n```sh\nminikube service grafana-service\n```\n\n- To open AlertManager, click tunnel url link provided by the command shown below to reach out Prometheus\n\n```sh\nminikube service alertmanager-service\n```\n\n- Define prometheus data source url, use this link shown below\n\n```\nhttp://prometheus-service.default.svc.cluster.local:9090\n```\n\n- Define alertmanager data source url, use this link shown below\n\n```\nhttp://alertmanager-service.default.svc.cluster.local:9093\n```\n\n### Define Alert through Grafana\n\n- Go to `localhost:9093` for Docker and Go there through `minikube service alertmanager-service` for Kubernetes\n- Define `Your Gmail address` for `Contract Point` and determine if test mail is send to its email\n- After define jvm micrometer dashboard in Grafana with its id 4701, click `Heap Used Panel` edit and `More -\u003e New Alert Rules` \n- Define `Threshold` as input assigning to `A` with `IS ABOVE` as `1.8`  \n- Create a new folder names for `3. Add folder and labels` and `4. Set evaluation behaviour`\n- Define `Contract Points` for your defined email in `5. Configure notification`\n- After reaching the threshold value, it triggers to send an alert notification to your defined mail\n\n### Alert Manager\n\n- Pre-configured Alert Rules: \n  - The alert is pre-defined in the `rule` file within `Prometheus`, streamlining your monitoring setup\n- Threshold-based Trigger: \n  - Once any metric exceeds its designated threshold, the `alert` is automatically activated\n- Instant Email Notifications: \n  - Upon triggering, `Alert Manager` sends an immediate `email notification` to your defined `email`, keeping you informed in real time\n\n\n---\n### Docker Image Location\n\n```\nhttps://hub.docker.com/repository/docker/noyandocker/pdfcompare/general\n```\n\n### Screenshots\n\n\u003cdetails\u003e\n\u003csummary\u003eClick here to show the screenshots of project\u003c/summary\u003e\n    \u003cp\u003e Figure 1 \u003c/p\u003e\n    \u003cimg src =\"screenshots/postman_result.PNG\"\u003e\n    \u003cp\u003e Figure 2 \u003c/p\u003e\n    \u003cimg src =\"screenshots/openapi_swagger.PNG\"\u003e\n    \u003cp\u003e Figure 3 \u003c/p\u003e\n    \u003cimg src =\"screenshots/jacoco_test_coverage_report.PNG\"\u003e\n    \u003cp\u003e Figure 4 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_prometheus.PNG\"\u003e\n    \u003cp\u003e Figure 5 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_1.PNG\"\u003e\n    \u003cp\u003e Figure 6 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_2.PNG\"\u003e\n    \u003cp\u003e Figure 7 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_3.PNG\"\u003e\n    \u003cp\u003e Figure 8 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_4.PNG\"\u003e\n    \u003cp\u003e Figure 9 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_5.PNG\"\u003e\n    \u003cp\u003e Figure 10 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_6.PNG\"\u003e\n    \u003cp\u003e Figure 11 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_alert_manager_1.PNG\"\u003e\n    \u003cp\u003e Figure 12 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_alert_1.PNG\"\u003e\n    \u003cp\u003e Figure 13 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_alert_2.PNG\"\u003e\n    \u003cp\u003e Figure 14 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_alert_3.PNG\"\u003e\n    \u003cp\u003e Figure 15 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_alert_4.PNG\"\u003e\n    \u003cp\u003e Figure 16 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_alert_5.PNG\"\u003e\n    \u003cp\u003e Figure 17 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_alert_6.PNG\"\u003e\n    \u003cp\u003e Figure 18 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_alert_7.PNG\"\u003e\n    \u003cp\u003e Figure 19 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_alert_8.PNG\"\u003e\n    \u003cp\u003e Figure 20 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_alert_9.PNG\"\u003e\n    \u003cp\u003e Figure 21 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_alert_10.PNG\"\u003e\n    \u003cp\u003e Figure 22 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_alert_11.PNG\"\u003e\n    \u003cp\u003e Figure 23 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_alert_12.PNG\"\u003e\n    \u003cp\u003e Figure 24 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_alertmanager_1.PNG\"\u003e\n    \u003cp\u003e Figure 25 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_alertmanager_2.PNG\"\u003e\n    \u003cp\u003e Figure 26 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_alertmanager_3.PNG\"\u003e\n    \u003cp\u003e Figure 27 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_alertmanager_4.PNG\"\u003e\n    \u003cp\u003e Figure 28 \u003c/p\u003e\n    \u003cimg src =\"screenshots/docker_grafana_alertmanager_5.PNG\"\u003e\n    \u003cp\u003e Figure 29 \u003c/p\u003e\n    \u003cimg src =\"screenshots/kubernetes_prometheus_1.PNG\"\u003e\n    \u003cp\u003e Figure 30 \u003c/p\u003e\n    \u003cimg src =\"screenshots/kubernetes_grafana_1.PNG\"\u003e\n    \u003cp\u003e Figure 31 \u003c/p\u003e\n    \u003cimg src =\"screenshots/kubernetes_grafana_2.PNG\"\u003e\n    \u003cp\u003e Figure 32 \u003c/p\u003e\n    \u003cimg src =\"screenshots/kubernetes_grafana_3.PNG\"\u003e\n    \u003cp\u003e Figure 33 \u003c/p\u003e\n    \u003cimg src =\"screenshots/kubernetes_grafana_4.PNG\"\u003e\n    \u003cp\u003e Figure 34 \u003c/p\u003e\n    \u003cimg src =\"screenshots/kubernetes_grafana_5.PNG\"\u003e\n    \u003cp\u003e Figure 35 \u003c/p\u003e\n    \u003cimg src =\"screenshots/kubernetes_grafana_6.PNG\"\u003e\n    \u003cp\u003e Figure 36 \u003c/p\u003e\n    \u003cimg src =\"screenshots/kubernetes_grafana_7.PNG\"\u003e\n    \u003cp\u003e Figure 37 \u003c/p\u003e\n    \u003cimg src =\"screenshots/kubernetes_grafana_8.PNG\"\u003e\n    \u003cp\u003e Figure 38 \u003c/p\u003e\n    \u003cimg src =\"screenshots/kubernetes_grafana_9.PNG\"\u003e\n    \u003cp\u003e Figure 39 \u003c/p\u003e\n    \u003cimg src =\"screenshots/kubernetes_grafana_alert_1.PNG\"\u003e\n    \u003cp\u003e Figure 40 \u003c/p\u003e\n    \u003cimg src =\"screenshots/kubernetes_grafana_alert_manager_1.PNG\"\u003e\n\u003c/details\u003e\n\n\n### Contributors\n\n- [Sercan Noyan Germiyanoğlu](https://github.com/Rapter1990)","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frapter1990%2Fpdfcompare","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frapter1990%2Fpdfcompare","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frapter1990%2Fpdfcompare/lists"}