Skip to content
This repository has been archived by the owner on Aug 18, 2023. It is now read-only.

Commit

Permalink
Merge pull request #29 from alb2k/develop
Browse files Browse the repository at this point in the history
Release 1.0.8
  • Loading branch information
alb2k authored Jun 27, 2021
2 parents 63decf5 + 50c851a commit b611dfe
Show file tree
Hide file tree
Showing 21 changed files with 374 additions and 32 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/checkBuild.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ jobs:
- uses: actions/checkout@v2

- name: Set up JDK 11
uses: actions/setup-java@v1
uses: actions/setup-java@v2
with:
java-version: 11.x
distribution: 'adopt'

- name: Cache local Maven repository
uses: actions/cache@v2
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ jobs:
- uses: actions/checkout@v2

- name: Set up JDK 11
uses: actions/setup-java@v1
uses: actions/setup-java@v2
with:
java-version: 11.x
distribution: 'adopt'

- name: Cache local Maven repository
uses: actions/cache@v2
Expand Down
29 changes: 29 additions & 0 deletions .github/workflows/deployDockerHubDevelop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Deploy develop to DockerHub

on:
workflow_dispatch:
push:
branches: [ develop ]
paths-ignore:
- '**.md'

jobs:
build_publish_docker:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Generate tag vars
id: tagvars
run: |
echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
echo "::set-output name=build_datetime::$(date -u +%Y%m%d-%H%M)"
- name: Builder Dockerimage and publish to Registry
uses: elgohr/Publish-Docker-Github-Action@master
with:
name: alb2k/fuel-filling-service
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
tags: "develop"
3 changes: 2 additions & 1 deletion .github/workflows/gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ jobs:
- uses: actions/checkout@v2

- name: Setup - Java
uses: actions/setup-java@v1
uses: actions/setup-java@v2
with:
java-version: 11.0.x
distribution: 'adopt'

- name: Restore - Maven Cache
uses: actions/cache@v2
Expand Down
23 changes: 22 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ jobs:
- uses: actions/checkout@v2

- name: Set up JDK 11
uses: actions/setup-java@v1
uses: actions/setup-java@v2
with:
java-version: 11.x
distribution: 'adopt'

- name: Cache local Maven repository
uses: actions/cache@v2
Expand Down Expand Up @@ -66,6 +67,26 @@ jobs:
asset_name: release.zip
asset_content_type: application/octet-stream

build_publish_docker:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Generate tag vars
id: tagvars
run: |
echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
echo "::set-output name=build_datetime::$(date -u +%Y%m%d-%H%M)"
- name: Builder Dockerimage and publish to Registry
uses: elgohr/Publish-Docker-Github-Action@master
with:
name: alb2k/fuel-filling-service
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
tags: "latest,master-${{ steps.tagvars.outputs.sha_short }}-${{ steps.tagvars.outputs.build_datetime }}"

after_release:
runs-on: ubuntu-latest
needs: [build_release_jar]
Expand Down
30 changes: 22 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,37 @@ A helidon (microprofile) RESTful webservice with microstream.
The project represents a basic CRUD webservice where you can manage fuel fillings (of a car).<br>
It is also shipped with a nice UI (openapi-ui) so that no external REST/HTTP client is required.

This project was created for the [Microstream hackathon](https://hackathon.microstream.one/)

### Used technologies
* [Microstream](https://microstream.one/platforms/microstream-for-java/)
* [Helidon MP](https://helidon.io/#getting-started)
* [Microprofile (config)](https://github.com/eclipse/microprofile-config)
* [Helidon MP](https://helidon.io/#getting-started)
* [MP Health](https://github.com/eclipse/microprofile-health)
* Logging via [SLF4J](http://www.slf4j.org/) and [Apache Log4j 2](https://logging.apache.org/log4)
* [OpenApi](https://www.openapis.org/)
* [OpenApi-UI](https://swagger.io/tools/swagger-ui/)
* [GitHub Actions](https://github.com/features/actions) for CI/CD
* [Heroku](https://www.heroku.com/) for hosting the demo

### [Documentation in detail](docs/README.md)
Documentation about this project is [available here](docs/README.md)

## [Demo](https://hackathon-ms-fuel-filling.herokuapp.com) [![Deployment Status](https://img.shields.io/github/workflow/status/alb2k/fuel-filling-service/Deploy%20CI?label=deployment)](https://github.com/alb2k/fuel-filling-service/actions/workflows/deploy.yml)
The demo is hosted on heroku.
The demo is hosted on heroku.<br>
It may take some seconds to start.

![openapi-ui screenshot](assets/OpenApiUI.png)

* [OpenAPI-UI (redirection)](https://hackathon-ms-fuel-filling.herokuapp.com)
* [OpenAPI](https://hackathon-ms-fuel-filling.herokuapp.com/openapi)
* [Health](https://hackathon-ms-fuel-filling.herokuapp.com/health)

## Download [![Release Status](https://img.shields.io/github/workflow/status/alb2k/fuel-filling-service/Release%20CI?label=release)](https://github.com/alb2k/fuel-filling-service/actions/workflows/release.yml)
There are prebuilt executables, which save you from building the executable locally.

### JAR
* Check if you have Java 11 installed, if not [install it](https://adoptopenjdk.net/?variant=openjdk11&jvmVariant=hotspot)
* Download the [latest zip from the releases](https://github.com/alb2k/fuel-filling-service/releases/latest)
* Unzip it and run it locally with ``java -jar fuel-filling-service.jar``
* Download the [latest zip from the releases](https://github.com/alb2k/fuel-filling-service/releases/latest) and unzip it
* Run ``java -jar fuel-filling-service.jar``
* Open http://localhost:8080
→ you should get redirected to the OpenAPI UI

Expand Down Expand Up @@ -60,9 +66,17 @@ Requirements:
Requirements:
* Docker

#### "Normal" Dockerfile
#### Running the prebuilt image from DockerHub [![Latest docker version](https://img.shields.io/badge/docker-latest-%232684ff)](https://hub.docker.com/r/alb2k/fuel-filling-service/tags?name=latest&page=1) [![Develop docker version](https://img.shields.io/badge/docker-develop-%232684ff)](https://hub.docker.com/r/alb2k/fuel-filling-service/tags?name=develop&page=1)
* Run the latest release using ``docker run --rm -p 8080:8080 --name fuel-filling alb2k/fuel-filling-service``
* Stop/Remove it with ``docker stop fuel-filling``

#### Building and running it
* Build the image with ``docker build -t fuel-filling .``
* Execute it with ``docker run --rm -p 8080:8080 --name fuel-filling fuel-filling``
* Stop/Remove it with ``docker stop fuel-filling``

### Dependencies and Licenses [![dependency overview](https://img.shields.io/badge/dependency--overview-online-success?logo=apache-maven)](https://alb2k.github.io/fuel-filling-service/dependencies/) [![Apache License 2.0](https://img.shields.io/github/license/alb2k/fuel-filling-service?color=informational)](https://choosealicense.com/licenses/apache-2.0/)
## Dependencies and Licenses [![dependency overview](https://img.shields.io/badge/dependency--overview-online-success?logo=apache-maven)](https://alb2k.github.io/fuel-filling-service/dependencies/) [![Apache License 2.0](https://img.shields.io/github/license/alb2k/fuel-filling-service?color=informational)](https://choosealicense.com/licenses/apache-2.0/)
For the license of this project, check the [LICENSE file](LICENSE)<br>
A summary of all dependencies and their licenses is also available [online](https://alb2k.github.io/fuel-filling-service/dependencies/)

This project was created for the [Microstream hackathon](https://hackathon.microstream.one/)
11 changes: 11 additions & 0 deletions docs/GHActions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# GitHub Actions

The following plans are used:
| Plan | Runs when | Description |
| --- | --- | --- |
| [checkBuild.yml](../.github/workflows/checkBuild.yml) | Push or PullRequest on develop | Checks if the project is buildable (using ``mvn -B clean package``) |
| [release.yml](../.github/workflows/release.yml) | Push on master | Builds a release jar and creates a new release draft on GitHub, where the jar is uploaded |
| [deploy.yml](../.github/workflows/deploy.yml) | Push on master | Deploys the current code to [Heroku](Heroku.md) |
| [gh-pages.yml](../.github/workflows/gh-pages.yml) | Push on master | Creates a [project-info-report about the dependencies](https://maven.apache.org/plugins/maven-project-info-reports-plugin/dependencies-mojo.html) and publishes it with [GitHub pages](https://pages.github.com/) |

Results of the executed workflows occur in the [``Actions`` tab](https://github.com/alb2k/fuel-filling-service/actions)
41 changes: 41 additions & 0 deletions docs/Helidon.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Helidon (Microprofile)

[Helidon MP](https://helidon.io/docs/latest/#/about/02_introduction) is a [collection of Java Libaries](https://alb2k.github.io/fuel-filling-service/dependencies/#Dependency_Tree) mainly used for Java/Jakarte EE conform web/microservices.<br>
This project is based on [helidon-quickstart-mp](https://github.com/oracle/helidon/tree/master/examples/quickstarts/helidon-quickstart-mp).

## Webservice
![Heldion_Overview.png](https://user-images.githubusercontent.com/80211953/113520281-34e32f80-9592-11eb-8ea8-6d5d118864b2.png)

The HTTP Webservice was done with [JAX-RS](https://en.wikipedia.org/wiki/Jakarta_RESTful_Web_Services) and other [Java/Jakarta EE technologies](https://en.wikipedia.org/wiki/Jakarta_EE) (see below).<br>
The "rest resources" (which represent the HTTP interface) are located in [src/main/java/hackathon/microstream/service/rest/resource](../src/main/java/hackathon/microstream/service/rest/resource).

The integrated webserver is the by default shipped [Helidon-Webserver](https://github.com/oracle/helidon/tree/master/webserver/webserver).

#### Validation
If entities are transmitted to a method they are validated (via the ``@Valid`` annotation) using [jersey-bean-validation](https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/bean-validation.html).<br>
When the validation fails, a ``ConstraintViolationException`` is thrown which is automatically processed by the [ConstraintViolationExceptionMapper](../src/main/java/hackathon/microstream/service/system/ConstraintViolationExceptionMapper.java) so that it results in a better readable exception:
```
Unrecognized token 'trues': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 7, column: 30]
```

#### Serialization
For the serialization from JSON to Java objects and back [com.fasterxml.jackson](https://github.com/FasterXML/jackson) is used.
This worked pretty good, however some tweaks had to be [applied to the defaults](../src/main/java/hackathon/microstream/service/system/ObjectMapperContextResolver.java):
* By default LocalDate is written as array, which is not [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) conform<br>
https://stackoverflow.com/a/28803634
* By default ObjectMapper throws an exception, if unknown properties are supplied.<br>
To be a bit less restrictive, unknown properties are allowed (easier handling of objects with / without UUID)

To also automatically serialize Java objects (to JSON) in a response without the need of doing it manually with an ObjectMapper [org.glassfish.jersey.media:jersey-media-json-jackson](https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-json-jackson) is used.<br>
More information [available here](https://stackoverflow.com/questions/26207252/messagebodywriter-not-found-for-media-type-application-json).

#### CDI
The corresponding [service](../src/main/java/hackathon/microstream/service/provider) is injected into the rest resource via CDI.

#### Microprofile
Furthermore the integrated webserver can be configured with microprofile.<br>
For example, the [``server.port`` can be set](../src/main/resources/META-INF/microprofile-config.properties#L4-L6).

#### Other tweaks
* When a entity is not found, a [``NotFoundException``](../src/main/java/hackathon/microstream/dal/util/NotFoundException.java) is thrown, which is automatically catched by the [``NotFoundExceptionHandler``](../src/main/java/hackathon/microstream/service/rest/errorhandling/NotFoundExceptionHandler.java)
74 changes: 74 additions & 0 deletions docs/Heroku.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Heroku deployment
The goal here was to deploy a demo online, so that you don't have to run the code locally and also have a showcase available.

I used [Heroku](https://www.heroku.com/home) once before with GitHub so I choose that as my cloud platform again.

## How to set it up
The setup is based on [this guide](https://dev.to/heroku/deploying-to-heroku-from-github-actions-29ej)

### Preparing Heroku
At first: You need to [setup an account](https://signup.heroku.com/)

TL;DR<br/>
Web applications on Heroku are called [web dynos](https://www.heroku.com/dynos).<br>
A [free tier account on Heroku](https://www.heroku.com/pricing) grants you 550 dyno hours (and additional 450 hours if you add your credit card).<br>
Your dyno will automatically sleep/shut down if there is no activity in the last 30 minutes.

After the account is set up, create a new app:
![Pic](https://user-images.githubusercontent.com/80211953/111872102-e4fb4a80-898d-11eb-8151-ab41ca7a23b7.png)
Choose your region, add a name (the app will be available under that ``https://<name>.herokuapp.com``) and then click create app.

### Deploying the project using GitHub
Great, now we have a new app on heroku... but there isn't actually anything running, because nothing was deployed.

So how can we deploy code (from GitHub)?<br>
There are 2 ways:
* Setup a deployment pipeline directly in Heroku
* Write a [GitHub actions](https://github.com/features/actions) workflow that builds and deploys the code

I wanted to stay independent from Heroku and - through the fact that I already had experience with GitHub Actions - I ultimately choose those.

#### Setting up secrets
There have to be some [secrets stored for the coming GitHub Actions workflow](https://docs.github.com/en/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-a-repository):
* ``HEROKU_APP_NAME``<br>
The app-name that is used on heroku e.g. ``hackathon-ms-fuel-filling``
* ``HEROKU_API_KEY``<br>
The API-Key so that the app can be deployed to heroku.<br>
The key can be generated via multiple methods.<br>
I recommend adding a new "authorization" (API-Key) using https://dashboard.heroku.com/account/applications#authorizations

#### Writing the workflow
Setup a new workflow and name it e.g. [deploy.yml](../.github/workflows/deploy.yml)

The workflow has to meet the following requirements:
* Executed the workflow when a new release is created or manually
* Build the app (as jar)
* Deploy the app to Heroku

The first two parts are pretty easy doable if you know a bit about GitHub Actions.<br>
The last part is a little bit more tricky:
* GitHub Actions own virtual (linux) machines are by default equipped with the Heroku CLI.<br>More details are available [here](https://github.com/actions/virtual-environments#available-environments)
* At first install [Heroku's Java plugin](https://github.com/heroku/plugin-java): ``heroku plugins:install java``
* Deploy the jar with the deploy command ``heroku deploy:jar``
* Select the jar using ``target/fuel-filling-service.jar``
* Set the JDK to Java 11 using ``--jdk 11``.<br> Heroku trys to deploy by default with JDK 8.
* The libs folder must be included: ``--includes target/libs/``
* Select the app that you want to deploy to with ``--app ${{ secrets.HEROKU_APP_NAME }}``
* Of course Heroku also needs some type of authentication. This is done using ``HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }}``

In the last 2 steps you noted the use of ``${{ secret.XXX }}``. <br>
This is the usage of the GitHub secrets we created before.

#### Using a Procfile
There is one special case when you want to use Heroku: You have to either expose your app on Port 80 or you have to bind to Herokus ``PORT`` environment variable.

This can be done easily using a [Procfile](/Procfile) in the repository root which contains ``-Dserver.port=$PORT``.

#### Deploying it
Great - now when everything was done correctly - you should be able to deploy it.<br>
Go to the ``Actions`` tab of your repository and run the Deployment workflow:
![Pic](https://user-images.githubusercontent.com/80211953/111875065-137e2300-8998-11eb-9819-f83c0e04cdbc.png)

After some time you should see that your app was deployed on Heroku.<br>
It is also useful to check the logs for problems and have a quick look at your app.
![Pic](https://user-images.githubusercontent.com/80211953/111875837-1418b880-899c-11eb-895e-81c62ba2e5d4.png)
Loading

0 comments on commit b611dfe

Please sign in to comment.