{"id":20113290,"url":"https://github.com/cloudacademy/java-tdd-bitcoinconverter","last_synced_at":"2025-05-06T12:30:28.435Z","repository":{"id":42517642,"uuid":"305224366","full_name":"cloudacademy/java-tdd-bitcoinconverter","owner":"cloudacademy","description":"Java JDK11 TDD Bitcoin Converter Project","archived":false,"fork":false,"pushed_at":"2023-07-26T06:37:39.000Z","size":121,"stargazers_count":2,"open_issues_count":0,"forks_count":18,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-09T12:11:39.828Z","etag":null,"topics":["bitcoin","cloudacademy","devops","java","jdk11","junit5","maven","mockito","tdd"],"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/cloudacademy.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-10-19T00:36:41.000Z","updated_at":"2024-02-19T01:29:34.000Z","dependencies_parsed_at":"2024-11-13T18:26:54.403Z","dependency_job_id":"615fe9f1-aed9-4e42-b194-ecc5be307a93","html_url":"https://github.com/cloudacademy/java-tdd-bitcoinconverter","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudacademy%2Fjava-tdd-bitcoinconverter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudacademy%2Fjava-tdd-bitcoinconverter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudacademy%2Fjava-tdd-bitcoinconverter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudacademy%2Fjava-tdd-bitcoinconverter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cloudacademy","download_url":"https://codeload.github.com/cloudacademy/java-tdd-bitcoinconverter/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252683361,"owners_count":21788022,"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":["bitcoin","cloudacademy","devops","java","jdk11","junit5","maven","mockito","tdd"],"created_at":"2024-11-13T18:23:52.492Z","updated_at":"2025-05-06T12:30:28.128Z","avatar_url":"https://github.com/cloudacademy.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Java JDK11 TDD Bitcoin Converter\n\n[![dev.build](https://github.com/cloudacademy/java-tdd-bitcoinconverter/actions/workflows/dev.build.yml/badge.svg)](https://github.com/cloudacademy/java-tdd-bitcoinconverter/actions/workflows/dev.build.yml) [![prod.build](https://github.com/cloudacademy/java-tdd-bitcoinconverter/actions/workflows/prod.build.yml/badge.svg)](https://github.com/cloudacademy/java-tdd-bitcoinconverter/actions/workflows/prod.build.yml) [![code coverage](https://coveralls.io/repos/github/cloudacademy/java-tdd-bitcoinconverter/badge.svg?branch=main)](https://coveralls.io/github/cloudacademy/java-tdd-bitcoinconverter?branch=main)\n\n## Background\nThe following repo contains source code developed using TDD (Test Driven Development) practices. The sample project implements a Java (JDK 11) library which interacts with the [Bitcoin Price Index](https://www.coindesk.com/coindesk-api) api.\n\n![Bitcoin Converter Architecture](./docs/java-tdd-bitcoinconverter.png)\n\n**Note**: If you intend to follow along and complete the full demonstration then please fork or setup a new GitHub repo - as step 6 will require you to create a GitHub Secret to store the [Coveralls](https://coveralls.io/) project token. Coveralls is used to create code coverage reports and visuals. \n\n:metal:\n\n## Prerequisites\n**JDK11** and **Maven3** are required for this project \n\nAll provided sample code and instructions have been tested with the following versions:\n\n* JDK11\n\n```\njava -version\nopenjdk version \"11.0.9\" 2020-10-20\nOpenJDK Runtime Environment (build 11.0.9+11)\nOpenJDK 64-Bit Server VM (build 11.0.9+11, mixed mode)\n```\n\n* Maven3\n\n```\nmvn --version\nApache Maven 3.9.3 (21122926829f1ead511c958d89bd2f672198ae9f)\nMaven home: /opt/maven\nJava version: 11.0.19, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64\nDefault locale: en, platform encoding: UTF-8\nOS name: \"linux\", version: \"4.15.0-212-generic\", arch: \"amd64\", family: \"unix\"\n```\n\n## Tools and Frameworks\nThe following tools and frameworks have been used to perform the TDD developement:\n\n* [Maven](http://maven.apache.org/) - used to provide build and test project automation and management\n* [JUnit5](https://junit.org/junit5/) - a unit testing framework, used to implement unit tests\n* [Mockito](https://site.mockito.org/) - a mocking library, used to create mocks for external dependencies\n* [GitHub Actions](https://github.com/features/actions) - used to provide CICD features for automated building and testing\n* [Coveralls](https://coveralls.io/) - used to provide unit test code coverage reports\n\n## JDK11 and JUnit5 Maven Archetype\nThe following custom Maven Archetype has been made available - this can used to create new JDK11 and JUnit5 based projects:\n\nhttps://github.com/cloudacademy/java11-junit5-archetype\n\n## Repo Branches\nBranches are used within this repo to demonstrate the TDD workflow (red, green, refactor), as well as highlighting other project management configuration areas. These branches allow you to quickly jump ahead to the area of interest:\n\n### Branches\n* [step1](https://github.com/cloudacademy/java-tdd-bitcoinconverter/tree/step1) - demonstrates how to setup the initial project structure with the first set of unit tests using JUnit5 and the ```@Test``` annotation, uses a fake implementation of the Bitcoin Price Index API\n\n* [step2](https://github.com/cloudacademy/java-tdd-bitcoinconverter/tree/step2) - refactors current unit tests and codebase to call the real Bitcoin Price Index API using the Apache HttpClient for HTTP access - the tests in this step will fail, this introduces you to the next step (mocks)\n\n* [step3](https://github.com/cloudacademy/java-tdd-bitcoinconverter/tree/step3) - introduces Mockito and refactors current unit tests to mock the Apache HttpClient HTTP calls to the Bitcoin Price Index API\n\n* [step4](https://github.com/cloudacademy/java-tdd-bitcoinconverter/tree/step4) - refactors the unit tests and codebase to add addtional unit tests to test error conditions\n\n* [step5](https://github.com/cloudacademy/java-tdd-bitcoinconverter/tree/step5) - adds in a GitHub Action workflow to perform automatic build and tests on push events - produces a jar artifact\n\n* [step6](https://github.com/cloudacademy/java-tdd-bitcoinconverter/tree/step6) - refactors the single GitHub Action workflow into seperate Dev and Prod GitHub Action workflows - the Dev workflow generates a unit test code coverage report and forwards it automatically into https://coveralls.io/ for viewing and analysis - the Prod workflow is used to produce releases\n\n* [step7](https://github.com/cloudacademy/java-tdd-bitcoinconverter/tree/step7) - introduces a client console project to test the GitHub Action built jar library artifact\n\n**Note**: The [main](https://github.com/cloudacademy/java-tdd-bitcoinconverter/tree/main) branch (this branch) contains the same code and configuration as contained in the [step7](https://github.com/cloudacademy/java-tdd-bitcoinconverter/tree/step7) branch\n\n## Bitcoin Converter Library\nThis project builds a Java library which contains the following 2 public methods:\n```java\npublic double getExchangeRate(Currency currency)\n```\nreturns in realtime the current Bitcoin exchange rate for the given currency (USD, GBP, or EUR)\n\n```java\npublic double convertBitcoins(Currency currency, double coins) throws IllegalArgumentException\n```\nreturns the dollar value for the given currency (USD, GBP, or EUR), and the number of Bitcoins\n\nTo build the Bitcoin Converter Library perform the following commands:\n\n```\nmvn clean compile test package\n```\n\n## Bitcoin Converter Client\nThis project also contains a sample [client](https://github.com/cloudacademy/java-tdd-bitcoinconverter/tree/main/client) console based application - which imports the Bitcoin Converter library. To build and run the client perform the following commands:\n\n```bash\n{\ncd client\n\n#install bitcoin lib\nFILE=`ls libs/`\nVERSION=`echo $FILE | egrep -o \"([0-9]{1,}\\.)+[0-9]{1,}-\\w*\"`\nmvn install:install-file \\\n -Dfile=./libs/$FILE \\\n -DgroupId=com.cloudacademy \\\n -DartifactId=bitcoin-converter-svc-lib \\\n -Dversion=$VERSION \\\n -Dpackaging=jar\n\n#build and package console app\nmvn clean package\n\n#execute console app\njava -jar target/bitcoin-converter-client-1.0.0-SNAPSHOT-jar-with-dependencies.jar\n}\n```\n\n## GitHub Action - CICD\nThis project demonstrates how to use [GitHub Actions](https://github.com/cloudacademy/java-tdd-bitcoinconverter/tree/main/.github/workflows) to perform automated builds, testing, packaging, and releases.\n\n### dev.build.yml\n```\nname: Java CI Dev\n\non:\n  push:\n    branches: main\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v2\n\n      - name: JDK 1.11 Install\n        uses: actions/setup-java@v1\n        with:\n          java-version: 11\n\n      - name: Maven Build\n        run: |\n          mvn -B clean package\n          mkdir staging\n          cp target/*.jar staging\n\n      - name: Code Coverage\n        run: |\n          mvn -B jacoco:prepare-agent clean test jacoco:report coveralls:report -Dcoveralls.secret=${{ secrets.COVERALLS }}\n\n      - name: Artifact Upload\n        uses: actions/upload-artifact@v2\n        with:\n          name: Package\n          path: staging\n```\n\n### prod.build.yml\n```\nname: Java CI Prod\n\non:\n  push:\n    tags:\n      - '*'\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v2\n\n      - name: JDK 1.11 Install\n        uses: actions/setup-java@v1\n        with:\n          java-version: 11\n\n      - name: Maven Build\n        run: |\n          mvn versions:set -DremoveSnapshot\n          mvn -B clean package test\n          mkdir release\n          cp target/*.jar release\n\n      - name: Artifact Upload\n        uses: actions/upload-artifact@v2\n        with:\n          name: Package\n          path: release\n\n      - name: Make Release\n        uses: softprops/action-gh-release@v0.1.5\n        with:\n          files:\n            target/*.jar\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n```\n\n## Coveralls - Code Coverage Report\nThis project forwards its unit testing code coverage reports to [coveralls.io](https://coveralls.io/github/cloudacademy/java-tdd-bitcoinconverter) for report viewing and analysis.\n\n## Vagrant\nThe provided [Vagrantfile](https://github.com/cloudacademy/java-tdd-bitcoinconverter/blob/main/Vagrantfile) can be used to spin up an Ubuntu 18.04 instance, which is bootstrapped to install both OpenJDK 11 and Maven 3.6.3:\n\n```\n$bootstrap = \u003c\u003cSCRIPT\nexport DEBIAN_FRONTEND=noninteractive\nexport APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1\n\napt-get update\napt-get install -y tree\n\necho ========================\n\necho installing openjdk-11-jdk...\napt-get install -y openjdk-11-jdk\n\necho ========================\n\necho installing LATEST maven ...\ncd /tmp\nLATEST_SEMVER=$(curl -s https://repo1.maven.org/maven2/org/apache/maven/maven/maven-metadata.xml \\\n| grep \"\u003cversion\u003e3.*\u003c/version\u003e\" \\\n| tr -s \" \" \\\n| cut -d \"\u003e\" -f2 \\\n| cut -d \"\u003c\" -f1 \\\n| sort -V -r \\\n| head -1)\nLATEST_SEMVER=${LATEST_SEMVER:=3.9.3} # default to 3.9.3 if not detected in previous step\necho downloading https://dlcdn.apache.org/maven/maven-3/$LATEST_SEMVER/binaries/apache-maven-$LATEST_SEMVER-bin.tar.gz ...\ncurl -OLs --output /dev/null https://dlcdn.apache.org/maven/maven-3/$LATEST_SEMVER/binaries/apache-maven-$LATEST_SEMVER-bin.tar.gz\ntar xf /tmp/apache-maven-*.tar.gz -C /opt\nln -s /opt/apache-maven-$LATEST_SEMVER /opt/maven\ncat \u003c\u003cEOF \u003e\u003e /etc/profile.d/maven.sh\nexport JAVA_HOME=/usr/lib/jvm/java-1.11.0-openjdk-amd64\nexport M2_HOME=/opt/maven\nexport MAVEN_HOME=/opt/maven\nexport PATH=/opt/maven/bin:${PATH}\nEOF\nchmod +x /etc/profile.d/maven.sh\nsource /etc/profile.d/maven.sh\n\necho ========================\n\necho finished ...\nSCRIPT\n\nVagrant.configure(\"2\") do |config|\n  config.vm.box = \"ubuntu/bionic64\"\n  config.vm.provision \"shell\", inline: $bootstrap\nend\n```\n\nUse the following Vagrant command to launch the instance:\n\n```\nvagrant up\n```\n\nThen SSH into the instance by running the following command:\n\n```\nvagrant ssh\n```\n\nTo confirm that both the OpenJDK 11 JDK and Maven 3.6.3 have been installed successfully by the boostrapping, run the following command:\n\n```\njava -version\nmvn -version\n```\n\nBack on your local workstation, you can use Visual Studio Code or any other editor to open and modify the contents of the current folder - with all changes being automatically synced back into the ```/vagrant``` directory within the Vagrant instance.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudacademy%2Fjava-tdd-bitcoinconverter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloudacademy%2Fjava-tdd-bitcoinconverter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudacademy%2Fjava-tdd-bitcoinconverter/lists"}