{"id":37019386,"url":"https://github.com/steinarb/sonar-collector","last_synced_at":"2026-01-14T02:08:55.115Z","repository":{"id":55802948,"uuid":"111156385","full_name":"steinarb/sonar-collector","owner":"steinarb","description":"A utility to collect a history of key numbers for each SonarQube analysis triggered by maven builds.","archived":false,"fork":false,"pushed_at":"2025-12-15T22:42:01.000Z","size":346,"stargazers_count":3,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-19T03:34:12.822Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/steinarb.png","metadata":{"files":{"readme":"README.org","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-11-17T22:22:26.000Z","updated_at":"2025-12-15T22:41:59.000Z","dependencies_parsed_at":"2024-01-08T16:46:01.236Z","dependency_job_id":"b80d11c9-0632-498c-a771-90394345a674","html_url":"https://github.com/steinarb/sonar-collector","commit_stats":null,"previous_names":[],"tags_count":54,"template":false,"template_full_name":null,"purl":"pkg:github/steinarb/sonar-collector","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steinarb%2Fsonar-collector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steinarb%2Fsonar-collector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steinarb%2Fsonar-collector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steinarb%2Fsonar-collector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/steinarb","download_url":"https://codeload.github.com/steinarb/sonar-collector/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steinarb%2Fsonar-collector/sbom","scorecard":{"id":850912,"data":{"date":"2025-08-11","repo":{"name":"github.com/steinarb/sonar-collector","commit":"862b05e9fe1d44661e32bfc89d646f995a8657e9"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/28 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":10,"reason":"20 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/sonar-collector-maven-ci-build.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/sonar-collector-maven-ci-build.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/steinarb/sonar-collector/sonar-collector-maven-ci-build.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/sonar-collector-maven-ci-build.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/steinarb/sonar-collector/sonar-collector-maven-ci-build.yml/master?enable=pin","Warn: containerImage not pinned by hash: docker/docker/Dockerfile:1: pin your Docker image by updating apache/karaf:4.2.8 to apache/karaf:4.2.8@sha256:90ab8758ddddf4f0b28afe7ca24b67456a9a8619be4cf5fc2fa90e3b26e64adf","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 2 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":9,"reason":"1 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-j288-q9x7-2f5v"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-23T22:30:44.258Z","repository_id":55802948,"created_at":"2025-08-23T22:30:44.259Z","updated_at":"2025-08-23T22:30:44.259Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408711,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2026-01-14T02:08:54.380Z","updated_at":"2026-01-14T02:08:55.107Z","avatar_url":"https://github.com/steinarb.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"* SonarQube metrics collector\n\n[[https://www.sonarqube.org][SonarQube]] is a code analysis tool that shows key numbers about code quality, e.g. code coverage, code complexity and various code practices.\n\nSonarQube has a web GUI that allows exploring the analysis results.\n\nHowever, SonarQube has no storage of build quality history.  To keep statistics about code quality one either have to manually type the key numbers of each analysed application into a spreadsheet, or use something like this tool.\n\nThis utility consists of a servlet that serves as a [[https://docs.sonarqube.org/display/SONAR/Webhooks][webhook that is called by Sonar when completing an analysis]].  The webhook POST data doesn't have the necessary information (which are some key metrics of the build).\n\nSo when receiving a POST, the servlet will do a callback to the SonarQube REST API to retrieve the metrics, which will then be stored in a PostgreSQL database.\n\nThe servlet has been written as a microservice that can be installed into an [[http://karaf.apache.org][apache karaf]] instance.\n\n** Status of the project\n\n[[https://github.com/steinarb/sonar-collector/actions/workflows/sonar-collector-maven-ci-build.yml][file:https://github.com/steinarb/sonar-collector/actions/workflows/sonar-collector-maven-ci-build.yml/badge.svg]]\n[[https://coveralls.io/github/badges/shields?branch=master][file:https://coveralls.io/repos/github/badges/shields/badge.svg?branch=master]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sonar-collector][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sonar-collector\u0026metric=alert_status#.svg]]\n[[https://maven-badges.herokuapp.com/maven-central/no.priv.bang.sonar.sonar-collector/sonar-collector][file:https://maven-badges.herokuapp.com/maven-central/no.priv.bang.sonar.sonar-collector/sonar-collector/badge.svg]]\n\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sonar-collector][file:https://sonarcloud.io/images/project_badges/sonarcloud-white.svg]]\n\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sonar-collector][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sonar-collector\u0026metric=sqale_index#.svg]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sonar-collector][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sonar-collector\u0026metric=coverage#.svg]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sonar-collector][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sonar-collector\u0026metric=ncloc#.svg]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sonar-collector][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sonar-collector\u0026metric=code_smells#.svg]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sonar-collector][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sonar-collector\u0026metric=sqale_rating#.svg]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sonar-collector][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sonar-collector\u0026metric=security_rating#.svg]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sonar-collector][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sonar-collector\u0026metric=bugs#.svg]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sonar-collector][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sonar-collector\u0026metric=vulnerabilities#.svg]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sonar-collector][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sonar-collector\u0026metric=duplicated_lines_density#.svg]]\n[[https://sonarcloud.io/summary/new_code?id=steinarb_sonar-collector][file:https://sonarcloud.io/api/project_badges/measure?project=steinarb_sonar-collector\u0026metric=reliability_rating#.svg]]\n\n*** Release history\n\n| Version | Date             | Description                                                                                 |\n|---------+------------------+---------------------------------------------------------------------------------------------|\n|  2.5.36 | \u003c2025-09-20 Sat\u003e | Use postgresql 42.7.8                                                                                        |\n|  2.5.35 | \u003c2025-07-11 Fri\u003e | Use liquibase 4.33.0                                                                        |\n|  2.5.34 | \u003c2025-06-18 Wed\u003e | Use jackson 2.19.1                                                                          |\n|  2.5.33 | \u003c2025-06-14 Sat\u003e | Built for java 21, use postgresql 42.7.7                                                    |\n|  2.5.32 | \u003c2025-04-05 Sat\u003e | Use liquibase 4.31.1 (version number mistake in release:prepare, sorry!)                    |\n|  1.5.31 | \u003c2025-02-19 Wed\u003e | Use liquibase 4.31.0                                                                        |\n|  1.5.30 | \u003c2025-02-12 Wed\u003e | Build with karaf 4.4.7, postgresql jdbc 42.7.5                                              |\n|  1.5.29 | \u003c2024-12-14 Sat\u003e | Use liquibase 4.30.0, postgresql jdbc 42.7.4                                                |\n|  1.5.28 | \u003c2024-08-03 Sat\u003e | Use jackson 2.17.2                                                                          |\n|  1.5.27 | \u003c2024-08-01 Thu\u003e | Use liquibase 4.29.0                                                                        |\n|  1.5.26 | \u003c2024-07-05 Fri\u003e | Use liquibase 4.28.0                                                                        |\n|  1.5.25 | \u003c2024-04-06 Sat\u003e | Use liquibase 4.27.0 and to build with karaf 4.4.5                                          |\n|  1.5.24 | \u003c2024-03-25 Mon\u003e | Use postgresql JDBC 42.7.3, jackson 2.16.2                                                  |\n|  1.5.23 | \u003c2024-03-02 Sat\u003e | Use postgresql JDBC 42.7.2                                                                  |\n|  1.5.22 | \u003c2023-12-14 Thu\u003e | Use postgresql JDBC 42.7.1 and mockito 5.8.0                                                |\n|  1.5.21 | \u003c2023-12-12 Tue\u003e | Use liquibase 4.24.0                                                                        |\n|  1.5.20 | \u003c2023-11-05 Sun\u003e | Use jackson 2.15.3, junit jupiter 5.10.0, and mockito 5.7.0                                 |\n|  1.5.19 | \u003c2023-10-31 Tue\u003e | Use karaf 4.4.4                                                                             |\n|  1.5.18 | \u003c2023-07-30 Sun\u003e | Use liquibase 2.15.2                                                                        |\n|  1.5.17 | \u003c2023-07-08 Sat\u003e | Use Java 17                                                                                 |\n|  1.5.16 | \u003c2023-07-02 Sun\u003e | Use liquibase 4.23.0                                                                        |\n|  1.5.15 | \u003c2023-04-26 Wed\u003e | Use jackson 2.15.0                                                                          |\n|  1.5.14 | \u003c2023-04-24 Mon\u003e | Use jackson 2.14.2                                                                          |\n|  1.5.13 | \u003c2023-04-23 Sun\u003e | Build karaf feature files in the maven \"compile\" phase                                      |\n|  1.5.12 | \u003c2023-03-06 Mon\u003e | Use liquibase 4.19.0, pax-jdbc 1.5.5, postgresql jdbc 42.5.4, karaf 4.4.3                   |\n|  1.5.11 | \u003c2022-12-04 Sun\u003e | Use jackson 2.14.1 to fix CVE-2022-42003 and CVE-2022-42004                                 |\n|  1.5.10 | \u003c2022-11-26 Sat\u003e | Use postgresql jdbc 42.5.1 to fix CVE-2022-41946                                            |\n|   1.5.9 | \u003c2022-11-01 Tue\u003e | Use liquibase 4.17.1, postgresql jdbc 42.5.0                                                |\n|   1.5.8 | \u003c2022-10-20 Thu\u003e | Add support for maintainability, security and reliability ratings                           |\n|   1.5.7 | \u003c2022-10-12 Wed\u003e | Work with SonarQube with version \u003e= 8 (no longer works with version 7.x and older)          |\n|   1.5.6 | \u003c2022-10-09 Sun\u003e | Github actions CI build, sonar report cleanup, support for sonar user token                 |\n|   1.5.5 | \u003c2022-08-21 Sun\u003e | Use liquibase 4.15.0                                                                        |\n|   1.5.4 | \u003c2022-08-10 Wed\u003e | Use maven-bundle-plugin 5.1.8, junit jupiter 5.9.0, mockito 4.6.1, and assertj 2.23.1       |\n|   1.5.3 | \u003c2022-08-10 Wed\u003e | Use postgresql jdbc driver 42.4.1                                                           |\n|   1.5.2 | \u003c2022-07-25 Mon\u003e | Use karaf 4.4.1                                                                             |\n|   1.5.1 | \u003c2022-05-31 Tue\u003e | Use jackson jackson 2.13.3 to fix security issue                                            |\n|   1.5.0 | \u003c2022-05-29 Sun\u003e | Use karaf 4.4.0 and OSGi 8                                                                  |\n|   1.4.8 | \u003c2022-02-21 Mon\u003e | Use Java 11, karaf 4.3.6, junit 5.8.2, assertj 3.22.0 and mockito 4.3.1                     |\n|   1.4.7 | \u003c2021-10-14 Thu\u003e | Use karaf 4.3.3 and postgresql JDBC 4.2.24                                                  |\n|   1.4.6 | \u003c2021-07-25 Sun\u003e | Use PostgreSQL JDBC driver 42.2.23                                                          |\n|   1.4.5 | \u003c2021-06-15 Tue\u003e | Use jackson 12.3                                                                            |\n|   1.4.4 | \u003c2021-06-13 Sun\u003e | Align dependency versions with other applications                                           |\n|   1.4.3 | \u003c2021-06-01 Tue\u003e | Get versions for the OSGi 7 framework and the OSGi compendium from the karaf BoM            |\n|   1.4.2 | \u003c2021-04-19 Mon\u003e | Get OSGi adapters dependency from a BoM                                                     |\n|   1.4.1 | \u003c2021-04-17 Sat\u003e | Get maven dependency versions and maven plugin config from a parent POM                     |\n|   1.4.0 | \u003c2021-04-12 Mon\u003e | Built with karaf 4.3.0 and OSGi 7                                                           |\n|   1.3.4 | \u003c2021-03-21 Sun\u003e | Bugfix: avoid loading junit and hamcrest in karaf                                           |\n|   1.3.3 | \u003c2021-03-21 Sun\u003e | Get maven dependencies from the karaf 4.2.11 BoM                                            |\n|   1.3.2 | \u003c2020-10-10 Sat\u003e | Use PostgreSQL JDBC driver 42.2.17                                                          |\n|   1.3.1 | \u003c2020-09-26 Sat\u003e | Use PostgreSQL JDBC driver 42.2.12                                                          |\n|   1.3.0 | \u003c2020-07-24 Fri\u003e | Remove use of cobertura, upgrade liquibase from 3.5.3 to 3.8.0                              |\n|   1.2.0 | \u003c2020-04-20 Mon\u003e | Use jackson-databind 2.9.10.3, make liquibase script work with h2                           |\n|   1.1.0 | \u003c2019-11-14 Thu\u003e | Use pax-jdbc-config to set up the database, build with openjdk 11, jackson security upgrade |\n|   1.0.0 | \u003c2017-12-18 Mon\u003e | First release                                                                               |\n\n** How to build the application\n\n(this assumes that you have an [[https://karaf.apache.org/manual/latest/quick-start.html#_quick_start][apache karaf already installed]] on your development computer, as well as git, maven, and a Java development kit)\n\nProcedure:\n 1. Clone the project\n    #+BEGIN_EXAMPLE\n      mkdir -p ~/git\n      cd ~/git\n      git clone https://github.com/steinarb/sonar-collector.git\n    #+END_EXAMPLE\n 2. Build the project with maven\n    #+BEGIN_EXAMPLE\n      cd ~/git/sonar-collector\n      mvn clean install\n    #+END_EXAMPLE\n 3. Give the following commands from the karaf console to install the REST service:\n    #+BEGIN_EXAMPLE\n      feature:repo-add mvn:no.priv.bang.sonar.sonar-collector/sonar-collector-webhook/LATEST/xml/features\n      feature:install sonar-collector-webhook-with-postgresql\n    #+END_EXAMPLE\n\n/Note/: You will need to have a suitable PostgreSQL database to write to for this servlet to be meaningful.  See the sections [[Create the database]] and [[Using a database running on a different host]] for more detail.  The database just have to be a blank, freshly created database, that the servlet can write to, either on localhost with the curent user, or using JDBC credentials configured from the karaf console (this is what's covered in [[Using a database running on a different host]]).\n\n** Run the Sonar metrics collector in docker\n\n[[https://hub.docker.com/repository/docker/steinarb/sonar-collector][The latest version of the sonar-collector is available from docker hub]].\n\n/Note/: The docker image is actually provisioned at startup time by the latest sonar-collector release to maven central, so don't be mislead by the creation date of the image. The most recent relase to maven central is what will be run.\n\nTo run the sonar-collector in the container:\n 1. get hold of an RDBMS (preferrably [[create an RDBMS ][PostgreSQL]] but any RDMS that has its driver deployed to maven central (i.e. /not/ Oracle) can probably be made to work)\n    1. The database could be an AWS MicroDB (preferraby PostgreSQL)\n    2. The database could potentially be an aurora instance (however, this heas not been tried, since AWS aurora instances costs money from day one)\n 2. add a user to the RDBMS (e.g. \"myuser\" with password \"sosecret\")\n 3. add a blank database to the RDBMS, e.g. named \"sonar-collector\", with the user created above as owner\n 4. In the docker container, get the image from docker hub:\n    #+begin_example\n      pull steinarb/sonar-collector:latest\n    #+end_example\n 5. Start a container with the image, setting the JDBC credentials as environment variables:\n    #+begin_example\n      docker run -p 8101:8101 -p 8181:8181  -e \"JDBC_URL=jdbc:postgresql://somehost.com/sonar-collector\"  -e \"JDBC_USER=myuser\" -e \"JDBC_USER=sosecret\" -d steinarb/sonar-collector:latest\n    #+end_example\n 6. [[https://docs.sonarqube.org/latest/project-administration/webhooks/][Add the URL of the sonar-collector running inside the container as a webhook to sonar]] (e.g. http://somecontainer.somecompany.com:8181/sonar-collector)\n 7. After this the key measurements from each sonar run will be stored as a row in the measures table with the time of the run\n 8. There is no UI, use a database explorer tool to run queries on the measures table to get the desired number\n\n*** JDBC config that can be set with environment variables\n\nThe values that can be overridden by setting environment variables on container start, are:\n| Variable            | Default value                      | Description                                                   |\n|---------------------+------------------------------------+---------------------------------------------------------------|\n| JDBC_DRIVER_FEATURE | postgresql                         | Karaf feature to load the driver                              |\n| JDBC_DRIVER_NAME    | PostgreSQL JDBC Driver             | Identify correct driver for OSGi service dependency injection |\n| JDBC_URL            | jdbc:postgresql:///sonar-collector |                                                               |\n| JDBC_USER           | \u003cnone\u003e                             | No default to make it possible to have no username            |\n| JDBC_PASSWORD       | \u003cnone\u003e                             | No default to make it possible to have no password            |\n\nExample docker run command for using a h2 database instead of postgresl\n#+begin_example\n  docker run -p 8101:8101 -p 8181:8181 -e 'JDBC_DRIVER_FEATURE=pax-jdbc-h2' -e 'JDBC_DRIVER_NAME=H2 JDBC Driver' -e 'JDBC_URL=jdbc:h2:tcp://somehost.company.com/~/sonar-collector' -e 'JDBC_USER=sa' -e JDBC_PASSWORD='' -d steinarb/sonar-collector:latest\n#+end_example\n\n*** Example values for some RDBMSes\n\n| RDBMS type          | Karaf feature    | JDBC_DRIVER_NAME                     | example JDBC_URL                                                        | Default port |\n|---------------------+------------------+--------------------------------------+-------------------------------------------------------------------------+--------------|\n| PostgreSQL          | postgresql       | PostgreSQL JDBC Driver               | jdbc:postgresql://somehost.company.com/sonar-collector                  |         5432 |\n| Derby (aka. JavaDB) | pax-jdbc-derby   | derby                                | jdbc:derby://somehost.company.com:1527/sonar-collector                  |         1527 |\n| H2                  | pax-jdbc-h2      | H2 JDBC Driver                       | jdbc:h2:tcp://somehost.company.com/~/sonar-collector                    |         9092 |\n| MSSQL               | pax-jdbc-mssql   | Microsoft JDBC Driver for SQL Server | jdbc:sqlserver://somehost.company.com:1433;databaseName=sonar-collector |         1433 |\n| mariadb             | pax-jdbc-mariadb | mariadb                              | jdbc:mariadb://somehost.company.com:3306/sonar-collector                |         3306 |\n| mysql               | pax-jdbc-mysql   | mysql                                | jdbc:mysql://somehost.company.com:3306/sonar-collector                  |         3306 |\n\n** How to install and run the application on a debian server\n\n(This procedure doesn't require development tools or building the project yourself.  The servlet, and its attached karaf feature has been deployed to maven central)\n\nThis describes how to install and run the program on a debian GNU/linux system.\n\n*** Install the required software\n\nAs root, do the following command:\n#+BEGIN_EXAMPLE\n  apt-get update\n  apt-get install postgresql\n#+END_EXAMPLE\n\n*** Create the database\n\nProcedure:\n 1. Create a PostgreSQL user matching the karaf user:\n    #+BEGIN_EXAMPLE\n      /usr/bin/sudo -u postgres createuser --pwprompt karaf\n    #+END_EXAMPLE\n    1. At the prompt \"Enter password for new role\", enter the JDBC password for user \"karaf\"\n    2. At the prompt \"Enter it again\", enter the same password again\n    Make a note of this password, since it will be needed later, when [[Using a database running on a different host][setting up a password authenticated connection]]\n 2. Create an empty database owned by the karaf user:\n    #+BEGIN_EXAMPLE\n      /usr/bin/sudo -u postgres createdb -O karaf sonarcollector\n    #+END_EXAMPLE\n\n*** Install apache karaf\n\nDo the following steps as root\n 1. Add a key for the apt repo containing the karaf package\n    #+BEGIN_EXAMPLE\n      wget -O - https://apt.bang.priv.no/apt_pub.gpg | apt-key add -\n    #+END_EXAMPLE\n 2. Add the repo containing karaf by adding the following lines to /etc/apt/sources.list :\n    #+BEGIN_EXAMPLE\n      # APT archive for apache karaf\n      deb http://apt.bang.priv.no/public stable main\n    #+END_EXAMPLE\n 3. Install the debian package\n    #+BEGIN_EXAMPLE\n      apt-get update\n      apt-get install karaf\n    #+END_EXAMPLE\n*** Install the application in karaf\n\nProcedure:\n 1. SSH into karaf\n    #+BEGIN_EXAMPLE\n      ssh -p 8101 karaf@localhost\n    #+END_EXAMPLE\n    The password is \"karaf\" (without the quotes)\n 2. Install the application\n    #+BEGIN_EXAMPLE\n      feature:repo-add mvn:no.priv.bang.sonar.sonar-collector/sonar-collector-webhook/LATEST/xml/features\n      feature:install sonar-collector-webhook-with-postgresql\n    #+END_EXAMPLE\n\n(sonar-collector has been deployed to maven central, which is a repository that is builtin to karaf)\n**** Using a database running on a different host\n\nThe above example shows connecting to a PostgreSQL database running on localhost, authenticating with ident authentication (ie. no password).\n\nThis example shows how to connect to a PostgreSQL database running on a different host, authenticating using username and password.\n\nProcedure:\n 1. SSH into karaf\n    #+BEGIN_EXAMPLE\n      ssh -p 8101 karaf@localhost\n    #+END_EXAMPLE\n    The password is \"karaf\" (without the quotes)\n 2. In the karaf command shell, create configuration for the JDBC connection:\n    #+BEGIN_EXAMPLE\n      config:edit org.ops4j.datasource-sonar-collector\n      config:property-set osgi.jdbc.driver.name \"PostgreSQL JDBC Driver\"\n      config:property-set dataSourceName \"jdbc/sonar-collector\"\n      config:property-set url \"jdbc:postgresql://lorenzo.hjemme.lan/sonarcollector\"\n      config:property-set user \"karaf\"\n      config:property-set password \"karaf\"\n      config:property-set org.apache.karaf.features.configKey \"org.ops4j.datasource-sonar-collector\"\n      config:update\n    #+END_EXAMPLE\n    (this assumes the username/password combination karaf/karaf, it is recommended to use a different password in a real setting with PostgreSQL accepting network connections)\n\nThe \"config:update\" command will cause the sonar collector to be restarted, it will pick up the new configuration, and connect to the remote server, and if the \"sonar-collector\" database exists as a blank database, create the schema and be ready to store data there.\n\nSide note: The configuration will be stored in standard .properties file format, in the file /etc/karaf/no.priv.bang.sonar.collector.webhook.SonarCollectorServlet.cfg and be persistent across restarts and reinstallations of the karaf .deb package (the .deb package will only uninstall/reinstall unchanged known files in this directory, and won't touch unknown files at all).\n\n***** Allowing network connections in PostgreSQL on debian\n\nNote that PostgreSQL out of the box on debian only accepts domain connections and localhost connections.\n\nTo make PostgreSQL listen on all network connections, two files must be edited and the PostgreSQL daemon must be restarted.\n\nProcedure, do the following, logged in as root on the server:\n 1. Do \"su\" to user postgres to get the right ownership on the files\n    #+BEGIN_EXAMPLE\n      su - postgres\n    #+END_EXAMPLE\n 2. Edit the /etc/postgresql/9.6/main/postgresql.conf file, uncomment the listen_address line and edit it to look like this\n    #+BEGIN_SRC conf\n      listen_addresses = '*'                  # what IP address(es) to listen on;\n    #+END_SRC\n 3. Edit the /etc/postgresql/9.6/main/pg_hba.conf, add the following lines\n    #+BEGIN_SRC conf\n      # IPv4 network connection allow password authentication\n      host    all             all             0.0.0.0/0               md5\n    #+END_SRC\n 4. Log out from user postgres (only root can restart the daemon):\n    #+BEGIN_EXAMPLE\n      exit\n    #+END_EXAMPLE\n 5. Restart the postgresql daemon\n    #+BEGIN_EXAMPLE\n      systemctl restart postgresql\n    #+END_EXAMPLE\n**** Using a different database than PostgreSQL\n\n/WARNING/! This is not regularily tested (i.e. won't be tested before releases) and I don't plan to actually use sonar-collector with anything except PostgreSQL myself.\n\nTo use JDBC against a RDBMS other than PostgreSQL, do the following from the karaf console command line (derby in-memory database used in the examples):\n 1. Load the component providing the DataSourceFactory OSGi service:\n    #+BEGIN_EXAMPLE\n      feature:install pax-jdbc-derby\n    #+END_EXAMPLE\n 2. Add karaf configuration selecting the correct DataSourceFactory and JDBC connection info (url, user and password):\n    #+BEGIN_EXAMPLE\n      config:edit org.ops4j.datasource-sonar-collector\n      config:property-set osgi.jdbc.driver.name \"PostgreSQL JDBC Driver\"\n      config:property-set dataSourceName \"jdbc/sonar-collector\"\n      config:property-set url \"jdbc:derby:data/example/derby;create=true\"\n      config:property-set osgi.jdbc.driver.name derby\n      config:property-set org.apache.karaf.features.configKey \"org.ops4j.datasource-sonar-collector\"\n      config:update\n    #+END_EXAMPLE\n 3. Load sonar-collector using a feature that doesn't unnecessarily pull in the PostgreSQL DataSourceFactory:\n    #+BEGIN_EXAMPLE\n      feature:repo-add mvn:no.priv.bang.sonar.sonar-collector/sonar-collector-webhook/LATEST/xml/features\n      feature:install sonar-collector-webhook-with-jdbc\n    #+END_EXAMPLE\n\n*** Add a webhook to Sonar\n\n**** Add a webhook to SonarCloud\n\nProcedure:\n 1. Open your SonarCloud project in a web browser and log in as a user with ownership to the project (I do login as github user)\n 2. In the project select the menu Administration-\u003eGeneral Settings\n 3. Select the webhooks tab in the tab bar on the left side of the page (you may have to scroll down to see it)\n 4. In \"Name:\", write:\n    : sonar-collecttor\n 5. In \"URL\", write:\n    : https://mydowmain.com:8181/sonar-collector\n 6. Click the button \"Save\"\n\n**** Add a webhook to a hosted SonarQube instance\n\nIn a hosted SonarQube the webhook can be set globally across all projects.\n\nProcedure:\n 1. Open your SonarCloud instance in a web browser, e.g. http://localhost:9000 and log in as an admin user (admin/admin in a test instance)\n 2. In the top menu, select Administration\n 3. Select the tab \"Webhooks\" in the list to the left of the page (you may have to scroll down to see the tab)\n 4. In \"Name\", type:\n    : sonar-collector\n 5. In \"URL\", type:\n    : http://localhost:8181/sonar-collector\n 6. Click the button \"Save\"\n\n*** Set a user token\nIf you get 401 when sonar-collector is doing web api callbacks to sonar to get numbers that aren't in the webhook call, then you can add a sonar user token to use with the sonar web api.\n\nProcedure:\n 1. In Sonar, go to My Account-\u003eSecurity, and create and retrieve a user token (/Note/: you only get one chance to copy the token after creating it)\n 2. Add the user token to the sonar-collector config. replace \"squ_3869fbac07cc388306804e35fb72ca7c4baff275\" with the token retrieved from sonar:\n    #+begin_example\n      config:edit no.priv.bang.sonar.collector.webhook.SonarCollectorServlet\n      config:property-set sonar_user_token squ_3869fbac07cc388306804e35fb72ca7c4baff275\n      config:update\n    #+end_example\n** License\n\nThis utility is licensend under the Apache license v. 2.  See the LICENSE file for details.\n** Development stuff\n*** Testing and debugging\n\nTo run the servlet locally and debug into the servlet, the following software is required:\n 1. A locally installed [[https://karaf.apache.org/][apache karaf]] (see the [[https://karaf.apache.org/manual/latest/quick-start.html][apache karaf quick start guide]] )\n 2. A locally installed [[https://www.sonarqube.org][SonarQube]] (see [[https://docs.sonarqube.org/display/SONAR/Webhooks][SonarQube Get Started in Two Minutes]] )\n 3. A locally installed (or at least reachable, see [[Using a database running on a different host]] ) [[https://www.postgresql.org][PostgreSQL database]]\n 4. An IDE that can do remote debugging\n\nPreparation for debugging\n 1. [[Create the database][create user and empty database in PostgreSQL]]\n 2. Add http://localhost:8181/sonar-collector as a [[Add a webhook to SonarCloud][webhook in SonarQube]]\n 3. Clone and build the sonar-collector\n    #+BEGIN_EXAMPLE\n      mkdir -p ~/git\n      cd ~/git/\n      git clone https://github.com/steinarb/sonar-collector.git\n      cd ~/git/sonar-collector/\n      mvn clean install\n    #+END_EXAMPLE\n 4. Start karaf with setup for remote debugging (cd to an unpacked downloaded karaf installation, start karaf as the user you used to do \"mvn clean install\")\n    #+BEGIN_EXAMPLE\n      cd ~/Downloads/apache-karaf-4.1.4/\n      bin/karaf debug\n    #+END_EXAMPLE\n 5. Install the sonar-collector in karaf, with the following commands in the karaf console:\n    #+BEGIN_EXAMPLE\n      feature:repo-add mvn:no.priv.bang.sonar.sonar-collector/sonar-collector-webhook/LATEST/xml/features\n      feature:install sonar-collector-webhook\n    #+END_EXAMPLE\n 6. Connect the IDE to a debugging connection on localhost port 5005 (see your IDE's documentation for this) and set the breakpoint at the desired code\n\nThen just trigger an analysis in the locally installed SonarQube and debug when the breakpoint is triggered:\n#+BEGIN_EXAMPLE\n   mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent package sonar:sonar -Dsonar.host.url=http://localhost:9000 -Dsonar.login=a51f2ab9a8790abd91773f0a7d2f6d2dc9d97975\n#+END_EXAMPLE\n(as the sonar.login argument, use the token that SonarQube returns when using the setup wizard of the quick start)\n*** Building the docker image\n\nPrecondition: docker running on the build server\n\nProcedure:\n 1. Move to the build directory:\n    #+begin_example\n      cd docker/\n    #+end_example\n 2. Build the image:\n    #+begin_example\n      mvn clean install\n    #+end_example\n 3. Verify with \"docker images\" that the image has been rebuilt (if the CREATED column shows an old time the image probably hasn't been rebuilt):\n    #+begin_example\n      sb@lorenzo:~/workspaces/ws02/sonar-collector/docker$ docker images\n      REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE\n      steinarb/sonar-collector   latest              6c578e16f6e0        3 seconds ago       291MB\n      sb@lorenzo:~/workspaces/ws02/sonar-collector/docker$\n    #+end_example\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsteinarb%2Fsonar-collector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsteinarb%2Fsonar-collector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsteinarb%2Fsonar-collector/lists"}