Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance documentation #31

Merged
merged 1 commit into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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