Skip to content

Commit

Permalink
Enhance documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
QubitPi committed Sep 1, 2023
1 parent c4d7a5d commit 12553b2
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 188 deletions.
29 changes: 17 additions & 12 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,28 +143,33 @@ jobs:
tags: ${{ secrets.DOCKERHUB_USERNAME }}/jersey-ws-template:latest

hashicorp:
name: Publish Jersey WS AMI Image and Deploy it to EC2 through HashiCorp
name: Generated Webservice WAR in GitHub Action, and Publish Template AMI Image and Deploy it to EC2 through HashiCorp
if: ${{ github.event.repository.name != 'jersey-ws-template' }}
needs: tests
runs-on: ubuntu-latest
defaults:
run:
working-directory: hashicorp
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Load deployment environment variables into Terraform variable file
run: |
touch instances/variables.auto.tfvars
echo 'zone_id = "${{ secrets.ZONE_ID }}"' > instances/variables.auto.tfvars
echo 'sentry_dsn = "${{ secrets.SENTRY_DSN }}"' >> instances/variables.auto.tfvars
- name: Load SSL Certificates
- name: Set up JDK ${{ env.JDK_VERSION }}
uses: actions/setup-java@v3
with:
java-version: ${{ env.JDK_VERSION }}
distribution: ${{ env.JDK_DISTRIBUTION }}
- name: Generate webservice WAR file
run: mvn -B clean package
- name: Load SSL Certificates into AMI
working-directory: hashicorp/images
run: |
echo '${{ secrets.SSL_CERTIFICATE }}' > server.crt
echo '${{ secrets.SSL_CERTIFICATE_KEY }}' > server.key
- name: Publish Jersey WS AMI image and deploy it to EC2 through HashiCorp
uses: QubitPi/hashicorp-aws@master
- name: Load runtime settings into Terraform variable file
working-directory: hashicorp/instances
run: |
touch variables.auto.tfvars
echo 'zone_id = "${{ secrets.ZONE_ID }}"' > variables.auto.tfvars
echo 'sentry_dsn = "${{ secrets.SENTRY_DSN }}"' >> variables.auto.tfvars
- name: Push AMI and Deploy EC2
uses: QubitPi/aergia@master
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
Expand Down
52 changes: 30 additions & 22 deletions docs/docs/ci-cd.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,6 @@ title: CI/CD

![Error loading ci-cd.png](./img/ci-cd.png)

:::caution

[Never use SonarCloud Caching](https://github.com/paion-data/astraios/pull/9), otherwise the dependency injection will
get screwed up. i.e. The following snippet will never go to GitHub Action script

```xml
- name: Cache SonarCloud packages
uses: actions/cache@v1
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Cache Maven packages
uses: actions/cache@v1
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
```

:::

The following [GitHub Secrets][How to set up GitHub Action Secrets] needs to be defined

- [**SONAR_TOKEN**](https://sonarcloud.io/project/overview?id=QubitPi_jersey-ws-template)
Expand Down Expand Up @@ -64,6 +42,36 @@ The following [GitHub Secrets][How to set up GitHub Action Secrets] needs to be
- Update `"EC2 Instance Name"` and `"Security Group Name"` in [Terraform config file][HashiCorp Terraform config file]
accordingly

### JPA through Elide

- **APPLICATION_PROPERTIES** The _application.properties_ file content that will be put under _src/main/resources/_
directory by CI/CD
- **JPADATASTORE_PROPERTIES** The _jpadatastore.properties_ file content that will be put under _src/main/resources/_
directory

Note that if model package is from an internal Maven repo which requires authentication, we can insert a _settings.xml_
generating step using [create-mvn-settings]. For example:

```yml
hashicorp:
name: Generated Webservice WAR in GitHub Action, and Publish Template AMI Image and Deploy it to EC2 through HashiCorp
needs: tests
runs-on: ubuntu-latest
steps:
...

- name: Generate Maven settings.xml
uses: ./.github/actions/create-mvn-settings
with:
internal-maven-repo-server-id: ${{ secrets.INTERNAL_MAVEN_REPO_SERVER_ID }}
internal-maven-repo-user: ${{ secrets.INTERNAL_MAVEN_REPO_USER }}
internal-maven-repo-token: ${{ secrets.INTERNAL_MAVEN_REPO_TOKEN }}

...
```

[create-mvn-settings]: https://github.com/QubitPi/jersey-ws-template/blob/jpa-elide/.github/actions/create-mvn-settings/action.yml

[docker hub]: https://hub.docker.com/r/jack20191124/jersey-ws-template/

[HashiCorp Packer template]: https://github.com/QubitPi/jersey-ws-template/blob/master/hashicorp/images/aws-jersey-ws.pkr.hcl
Expand Down
53 changes: 4 additions & 49 deletions docs/docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,11 @@ sidebar_position: 3
title: Development
---

Running Webservice in Docker Compose
------------------------------------

### Defining Data Models

Jersey WS Template can run in [Docker Compose] for the following purposes

1. Decoupling frontend and backend development
2. Easily integrating application backed by Jersey WS Template testing in CI/CD

![Error Loading docker-compose.png](./img/docker-compose.png)

```bash
git clone https://github.com/QubitPi/jersey-ws-template.git
cd jersey-ws-template
git checkout jpa-elide
mvn clean package
MODEL_PACKAGE_NAME=$JWT_MODEL_PACKAGE_NAME docker compose up --build --force-recreate
```

where `$JWT_MODEL_PACKAGE_NAME` is the package in config JAR that contains all
[elide models](https://elide.io/pages/guide/v7/02-data-model.html). It can be set, for example, at command line with:

```bash
export JWT_MODEL_PACKAGE_NAME=com.mycompany.jwt.models
```

The variable will be [passed](https://stackoverflow.com/a/58900415) into Docker Compose file.

### Troubleshooting

#### Database Does Not Contain Model Packages's Bean Table

_If tests is running in IDE_, make sure the model package JAR it is in IDE's **External Libraries**

Running Tests
-------------

The following commands runs both unit and integration tests

```bash
mvn clean verify
```
Expand All @@ -55,7 +22,7 @@ Packaging
mvn clean package
```

A [**WAR** file](https://en.wikipedia.org/wiki/WAR_(file_format)) named `jersey-ws-template-1.0-SNAPSHOT.war` will
A [WAR file](https://en.wikipedia.org/wiki/WAR_(file_format)) named **jersey-ws-template-1.0-SNAPSHOT.war** will
be generated under _target_ directory for [running in Jetty](#running-in-standalone-jetty)

Running Webservice in Standalone Jetty (Production)
Expand All @@ -64,13 +31,7 @@ Running Webservice in Standalone Jetty (Production)
### Download Jetty

At [download page](https://www.eclipse.org/jetty/download.php), pick up a `.tgz` distribution. **It is very important
to pick up Jetty server version that matches JDK version**. For JDK **17**, it's been tested that Jetty _11.0.15_ works

:::note

During testing, the embedded Jetty version is also 11.0.15

:::
to pick up Jetty server version that matches JDK version**. For JDK **17**, it's been tested that Jetty _11.0.15_ worked

Hence, we will use "11.0.15" release as an example:

Expand Down Expand Up @@ -110,12 +71,6 @@ Lastly, drop the [WAR file](#packaging) into **/path/to/jetty-base/webapps** dir
mv /path/to/war-file /path/to/jetty-base/webapps/ROOT.war
```

### Configuring Webservice

#### Define Model Package

#### Set Application Properties

### Running Webservice

```bash
Expand Down
107 changes: 74 additions & 33 deletions docs/docs/elide.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
---
sidebar_position: 6
title: Elide Middleware
title: JPA through Elide Middleware
---

Template can delegate JPA persistence to [Elide].

Configuring Elide requires 2 [bindings][what is binding]:
[Jersey Webservice Template] (_JWT_) delegates JPA capabilities to [Elide] and configures Elide through 2 required
Elide [bindings][what is binding]:

1. **[Elide][Elide instance class]**
2. **[ElideSettings][ElideSettings instance class]** with 2 extra sub-bindings:
Expand All @@ -15,66 +14,110 @@ Configuring Elide requires 2 [bindings][what is binding]:

The binding is referencing [Elide Standalone] in the following way:

:::danger

Although the Jersey binder wraps HK2 binder, we
[must pick the _Jersey binder_ for binding Elide resources](https://github.com/QubitPi/jersey-ws-template/pull/29/files#diff-afa024cc2643aaf681db505cac24b8601c94931290718993392e7726001b1559L39-R40),
otherwise, dependency injection will flaky and not right.

:::

![Error loading resource-binding.png](./img/resource-binding.png)

To inject Elide model package, simply put the models in a separate JAR and include it as a dependency in POM. If the
model package is internal and cannot be visible publicly, either make the webservice project private or public with
env variable masking, for example:
Running Webservice in Docker Compose
------------------------------------

### Step 1: Defining Data Models

To inject [Elide model package](https://github.com/yahoo/elide/tree/master/elide-standalone#create-models), simply put
the models in a separate JAR and include it as a dependency in POM. If the model package is internal and cannot be
visible publicly, either make the webservice project private or public with env variable masking, for example:

```xml
<dependencies>
<dependency>
<groupId>${env.MODEL_PACKAGE_JAR_GROUP_ID}</groupId>
<artifactId>${env.MODEL_PACKAGE_JAR_ARTIFACT_ID}</artifactId>
<version>${env.MODEL_PACKAGE_JAR_VERSION}</version>
</dependency>
</dependencies>
<dependencies>
<dependency>
<groupId>${env.MODEL_PACKAGE_JAR_GROUP_ID}</groupId>
<artifactId>${env.MODEL_PACKAGE_JAR_ARTIFACT_ID}</artifactId>
<version>${env.MODEL_PACKAGE_JAR_VERSION}</version>
</dependency>
</dependencies>

...

<repositories>
<repository>
<id>${env.MODEL_PACKAGE_REPO_ID}</id>
<name>JPA model pacakge JAR repository</name>
<url>${env.MODEL_PACKAGE_REPO_URL}</url>
</repository>
</repositories>
```

```bash
export MODEL_PACKAGE_JAR_GROUP_ID=com.mycompnay
export MODEL_PACKAGE_JAR_ARTIFACT_ID=my-model-package
export MODEL_PACKAGE_JAR_VERSION=1.0.7

export MODEL_PACKAGE_REPO_ID=my-repo-id
export MODEL_PACKAGE_REPO_URL=https://private.mvnrepository.com/artifact/com.company/my-model-package
```

### Step 2: Spinning Up Docker Compose

Jersey WS Template can run in [Docker Compose] for the following purposes

1. Decoupling frontend and backend developments
2. Making it easy to run E2E testing of Jersey WS Template-backed application in CI/CD

:::caution

The jetty-base should be initialized with
Docker Compose designed here is intended for local development and testing purposes ONLY! _It is strongly discouraged
to run this Docker Compose in production!_

:::

![Error Loading docker-compose.png](./img/docker-compose.png)

Simply run:

```bash
java -jar $JETTY_HOME/start.jar --add-module=annotations,server,http,deploy,servlet,webapp,resources,jsp,websocket
git clone https://github.com/QubitPi/jersey-ws-template.git
cd jersey-ws-template
git checkout jpa-elide
mvn clean package
MODEL_PACKAGE_NAME=$JWT_MODEL_PACKAGE_NAME docker compose up --build --force-recreate
```

In addition, before running webservice, the environment variable **MODEL_PACKAGE_NAME** must be set. For example:
where `$JWT_MODEL_PACKAGE_NAME` is the package in config JAR that contains all
[elide models](https://elide.io/pages/guide/v7/02-data-model.html). It can be set, for example, at command line with:

```bash
export MODEL_PACKAGE_NAME=com.mycompnay.models
export JWT_MODEL_PACKAGE_NAME=com.mycompany.jwt.models
```

:::
The variable will be [passed](https://stackoverflow.com/a/58900415) into Docker Compose file.

Example POST via JSON API:
### Troubleshooting

```bash
curl -X POST http://localhost:8080/v1/data/EntityType \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-d '{"data": {"type": "EntityType", "id": "elide-demo"}}'
```
#### Database Does Not Have My Model Packages's Bean Table

Troubleshooting
---------------
_If tests is running in IntelliJ IDE_, make sure the model package JAR it is in IDE's **External Libraries**

Otherwise, the dependency injection didn't find a bean class under the package specified by
[JWT_MODEL_PACKAGE_NAME](#step-1-defining-data-models)

### Entity Missing Default Constructor

```bash
13:17:52.396 [main] INFO o.h.m.i.EntityInstantiatorPojoStandard - HHH000182: No default (no-argument) constructor for
[main] INFO o.h.m.i.EntityInstantiatorPojoStandard - HHH000182: No default (no-argument) constructor for
class: ... (class must be instantiated by Interceptor)
```

Simply add a no-args constructor to the bean class.

### How to Exclude GraphQL Feature

To optionally disable GraphQL endpoints, simply exclude corresponding dependencies in POM. For example:
To optionally disable GraphQL endpoints, exclude corresponding dependencies in POM. For example:

```xml
<dependency>
Expand All @@ -90,13 +133,11 @@ To optionally disable GraphQL endpoints, simply exclude corresponding dependenci
</dependency>
```

[BinderFactory]: https://github.com/QubitPi/jersey-ws-template/blob/jpa-elide/src/main/java/com/qubitpi/ws/jersey/template/application/BinderFactory.java

[Elide]: https://elide.io/
[Elide instance class]: https://github.com/yahoo/elide/blob/master/elide-core/src/main/java/com/yahoo/elide/Elide.java
[Elide Standalone]: https://github.com/yahoo/elide/tree/master/elide-standalone
[ElideSettings instance class]: https://github.com/yahoo/elide/blob/master/elide-core/src/main/java/com/yahoo/elide/ElideSettings.java

[ResourceConfig]: https://github.com/QubitPi/jersey-ws-template/blob/jpa-elide/src/main/java/com/qubitpi/ws/jersey/template/application/ResourceConfig.java
[Jersey Webservice Template]: https://qubitpi.github.io/jersey-ws-template/

[what is binding]: https://qubitpi.github.io/jersey/ioc.html
Loading

0 comments on commit 12553b2

Please sign in to comment.