Skip to content
Closed
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
53 changes: 46 additions & 7 deletions .github/workflows/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,56 @@ on:

jobs:
ci:
uses: PedroHenriques/ci_cd_workflow_templates/.github/workflows/ci_dotnet_package.yml@v1
uses: PedroHenriques/ci_cd_workflow_templates/.github/workflows/ci_docker.yml@v1
with:
environment: "dev"
deployable_branch_name: 'main'
source_dir_name: 'src'
deployment_file-or-dir_path: 'build.txt'
manifest_dir_name: 'Infrastructure'
custom_service_file_pattern: '*.csproj'
build_file_pattern: 'build.txt'
major_version_label_name: 'major'
minor_version_label_name: 'minor'
patch_version_label_name: 'patch'
build_file_pattern: 'Dockerfile'
deploy_all_services_label_name: 'deploy all services'
skip_heavy_tests: ${{ github.event_name == 'pull_request' && github.event.action == 'closed' }}
target_frameworks: '["net8.0", "net9.0", "net10.0"]'
secrets: inherit

# cd-dev:
# needs: ci
# if: ${{ github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true && github.base_ref == 'main' }}
# uses: PedroHenriques/ci_cd_workflow_templates/.github/workflows/cd_docker.yml@v1
# with:
# environment: "dev"
# source_dir_name: 'src'
# manifest_dir_name: 'Infrastructure'
# custom_service_file_pattern: '*.csproj'
# build_file_pattern: 'Dockerfile'
# img_tag: ${{ needs.ci.outputs.img_tag }}
# deploy_all_services_label_name: 'deploy all services'
# secrets: inherit

# cd-qa:
# needs: [ci, cd-dev]
# if: ${{ github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true && github.base_ref == 'main' }}
# uses: PedroHenriques/ci_cd_workflow_templates/.github/workflows/cd_docker.yml@v1
# with:
# environment: "qua"
# source_dir_name: 'src'
# manifest_dir_name: 'Infrastructure'
# custom_service_file_pattern: '*.csproj'
# build_file_pattern: 'Dockerfile'
# img_tag: ${{ needs.ci.outputs.img_tag }}
# deploy_all_services_label_name: 'deploy all services'
# secrets: inherit

# cd-prd:
# needs: [ci, cd-qa]
# if: ${{ github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true && github.base_ref == 'main' }}
# uses: PedroHenriques/ci_cd_workflow_templates/.github/workflows/cd_docker.yml@v1
# with:
# environment: "prd"
# source_dir_name: 'src'
# manifest_dir_name: 'Infrastructure'
# custom_service_file_pattern: '*.csproj'
# build_file_pattern: 'Dockerfile'
# img_tag: ${{ needs.ci.outputs.img_tag }}
# deploy_all_services_label_name: 'deploy all services'
# secrets: inherit
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## YYYY-MM-DD

### Added

- Initial version of the application
58 changes: 32 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
# .Net Toolkit
The .Net Toolkit is split into multiple packages:
- **Base .Net Toolkit**: Intended to be used in non Asp.Net application
- **Asp.Net Toolkit**: Intended to be used in Asp.Net application
# Your application name
Your application brief description.

## Main functionalities
- Handles setting up the connections with MongoDb, Redis, Kafka and LaunchDarkly
- Exposes functionality to perform most operations on this tech stack while abstracting the implementation details of each technology
- Standardizes the interactions with this tech stack across all the applications that use this package
- Reduces the cost of evolving the interaction with this tech stack across all the applications
## Applications wiki

[Link to applications wiki](https://wiki.com/something)

**Note:** This package does not intend to completely abstract, from the application, the technology being used.
The application will still need to interact with some data types from the underlying technologies.
## Main functionalities
- Store data in the schema you want
- API to create, update and delete entities and their data
- Register entities (Ex: countries, holidays, stores, etc.)
- Manage the data of each registered entity
- Register notifications for an entity
- Every change made to a data point of an entity can trigger notifications to 1 or many destinations
- Use this to notify other applications that need to know when data changes
- Supported destinations:
- Kafka topic
- HTTP(S) webhook

# Application Architecture
[more information here](/documentation/architecture.md)

# Technical information
For detailed information about each package look at:
| Package | Documentation |
| ----------- | ----------- |
| Base .Net Toolkit | [doc](/src/Toolkit/README.md) |
| Asp.Net Toolkit | [doc](/src/Toolkit.Asp/README.md) |
## Stack
This application uses the following technologies:
- C# .Net
- MongoDb
- Redis

The application also interacts with the following technologies:
- Kafka

# Developer information
## Requisites
Expand Down Expand Up @@ -57,8 +65,7 @@ The available services are declared in the local environment Docker compose proj
This will run a Docker compose project and start several networked Docker containers will all the services and necessary tools to use the application.

The following services will be running in the containers:
- 1 MongoDb instance
- 1 Redis single node instances
- List your services here
- Confluent community edition Kafka Broker
- Confluent Schema Registry
- A GUI for MongoDb
Expand Down Expand Up @@ -102,20 +109,19 @@ Accept the T&C and submit to enter.
![alt text](documentation/redis_tec.png)

Add the following databases:<br>
`redis://default:password@redis:6379`<br>
`redis://default:password@api_redis:6379`<br>

`Kafka GUI`: [http://localhost:9002](http://localhost:9002)<br>
**NOTES:**<br>
Add a topic with the name `myTestTopicJson` with, at least, 1 partition.
Register the `myTestTopicJson-key` and `myTestTopicJson-value` schemas, using the contents of the files `setup/local/tester_kafka_json_schema_key.json` and `setup/local/tester_kafka_json_schema_value.json`, respectively.
Add a topic with the name `myTestTopicAvro` with, at least, 1 partition.
Register the `myTestTopicAvro-key` and `myTestTopicAvro-value` schemas, using the contents of the files `setup/local/tester_kafka_avro_schema_key.json` and `setup/local/tester_kafka_avro_schema_value.json`, respectively.
Add a topic with the name `myTestTopic` with, at least, 1 partition.
Register the `myTestTopic-key` and `myTestTopic-value` schemas, using the contents of the files `setup/local/myTestTopic_schema_key.json` and `setup/local/myTestTopic_schema_value.json`, respectively and the type `JSON`.

`Kibana`: [http://localhost:9003](http://localhost:9003)

`Test API`: [http://localhost:10000](http://localhost:10000)<br>
`API`: [http://localhost:10000](http://localhost:10000)<br>
Use the Postman collection at `setup/local/XPTO.postman_collection` to interact with the application.

`Test API Swagger UI`: [http://localhost:10000/swagger](http://localhost:10000/swagger)
`API Swagger UI`: [http://localhost:10000/swagger](http://localhost:10000/swagger)

### Stop the local environment
From the root of the project run the command
Expand Down Expand Up @@ -152,7 +158,7 @@ Whitespace separated list of test `.csproj` to run.

**NOTES:**<br>
- When running the tests with the flags `--docker` or `--cicd`, the tests will run inside a Docker container that will be in the `myapp_shared` network.
- When running the script with the flags `--integration` or `--e2e` the flag `--docker` is assumed as well, which means the tests will run inside a Docker container.
- When running the script with the flags ``--integration` or `--e2e` the flag `--docker` is assumed as well, which means the tests will run inside a Docker container.
- You can use the `setup/local/.env.test` file to define envrionment variables to be used when starting the local development environment to be used for integration and E2E tests.

### Generating test coverage reports
Expand Down
2 changes: 1 addition & 1 deletion cli/external_static_analysis.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
RUNNING_IN_PIPELINE=0;

while [ "$#" -gt 0 ]; do
case "$1" in

Check failure on line 11 in cli/external_static_analysis.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add a default case (*) to handle unexpected values.

See more on https://sonarcloud.io/project/issues?id=PedroHenriques_dotnet_toolkit&issues=AZ67wvVXPTI3RoldkLP2&open=AZ67wvVXPTI3RoldkLP2&pullRequest=473
--docker) USE_DOCKER=1; shift 1;;
--cicd) RUNNING_IN_PIPELINE=1; USE_DOCKER=1; shift 1;;
--target-lang) shift 2;;
Expand Down Expand Up @@ -37,7 +37,7 @@
fi

TEST_COVERAGE_PATH="./test/**/${TEST_COVERAGE_FILE_NAME}";
CMD="dotnet tool restore && dotnet sonarscanner begin /k:"${EXTERNAL_STATIC_ANALYSIS_PROJ_KEY}" /o:"${EXTERNAL_STATIC_ANALYSIS_ORG}" /d:sonar.token="${EXTERNAL_STATIC_ANALYSIS_TOKEN}" /d:sonar.host.url="${EXTERNAL_STATIC_ANALYSIS_HOST}" /d:sonar.cs.opencover.reportsPaths="${TEST_COVERAGE_PATH}" /d:sonar.projectBaseDir=/app /d:sonar.exclusions=**/bin/**,**/obj/**,setup/**,app/setup/** /d:sonar.coverage.exclusions=setup/**,app/setup/** ${EXTRA_OPTS} /d:sonar.qualitygate.wait=${SONAR_QG_WAIT} /d:sonar.qualitygate.timeout=${SONAR_QG_TIMEOUT_SEC} && dotnet build -p:UseLocalToolkit=true && chmod +x ./cli/test.sh && ./cli/test.sh --coverage && dotnet sonarscanner end /d:sonar.token="${EXTERNAL_STATIC_ANALYSIS_TOKEN}"";
CMD="dotnet tool restore && dotnet sonarscanner begin /k:"${EXTERNAL_STATIC_ANALYSIS_PROJ_KEY}" /o:"${EXTERNAL_STATIC_ANALYSIS_ORG}" /d:sonar.token="${EXTERNAL_STATIC_ANALYSIS_TOKEN}" /d:sonar.host.url="${EXTERNAL_STATIC_ANALYSIS_HOST}" /d:sonar.cs.opencover.reportsPaths="${TEST_COVERAGE_PATH}" /d:sonar.projectBaseDir=/app /d:sonar.exclusions=**/bin/**,**/obj/**,setup/**,app/setup/** /d:sonar.coverage.exclusions=setup/**,app/setup/** ${EXTRA_OPTS} /d:sonar.qualitygate.wait=${SONAR_QG_WAIT} /d:sonar.qualitygate.timeout=${SONAR_QG_TIMEOUT_SEC} && dotnet build && chmod +x ./cli/test.sh && ./cli/test.sh --coverage && dotnet sonarscanner end /d:sonar.token="${EXTERNAL_STATIC_ANALYSIS_TOKEN}"";

if [ $USE_DOCKER -eq 1 ]; then
INTERACTIVE_FLAGS="-it";
Expand Down
2 changes: 1 addition & 1 deletion cli/start_elk.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ export COMPOSE_PROFILES;

docker network create myapp_shared || true;

docker compose -f setup/local/docker-compose.elk.yml -p myapp_elk up --no-build "$@";
docker compose -f setup/local/docker-compose.elk.yml -p myapp_elk up --no-build "$@";
2 changes: 1 addition & 1 deletion cli/stop.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ export COMPOSE_PROFILES;

docker compose -f setup/local/docker-compose.yml -p myapp down;
docker compose -f setup/local/docker-compose.elk.yml -p myapp_elk down;
docker system prune -f --volumes;
docker system prune -f --volumes;
7 changes: 3 additions & 4 deletions cli/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
WATCH=0;
PROJ="";
FILTERS="";
DOTNET_FRAMEWORK="net10.0";
USE_DOCKER=0;
RUNNING_IN_PIPELINE=0;
RUN_LOCAL_ENV=0;
Expand All @@ -17,7 +16,7 @@
--docker) USE_DOCKER=1; shift 1;;
--cicd) RUNNING_IN_PIPELINE=1; USE_DOCKER=1; shift 1;;
--filter) FILTERS="--filter ${2}"; shift 2;;
--target-lang) DOTNET_FRAMEWORK="${2}"; shift 2;;
--target-lang) shift 2;;
--unit) FILTERS="--filter Type=Unit"; TEST_TYPE="unit"; shift 1;;
--integration) FILTERS="--filter Type=Integration"; TEST_TYPE="integration"; RUN_LOCAL_ENV=1; USE_DOCKER=1; shift 1;;
--e2e) FILTERS="--filter Type=E2E"; TEST_TYPE="e2e"; RUN_LOCAL_ENV=1; USE_DOCKER=1; shift 1;;
Expand All @@ -28,7 +27,7 @@
esac
done

case "${TEST_TYPE}" in

Check failure on line 30 in cli/test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add a default case (*) to handle unexpected values.

See more on https://sonarcloud.io/project/issues?id=PedroHenriques_dotnet_toolkit&issues=AZ67wvRQPTI3RoldkLP0&open=AZ67wvRQPTI3RoldkLP0&pullRequest=473
"unit")
if [ ! -d "./test/unit/" ]; then
echo "No './test/unit/' directory found. Assuming no unit tests exist.";
Expand Down Expand Up @@ -100,7 +99,7 @@

ATTEMPTS=$((ATTEMPTS+1));
if [ ${ATTEMPTS} -ge ${MAX_RETRIES} ]; then
echo "ERROR: Some services failed to become ready:";

Check warning on line 102 in cli/test.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Redirect this error message to stderr (>&2).

See more on https://sonarcloud.io/project/issues?id=PedroHenriques_dotnet_toolkit&issues=AZ67wvRQPTI3RoldkLP1&open=AZ67wvRQPTI3RoldkLP1&pullRequest=473
echo "${BAD_CONTAINERS}";
echo "Recent logs (last 200 lines each):";
docker compose -f "${COMPOSE_FILE}" -p "${PROJECT_NAME}" logs --tail=200;
Expand All @@ -113,14 +112,14 @@
docker network create myapp_shared || true;
fi

CMD="dotnet test ${PROJ} -f ${DOTNET_FRAMEWORK} ${FILTERS} ${COVERAGE}";
CMD="dotnet test ${PROJ} ${FILTERS} ${COVERAGE}";

if [ $WATCH -eq 1 ]; then
if [ -z "$PROJ" ]; then
echo "In watch mode a project name or path must be provided as argument." >&2; exit 1;
fi

CMD="dotnet watch -q --project ${PROJ} test -f ${DOTNET_FRAMEWORK} --no-restore ${FILTERS}";
CMD="dotnet watch -q --project ${PROJ} test --no-restore ${FILTERS}";
fi

if [ $USE_DOCKER -eq 1 ]; then
Expand Down
Loading
Loading