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

chore(build): integrate ecommerce commons library #5

Merged
merged 14 commits into from
Aug 7, 2023
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ hs_err_pid*
build
/.gradle
.env
/checkouts/*
7 changes: 5 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
FROM amazoncorretto:17-alpine AS build
FROM openjdk:17-jdk as build
WORKDIR /workspace/app

RUN microdnf install git

COPY gradlew .
COPY gradle gradle
COPY build.gradle.kts .
COPY settings.gradle.kts .
COPY gradle.lockfile .
COPY gradle.properties .
COPY pagopa-ecommerce-commons-maven-install.sh .

COPY eclipse-style.xml eclipse-style.xml
COPY src src
COPY api-spec api-spec
RUN ./gradlew build -x test
RUN ./gradlew build -x test -PbuildCommons
RUN mkdir build/extracted && java -Djarmode=layertools -jar build/libs/*.jar extract --destination build/extracted

FROM amazoncorretto:17-alpine
Expand Down
251 changes: 250 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,254 @@
# PagoPA Ecommerce Helpdesk Service
# PagoPA Help desk service

pietro-tota marked this conversation as resolved.
Show resolved Hide resolved
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=pagopa_pagopa-ecommerce-helpdesk-service&metric=alert_status)](https://sonarcloud.io/dashboard?id=pagopa_pagopa-ecommerce-helpdesk-service)

This microservice is responsible for ...

- [PagoPA Help Desk Service](#pagopa-helpdesk-service)
* [Api Documentation 📖](#api-documentation-)
pietro-tota marked this conversation as resolved.
Show resolved Hide resolved
* [Technology Stack](#technology-stack)
* [Start Project Locally 🚀](#start-project-locally-)
+ [Prerequisites](#prerequisites)
+ [Run docker container](#run-docker-container)
* [Develop Locally 💻](#develop-locally-)
+ [Prerequisites](#prerequisites-1)
+ [Run the project](#run-the-project)
+ [Install ecommerce commons library](#install-ecommerce-commons-library-locally)
+ [Testing 🧪](#testing-)
- [Unit testing](#unit-testing)
- [Integration testing](#integration-testing)
- [Performance testing](#performance-testing)
* [Dependency management 🔧](#dependency-management-)
+ [Dependency lock](#dependency-lock)
+ [Dependency verification](#dependency-verification)
* [Contributors 👥](#contributors-)
+ [Maintainers](#maintainers)

<small><i><a href='http://ecotrust-canada.github.io/markdown-toc/'>Table of contents generated with
markdown-toc</a></i></small>

---

## Api Documentation 📖

See
the [OpenAPI 3 here.](https://editor.swagger.io/?url=https://raw.githubusercontent.com/pagopa/pagopa-ecommerce-helpdesk-service/main/api-spec/openapi.yaml)

---

## Technology Stack

- Kotlin
- Spring Boot

---

## Start Project Locally 🚀

### Prerequisites

- docker

### Populate the environment

The microservice needs a valid `.env` file in order to be run.

If you want to start the application without too much hassle, you can just copy `.env.example` with

```shell
$ cp .env.example .env
```

to get a good default configuration.

If you want to customize the application environment, reference this table:

| Variable name | Description | type | default |
|--------------------------------|-------------------------------------------------------------------|-------------------|---------|
| MONGO_HOST | Host where MongoDB instance used to persist wallet data | hostname (string) | |
| MONGO_PORT | Port where MongoDB is bound to in MongoDB host | number | |
| MONGO_USERNAME | MongoDB username used to connect to the database | string | |
| MONGO_PASSWORD | MongoDB password used to connect to the database | string | |
| MONGO_SSL_ENABLED | Whether SSL is enabled while connecting to MongoDB | string | |

### Run docker container

```shell
$ docker compose up --build
```

---

## Develop Locally 💻

### Prerequisites

- git
- gradle
- jdk-17
- ecommerce-commons library installed into maven local folder

### Run the project

```shell
$ ./gradlew bootRun
```

### Install ecommerce commons library locally

pietro-tota marked this conversation as resolved.
Show resolved Hide resolved
Into gradle build file have been added a task that take cares for you of proper ecommerce-commons library build,
performing ecommerce-commons repository clone, checkout to the referred version and build (using maven).

pietro-tota marked this conversation as resolved.
Show resolved Hide resolved
If you want to re-build ecommerce commons library you can run build command with the `-PbuildCommons` argument

pietro-tota marked this conversation as resolved.
Show resolved Hide resolved
This two properties maps ecommerce commons version and ref branch:

pietro-tota marked this conversation as resolved.
Show resolved Hide resolved
````
val ecommerceCommonsVersion = "x.y.z" -> valued with ecommerce commons wanted pom version
val ecommerceCommonsRef = ecommerceCommonsVersion -> the branch/tag to be checkout.
````

`ecommerceCommonsRef` is, by default, valued with the ecommerce commons library version, causing tagged version to be
checkout.

pietro-tota marked this conversation as resolved.
Show resolved Hide resolved
This value was left as a separate property because, during developing phases can be changed to a feature branch
making the local build use a ref branch other than a tag for developing purpose.

```Shell
$ ./gradlew build -PbuildCommons
```

Running the above command the version above task will run before project compilation building ecommerce commons locally inside maven local repository

pietro-tota marked this conversation as resolved.
Show resolved Hide resolved
### Testing 🧪

#### Unit testing

To run the **Junit** tests:

```shell
$ ./gradlew test
```

#### Integration testing

TODO

#### Performance testing

install [k6](https://k6.io/) and then from `./performance-test/src`

1. `k6 run --env VARS=local.environment.json --env TEST_TYPE=./test-types/load.json main_scenario.js`

### Dependency management 🔧

For support reproducible build this project has the following gradle feature enabled:

- [dependency lock](https://docs.gradle.org/8.1/userguide/dependency_locking.html)
- [dependency verification](https://docs.gradle.org/8.1/userguide/dependency_verification.html)

#### Dependency lock

This feature use the content of `gradle.lockfile` to check the declared dependencies against the locked one.

If a transitive dependencies have been upgraded the build will fail because of the locked version mismatch.

The following command can be used to upgrade dependency lockfile:

```shell
./gradlew dependencies --write-locks
```

Running the above command will cause the `gradle.lockfile` to be updated against the current project dependency
configuration

#### Dependency verification

This feature is enabled by adding the gradle `./gradle/verification-metadata.xml` configuration file.

Perform checksum comparison against dependency artifact (jar files, zip, ...) and metadata (pom.xml, gradle module
metadata, ...) used during build
and the ones stored into `verification-metadata.xml` file raising error during build in case of mismatch.

The following command can be used to recalculate dependency checksum:

```shell
./gradlew --write-verification-metadata sha256 clean spotlessApply build
```

In the above command the `clean`, `spotlessApply` `build` tasks where chosen to be run
in order to discover all transitive dependencies used during build and also the ones used during
spotless apply task used to format source code.

The above command will upgrade the `verification-metadata.xml` adding all the newly discovered dependencies' checksum.
Those checksum should be checked against a trusted source to check for corrispondence with the library author published
checksum.

`/gradlew --write-verification-metadata sha256` command appends all new dependencies to the verification files but does
not remove
entries for unused dependencies.

This can make this file grow every time a dependency is upgraded.

To detect and remove old dependencies make the following steps:

1. Delete, if present, the `gradle/verification-metadata.dryrun.xml`
2. Run the gradle write-verification-metadata in dry-mode (this will generate a verification-metadata-dryrun.xml file
leaving untouched the original verification file)
3. Compare the verification-metadata file and the verification-metadata.dryrun one checking for differences and removing
old unused dependencies

The 1-2 steps can be performed with the following commands

```Shell
rm -f ./gradle/verification-metadata.dryrun.xml
./gradlew --write-verification-metadata sha256 clean spotlessApply build --dry-run
```

The resulting `verification-metadata.xml` modifications must be reviewed carefully checking the generated
dependencies checksum against official websites or other secure sources.

If a dependency is not discovered during the above command execution it will lead to build errors.

You can add those dependencies manually by modifying the `verification-metadata.xml`
file adding the following component:

```xml

<verification-metadata>
<!-- other configurations... -->
<components>
<!-- other components -->
<component group="GROUP_ID" name="ARTIFACT_ID" version="VERSION">
<artifact name="artifact-full-name.jar">
<sha256 value="sha value"
origin="Description of the source of the checksum value"/>
</artifact>
<artifact name="artifact-pom-file.pom">
<sha256 value="sha value"
origin="Description of the source of the checksum value"/>
</artifact>
</component>
</components>
</verification-metadata>
```

Add those components at the end of the components list and then run the

```shell
./gradlew --write-verification-metadata sha256 clean spotlessApply build
```

that will reorder the file with the added dependencies checksum in the expected order.

Finally, you can add new dependencies both to gradle.lockfile writing verification metadata running

```shell
./gradlew dependencies --write-locks --write-verification-metadata sha256
```

For more information read the
following [article](https://docs.gradle.org/8.1/userguide/dependency_verification.html#sec:checksum-verification)

## Contributors 👥

Expand Down
20 changes: 16 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,16 @@ plugins {
application
}

java.sourceCompatibility = JavaVersion.VERSION_17
val ecommerceCommonsVersion = "0.19.5"

val ecommerceCommonsRef = ecommerceCommonsVersion
pietro-tota marked this conversation as resolved.
Show resolved Hide resolved

tasks.withType<KotlinCompile> { kotlinOptions.jvmTarget = "17" }
java.sourceCompatibility = JavaVersion.VERSION_17

repositories { mavenCentral() }
repositories {
mavenCentral()
mavenLocal()
}

dependencyManagement {
imports { mavenBom("org.springframework.boot:spring-boot-dependencies:3.0.5") }
Expand Down Expand Up @@ -63,6 +68,7 @@ dependencies {
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
implementation("it.pagopa:pagopa-ecommerce-commons:$ecommerceCommonsVersion")

// ECS logback encoder
implementation("co.elastic.logging:logback-ecs-encoder:$ecsLoggingVersion")
Expand Down Expand Up @@ -164,8 +170,14 @@ tasks.register(
)
}

tasks.register<Exec>("install-commons") {
val buildCommons = providers.gradleProperty("buildCommons")
onlyIf("To build commons library run gradle build -PbuildCommons") { buildCommons.isPresent }
giovanniberti marked this conversation as resolved.
Show resolved Hide resolved
commandLine("sh", "./pagopa-ecommerce-commons-maven-install.sh", ecommerceCommonsRef)
}

tasks.withType<KotlinCompile> {
dependsOn("helpdesk")
dependsOn("helpdesk", "install-commons")
kotlinOptions.jvmTarget = "17"
}

Expand Down
Loading
Loading