{"id":15565020,"url":"https://github.com/conorheffron/ironoc","last_synced_at":"2026-03-01T00:04:45.706Z","repository":{"id":230081248,"uuid":"738456065","full_name":"conorheffron/ironoc","owner":"conorheffron","description":"Personal / Portfolio Website","archived":false,"fork":false,"pushed_at":"2024-12-03T19:02:47.000Z","size":2017,"stargazers_count":1,"open_issues_count":19,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-12-07T04:45:52.539Z","etag":null,"topics":["aws","cache","git-api-sample","git-client","jdk21","maven","personal","portfolio","reactjs","restful-api","runnable","spring-boot","spring-boot-3","spring-scheduler","swagger-ui"],"latest_commit_sha":null,"homepage":"https://conorheffron.ironoc.net","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/conorheffron.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":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-03T09:15:32.000Z","updated_at":"2024-12-03T17:40:21.000Z","dependencies_parsed_at":"2024-04-10T22:14:34.258Z","dependency_job_id":"0fd19d1e-43cc-4688-844d-9c48653bc715","html_url":"https://github.com/conorheffron/ironoc","commit_stats":null,"previous_names":["conorheffron/ironoc","cph39/ironoc"],"tags_count":67,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/conorheffron%2Fironoc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/conorheffron%2Fironoc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/conorheffron%2Fironoc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/conorheffron%2Fironoc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/conorheffron","download_url":"https://codeload.github.com/conorheffron/ironoc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229710213,"owners_count":18111546,"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":["aws","cache","git-api-sample","git-client","jdk21","maven","personal","portfolio","reactjs","restful-api","runnable","spring-boot","spring-boot-3","spring-scheduler","swagger-ui"],"created_at":"2024-10-02T16:48:46.081Z","updated_at":"2025-12-28T05:15:30.266Z","avatar_url":"https://github.com/conorheffron.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ironoc\n\n[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)\n\n[![Maven Package](https://github.com/conorheffron/ironoc/actions/workflows/maven-publish.yml/badge.svg)](https://github.com/conorheffron/ironoc/actions/workflows/maven-publish.yml)\n\n[![Deploy to Amazon ECS](https://github.com/conorheffron/ironoc/actions/workflows/aws.yml/badge.svg)](https://github.com/conorheffron/ironoc/actions/workflows/aws.yml)\n\n[![Java CI with Maven](https://github.com/conorheffron/ironoc/actions/workflows/maven.yml/badge.svg)](https://github.com/conorheffron/ironoc/actions/workflows/maven.yml)\n\n[![Node.js Package](https://github.com/conorheffron/ironoc/actions/workflows/npm-publish-packages.yml/badge.svg)](https://github.com/conorheffron/ironoc/actions/workflows/npm-publish-packages.yml)\n\n[![Node.js CI](https://github.com/conorheffron/ironoc/actions/workflows/node.js.yml/badge.svg)](https://github.com/conorheffron/ironoc/actions/workflows/node.js.yml)\n\n![Proof HTML](https://github.com/conorheffron/ironoc/actions/workflows/proof-html.yml/badge.svg)\n\n![Auto Assign](https://github.com/conorheffron/ironoc/actions/workflows/auto-assign.yml/badge.svg)\n\n### Sonar\n\n[![SonarQube](https://github.com/conorheffron/ironoc/actions/workflows/sonar.yml/badge.svg)](https://github.com/conorheffron/ironoc/actions/workflows/sonar.yml)\n\n[![Quality gate](https://sonarcloud.io/api/project_badges/quality_gate?project=conorheffron_ironoc)](https://sonarcloud.io/summary/new_code?id=conorheffron_ironoc)\n\n[Sonar Overall Summary](https://sonarcloud.io/summary/overall?id=conorheffron_ironoc\u0026branch=main)\n\n### Docker Image Repositories\n- [ironoc Docker Hub Repository](https://hub.docker.com/repository/docker/conorheffron/ironoc/general)\n- [ironoc GitHub Docker Container Registry](https://github.com/conorheffron/ironoc/pkgs/container/ironoc)\n\n## Hosted at:\n- [ironoc.net](https://ironoc.net)\n\n## About\nPersonal website / portfolio  [https://www.ironoc.net/](https://www.ironoc.net/)\n\n## Tech Stack\n - Java 25 (LTS), Spring Boot 4, ReactJs 19, Maven 4, HTML5+CSS, Docker / Bash, AWS, minikube, \u0026 kubectl.\n\n##### Note: `iRonoc` is an active user of the `GitHub API` \u0026 `conorheffron` is a proud participant in the GitHub Developer Program.\n- The `iRonoc` PM tool is designed to streamline project management by automating project navigation \u0026 issue tracking. \n- By leveraging the GitHub API, the aim is to enhance the developer experience and contribute to the vibrant GitHub ecosystem.\n- As part of the GitHub Developer Program, it is important to commit to adhering to best practices \u0026 continuously improving the \nintegration to provide value to users.\n\n\u003ca href=\"https://docs.github.com/en/get-started/exploring-integrations/github-developer-program\"\u003e\n    \u003cdiv style=\"align:center\"\u003e\n        \u003cimg src=\"./screen-grabs/github-mark.png\" alt=\"GitHub Developer Program\"/\u003e\n    \u003c/div\u003e\n\u003c/a\u003e\n\n## See ironoc-frontend README [here](./frontend/README.md)\n\n## Run without cloning project:\n```\ndocker run -d --restart=always -p 8080:8080 conorheffron/ironoc\n```\n\n## AWS CLI to pull required svc / user account credentials.\n### Configure account, verify details \u0026 then generate ID/Keys/Tokens.\n```shell\naws configure\n\naws iam get-user\n\naws sts get-session-token\n```\n\n## Add localhost proxy to frontend config (do not commit - only for local runs).\n![ui-config-screenshot](screen-grabs/local-ui-proxy.png)\n\n## Run after project checkout (JDK 25 \u0026 Maven 4 required)\n### Build frontend \u0026 server side, along with Java Code Coverage report.\n```shell\n./mvnw clean package -U\n```\n\n#### View Java Code Coverage reports in Browser or Preview tab in IDE.\n##### Path to reports is `target/site/jacoco/index.html`\n\n![ui-config-screenshot](screen-grabs/jacoco.png)\n\n##### View in browser at `http://localhost:63342/ironoc/target/site/jacoco/index.html?_ijt=s0hqlj2p4s6554gldritju13qr\u0026_ij_reload=RELOAD_ON_SAVE`\n###### Note: Change port as needed/identifier as this is URL generated during build process \u0026 opened via IDE window.\n![ui-config-screenshot](screen-grabs/jacoco-browser.png)\n\n### Build \u0026 Run frontend on react development server, then run react test suite.\n```shell\ncd frontend\n\nnpm install [--force or --legacy-peer-deps]\n\nnpm run build\n\nrpm run start\n\nnpm run test\n\nnpm run test:coverage\n```\n##### See the output below to verify the frontend test suite results.\n![react-tests](screen-grabs/react-tests.png)\n\n##### See the output below to verify the test coverage for the frontend from the command line.\n![npm-test-coverage](screen-grabs/npm-test-coverage.png)\n\n#### View Frontend Code Coverage reports in Browser or Preview tab in IDE.\n##### Path to reports is `frontend/coverage/lcov-report/index.html`\n![npm-test-coverage-report-1](screen-grabs/npm-test-coverage-report-1.png)\n\n![npm-test-coverage-report-2](screen-grabs/npm-test-coverage-report-2.png)\n\n![npm-test-coverage-report-3](screen-grabs/npm-test-coverage-report-3.png)\n\n### Run app\n```shell\n./mvnw -DAWS_ACCESS_KEY_ID=\"\u003cval1\u003e\" \\\n    -DAWS_REGION=\u003cval2\u003e \\\n    -DAWS_SECRET_ACCESS_KEY=\"\u003cval3\u003e\" \\\n    -DAWS_SESSION_TOKEN=\"\u003cval4\u003e\" \\\n    spring-boot:run\n```\n\n![image](screen-grabs/IDEA-Intellj-run.png)\n\n\n### Build / Run (spin-up) Docker container:\n```\ndocker image build -t ironoc .\ndocker compose up -d\ndocker logs ironoc-portfolio-1 -f\n```\n\n![image](screen-grabs/cli-docker.png)\n\n\n### Tear-down:\n```\ndocker compose down\n```\n\n# Screenshot\n![Home](screen-grabs/home-page.png)\n\n# Local k8s cluster with Minikube:\n\nMiniKube Install Notes for mac users\n```\nbrew install kubectl\nbrew install virtualbox\nbrew install / upgrade minikube\n```\n\n```shell\nOracle VirtualBox Manager v7.1.4\n\n% kubectl version     \nClient Version: v1.30.2\nKustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3\nServer Version: v1.31.0\n\n% minikube version\nminikube version: v1.34.0\ncommit: 210b148df93a80eb872ecbeb7e35281b3c582c61\n\n% docker version\nClient:\nVersion:           27.3.1\nAPI version:       1.47\nGo version:        go1.22.7\nGit commit:        ce12230\nBuilt:             Fri Sep 20 11:38:18 2024\nOS/Arch:           darwin/amd64\nContext:           desktop-linux\n```\n\n- Open terminal\n```shell\n%  minikube start --driver=docker                 \n😄  minikube v1.35.0 on Darwin 15.3.1\n🆕  Kubernetes 1.32.0 is now available. If you would like to upgrade, specify: --kubernetes-version=v1.32.0\n✨  Using the docker driver based on existing profile\n👍  Starting \"minikube\" primary control-plane node in \"minikube\" cluster\n🚜  Pulling base image v0.0.46 ...\n🏃  Updating the running docker \"minikube\" container ...\n❗  Image was not built for the current minikube version. To resolve this you can delete and recreate your minikube cluster using the latest images. Expected minikube version: v1.34.0 -\u003e Actual minikube version: v1.35.0\n🐳  Preparing Kubernetes v1.31.0 on Docker 27.2.0 ...\n🔗  Configuring bridge CNI (Container Networking Interface) ...\n🔎  Verifying Kubernetes components...\n    ▪ Using image docker.io/kubernetesui/metrics-scraper:v1.0.8\n    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5\n    ▪ Using image docker.io/kubernetesui/dashboard:v2.7.0\n💡  Some dashboard features require the metrics-server addon. To enable all features please run:\n\n        minikube addons enable metrics-server\n\n🌟  Enabled addons: storage-provisioner, default-storageclass, dashboard\n🏄  Done! kubectl is now configured to use \"minikube\" cluster and \"default\" namespace by default\n\n\n% kubectl cluster-info\nKubernetes control plane is running at https://127.0.0.1:63402\nCoreDNS is running at https://127.0.0.1:63402/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy\n\nTo further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.\n\n\n% minikube dashboard\n🤔  Verifying dashboard health ...\n🚀  Launching proxy ...\n🤔  Verifying proxy health ...\n🎉  Opening http://127.0.0.1:63612/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/ in your default browser...\n```\n\n### Then change namespace in browser from default to ironoc-ns after 'kubectl create ns ironoc-ns'\n- i.e. http://127.0.0.1:63612/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/#/pod?namespace=ironoc-ns\n\n### Open New tab in terminal \u0026 create deployment\n```shell\n% docker image build -t ironoc .\n[+] Building 100.5s (11/11) FINISHED                                                                                                                                                                                                                                                        docker:desktop-linux\n =\u003e [internal] load build definition from Dockerfile                                                                                                                                                                                                                                                        0.0s\n =\u003e =\u003e transferring dockerfile: 284B                                                                                                                                                                                                                                                                        0.0s\n =\u003e [internal] load metadata for docker.io/library/eclipse-temurin:21-jdk                                                                                                                                                                                                                                   2.0s\n =\u003e [auth] library/eclipse-temurin:pull token for registry-1.docker.io                                                                                                                                                                                                                                      0.0s\n =\u003e [internal] load .dockerignore                                                                                                                                                                                                                                                                           0.0s\n =\u003e =\u003e transferring context: 2B                                                                                                                                                                                                                                                                             0.0s\n.\n.\n.\n\n\n% minikube image load ironoc:latest\n\n\n% kubectl create ns ironoc-ns\nnamespace/ironoc-ns created\n\n\n% kubectl apply -f k8s/ironoc.yaml --namespace=ironoc-ns\ndeployment.apps/ironoc-app-deployment created\nhorizontalpodautoscaler.autoscaling/ironoc-app-deployment-hpa-kbij created\n\n\n% kubectl get pods --namespace=ironoc-ns\nNAME                                     READY   STATUS    RESTARTS   AGE\nironoc-app-deployment-6d84f75b44-5xvgj   1/1     Running   0          8s\n\n\n% kubectl get deployment --namespace=ironoc-ns\nNAME                    READY   UP-TO-DATE   AVAILABLE   AGE\nironoc-app-deployment   1/1     1            1           105s\n\n\n% kubectl expose deployment ironoc-app-deployment --type=NodePort --namespace=ironoc-ns\n\nservice/ironoc-app-deployment exposed\n\n\n% kubectl get svc --namespace=ironoc-ns\nNAME                    TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE\nironoc-app-deployment   NodePort   10.98.229.246   \u003cnone\u003e        8080:31602/TCP   6s\n\n\n% minikube service ironoc-app-deployment --url --namespace=ironoc-ns\nhttp://127.0.0.1:63455\n❗  Because you are using a Docker driver on darwin, the terminal needs to be open to run it.\n```\n\n### Open New tab in terminal \u0026 tail logs\n```shell\n% kubectl get pods --namespace=ironoc-ns\nNAME                                     READY   STATUS    RESTARTS   AGE\nironoc-app-deployment-6d84f75b44-5xvgj   1/1     Running   0          3m28s\n\n\n% kubectl logs ironoc-app-deployment-6d84f75b44-5xvgj -f --namespace=ironoc-ns\n\njava  -jar /app.war\n\n\n_________ _______  _______  _        _______  _______\n\\__   __/(  ____ )(  ___  )( (    /|(  ___  )(  ____ \\\n   ) (   | (    )|| (   ) ||  \\  ( || (   ) || (    \\/\n   | |   | (____)|| |   | ||   \\ | || |   | || |\n   | |   |     __)| |   | || (\\ \\) || |   | || |\n   | |   | (\\ (   | |   | || | \\   || |   | || |\n___) (___| ) \\ \\__| (___) || )  \\  || (___) || (____/\\\n\\_______/|/   \\__/(_______)|/    )_)(_______)(_______/\n\n\n2025-05-19T18:47:04.581Z  INFO 7 --- [           main] n.i.p.App                                : Starting App v7.3.7 using Java 21.0.7 with PID 7 (/app.war started by root in /)\n2025-05-19T18:47:04.765Z  INFO 7 --- [           main] n.i.p.App                                : No active profile set, falling back to 1 default profile: \"default\"\n2025-05-19T18:47:22.489Z  INFO 7 --- [           main] o.s.b.w.e.t.TomcatWebServer              : Tomcat initialized with port 8080 (http)\n2025-05-19T18:47:22.788Z  INFO 7 --- [           main] o.a.c.c.StandardService                  : Starting service [Tomcat]\n2025-05-19T18:47:22.790Z  INFO 7 --- [           main] o.a.c.c.StandardEngine                   : Starting Servlet engine: [Apache Tomcat/10.1.40]\n2025-05-19T18:48:03.677Z  INFO 7 --- [           main] o.a.j.s.TldScanner                       : At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.\n2025-05-19T18:48:04.178Z  INFO 7 --- [           main] o.a.c.c.C.[.[.[/]                        : Initializing Spring embedded WebApplicationContext\n2025-05-19T18:48:04.181Z  INFO 7 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 58800 ms\n2025-05-19T18:48:06.066Z  WARN 7 --- [           main] n.i.p.l.AbstractLogger                   : The job to pre-populate the cache of GitHub information is disabled.\n2025-05-19T18:48:08.397Z  INFO 7 --- [           main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]\n2025-05-19T18:48:10.364Z  INFO 7 --- [           main] efaultSchemaResourceGraphQlSourceBuilder : Loaded 1 resource(s) in the GraphQL schema.\n2025-05-19T18:48:11.493Z  INFO 7 --- [           main] o.s.b.a.g.GraphQlAutoConfiguration       : GraphQL schema inspection:\n        Unmapped fields: {DonateItem=[donate, link, img, alt, name, overview, founded, phone], Query=[donateItemsByCountAndOffset]}\n        Unmapped registrations: {Query.donateItemsSchemaMapping=DonateGraphqlController#donateItemsSchemaMapping[0 args], Query.charityOptionByDonateLink=DonateGraphqlController#charityOptionByDonateLink[1 args], Donate.charityOptions=DonateGraphqlController#charityOptions[1 args]}\n        Unmapped arguments: {}\n        Skipped types: []\n2025-05-19T18:48:11.699Z  INFO 7 --- [           main] s.b.a.g.s.GraphQlWebMvcAutoConfiguration : GraphQL endpoint HTTP POST /graphql\n2025-05-19T18:48:13.978Z  INFO 7 --- [           main] o.s.b.w.e.t.TomcatWebServer              : Tomcat started on port 8080 (http) with context path '/'\n2025-05-19T18:48:14.061Z  INFO 7 --- [           main] n.i.p.App                                : Started App in 73.393 seconds (process running for 81.378)\n2025-05-19T18:50:24.815Z  INFO 7 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/]                        : Initializing Spring DispatcherServlet 'dispatcherServlet'\n2025-05-19T18:50:24.816Z  INFO 7 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet                : Initializing Servlet 'dispatcherServlet'\n2025-05-19T18:50:24.821Z  INFO 7 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet                : Completed initialization in 5 ms\n2025-05-19T18:50:27.308Z  INFO 7 --- [nio-8080-exec-5] n.i.p.l.AbstractLogger                   : Retrieved brews from GraphQL query, coffeeDomains=[name: 'Black Coffee' id: '1', name: 'Latte' id: '2', name: 'Caramel Latte' id: '3', name: 'Cappuccino' id: '4', name: 'Americano' id: '5', name: 'Espresso' id: '6', name: 'Macchiato' id: '7', name: 'Mocha' id: '8', name: 'Hot Chocolate' id: '9', name: 'Chai Latte' id: '10', name: 'Matcha Latte' id: '11', name: 'Seasonal Brew' id: '12', name: 'Svart Te' id: '13', name: 'Islatte' id: '14', name: 'Islatte Mocha' id: '15', name: 'Frapino Caramel' id: '16', name: 'Frapino Mocka' id: '17', name: 'Apelsinjuice' id: '18', name: 'Frozen Lemonade' id: '19', name: 'Lemonad' id: '20', name: 'Iced Coffee' id: '1', name: 'Iced Espresso' id: '2', name: 'Cold Brew' id: '3', name: 'Frappuccino' id: '4', name: 'Nitro' id: '5', name: 'Mazagran' id: '6']\n```\n\n### (clean-up \u0026 again after local testing complete)\n```shell\n% minikube delete \n🔥  Deleting \"minikube\" in docker ...\n🔥  Deleting container \"minikube\" ...\n🔥  Removing /home/.minikube/machines/minikube ...\n💀  Removed all traces of the \"minikube\" cluster.\n```\n\n### Navigate to GraphQL Playground via Charity Options drop down or directly by the following link(s):\n```\nhttp://localhost:8080/graphiql?path=/graphql\n\nor \n\nhttps://ironoc.net/graphiql?path=/graphql\n```\n![GraphQL Playground (PG)](screen-grabs/graph-i-ql.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconorheffron%2Fironoc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fconorheffron%2Fironoc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconorheffron%2Fironoc/lists"}