Skip to content

Commit

Permalink
Merge pull request #4 from pagopa/PRDP-237-recover-api-for-io-error-t…
Browse files Browse the repository at this point in the history
…o-notify-status

feat: PRDP-237 Add recover api IO_ERROR_TO_NOTIFY and GENERATED status
  • Loading branch information
pasqualespica authored Nov 28, 2023
2 parents 19ec8cb + 930f3e3 commit 0b6dec5
Show file tree
Hide file tree
Showing 16 changed files with 1,106 additions and 61 deletions.
151 changes: 128 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,147 @@
# pagoPA Functions template
# pagoPA Receipt-pdf-helpdesk

Java template to create an Azure Function.
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=pagopa_pagopa-receipt-pdf-helpdesk&metric=alert_status)](https://sonarcloud.io/dashboard?id=pagopa_pagopa-receipt-pdf-helpdesk)

## Function examples
There is an example of a Http Trigger function.
Java Azure Functions that exposed the following recover APIs:
- ReceiptToReviewed
- RecoverFailedReceipt
- RecoverNotNotifiedReceipt

---

## Run locally with Docker
`docker build -t pagopa-functions-template .`
## Summary 📖

`docker run -p 8999:80 pagopa-functions-template`
- [Api Documentation 📖](#api-documentation-)
- [Start Project Locally 🚀](#start-project-locally-)
* [Run locally with Docker](#run-locally-with-docker)
+ [Prerequisites](#prerequisites)
+ [Run docker container](#run-docker-container)
* [Run locally with Maven](#run-locally-with-maven)
+ [Prerequisites](#prerequisites-1)
+ [Set environment variables](#set-environment-variables)
+ [Run the project](#run-the-project)
* [Test](#test)
- [Develop Locally 💻](#develop-locally-)
* [Prerequisites](#prerequisites-2)
* [Testing 🧪](#testing-)
+ [Unit testing](#unit-testing)
+ [Integration testing](#integration-testing)
+ [Performance testing](#performance-testing)
- [Contributors 👥](#contributors-)
* [Maintainers](#maintainers)

### Test
`curl http://localhost:8999/example`
---

## Api Documentation 📖

See
the [OpenApi 3 here](https://editor.swagger.io/?url=https://raw.githubusercontent.com/pagopa/pagopa-receipt-pdf-helpdesk/main/openapi/openapi.json)

## Start Project Locally 🚀

### Run locally with Docker

#### Prerequisites

- docker

#### Set environment variables

`docker build -t pagopa-receip-pdf-helpdesk .`

`cp .env.example .env`

and replace in `.env` with correct values

#### Run docker container

then type :

`docker run -p 80:80 --env-file=./.env pagopa-receip-pdf-helpdesk`

### Run locally with Maven

#### Prerequisites

- maven

#### Set environment variables

## Run locally with Maven
On terminal type:

`cp local.settings.json.example local.settings.json`

then replace env variables with correct values
(if there is NO default value, the variable HAS to be defined)

| VARIABLE | USAGE | DEFAULT VALUE |
|----------------------------------------|---------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------:|
| `RECEIPT_QUEUE_CONN_STRING` | Connection string to the Receipt Queue | |
| `RECEIPT_QUEUE_TOPIC` | Topic name of the Receipt Queue | |
| `COSMOS_BIZ_EVENT_CONN_STRING` | Connection string to the BizEvent CosmosDB | |
| `COSMOS_BIZ_EVENT_SERVICE_ENDPOINT` | Endpoint to the BizEvent CosmosDB | |
| `COSMOS_BIZ_EVENT_DB_NAME` | Database name of the BizEvent database in CosmosDB | |
| `COSMOS_BIZ_EVENT_CONTAINER_NAME` | Container name of the BizEvent container in CosmosDB | |
| `COSMOS_RECEIPTS_CONN_STRING` | Connection string to the Receipt CosmosDB | |
| `COSMOS_RECEIPT_SERVICE_ENDPOINT` | Endpoint to the Receipt CosmosDB | |
| `COSMOS_RECEIPT_KEY` | Key to the Receipt CosmosDB | |
| `COSMOS_RECEIPT_DB_NAME` | Database name of the Receipt database in CosmosDB | |
| `COSMOS_RECEIPT_CONTAINER_NAME` | Container name of the Receipt container in CosmosDB | |
| `COSMOS_RECEIPT_ERROR_CONTAINER_NAME` | Container name of the Receipt-message-error container in CosmosDB | |
| `PDV_TOKENIZER_BASE_PATH` | PDV Tokenizer API base path | "https://api.uat.tokenizer.pdv.pagopa.it/tokenizer/v1" |
| `PDV_TOKENIZER_SEARCH_TOKEN_ENDPOINT` | PDV Tokenizer API search token endpoint | "/tokens/search" |
| `PDV_TOKENIZER_FIND_PII_ENDPOINT` | PDV Tokenizer API find pii endpoint | "/tokens/%s/pii" |
| `PDV_TOKENIZER_CREATE_TOKEN_ENDPOINT` | PDV Tokenizer API create token endpoint | "/tokens" |
| `PDV_TOKENIZER_SUBSCRIPTION_KEY` | API azure ocp apim subscription key | |
| `PDV_TOKENIZER_INITIAL_INTERVAL` | PDV Tokenizer initial interval for retry a request that fail with 429 status code | 200 |
| `PDV_TOKENIZER_MULTIPLIER` | PDV Tokenizer interval multiplier for subsequent request retry | 2.0 |
| `PDV_TOKENIZER_RANDOMIZATION_FACTOR` | PDV Tokenizer randomization factor for interval retry calculation | 0.6 |
| `PDV_TOKENIZER_MAX_RETRIES` | PDV Tokenizer max request retry | 3 |
| `TOKENIZER_APIM_HEADER_KEY` | Tokenizer APIM header key | x-api-key |
| `MAX_DATE_DIFF_MILLIS` | Difference in millis between the current time and the date from witch the receipts will be fetched in massive recover operation | 360000 |

> to doc details about AZ fn config
> see [here](https://stackoverflow.com/questions/62669672/azure-functions-what-is-the-purpose-of-having-host-json-and-local-settings-jso)

#### Run the project

`mvn clean package`

`mvn azure-functions:run`

### Test
`curl http://localhost:7071/example`

`curl http://localhost:8080/info`

---

## Develop Locally 💻

### Prerequisites

- git
- maven
- jdk-17

### Testing 🧪

#### Unit testing

To run the **Junit** tests:

`mvn clean verify`

#### Integration testing

#### Performance testing

---

## Contributors 👥

Made with ❤️ by PagoPa S.p.A.

## TODO
Once cloned the repo, you should:
- to deploy on standard Azure service:
- rename `deploy-pipelines-standard.yml` to `deploy-pipelines.yml`
- remove `helm` folder
- to deploy on Kubernetes:
- rename `deploy-pipelines-aks.yml` to `deploy-pipelines.yml`
- customize `helm` configuration
- configure the following GitHub action in `.github` folder:
- `deploy.yml`
- `sonar_analysis.yml`
### Maintainers

Configure the SonarCloud project :point_right: [guide](https://pagopa.atlassian.net/wiki/spaces/DEVOPS/pages/147193860/SonarCloud+experimental).
See `CODEOWNERS` file
160 changes: 160 additions & 0 deletions openapi/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,148 @@
}
}
]
},
"/recoverNotNotified": {
"put": {
"tags": [
"Receipts REST APIs"
],
"summary": "Recover a receipt, or group of, in IO_ERROR_TO_NOTIFY or GENERATED status",
"operationId": "recoverNotNotified",
"parameters": [],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NotNotifiedRecoveryRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Succesfull Calls.",
"headers": {
"X-Request-Id": {
"description": "This header identifies the call",
"schema": {
"type": "string"
}
}
},
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
}
},
"400": {
"description": "Bad request invalid input.",
"headers": {
"X-Request-Id": {
"description": "This header identifies the call",
"schema": {
"type": "string"
}
}
},
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
}
},
"401": {
"description": "Wrong or missing function key.",
"headers": {
"X-Request-Id": {
"description": "This header identifies the call",
"schema": {
"type": "string"
}
}
}
},
"404": {
"description": "Requested receipt not found.",
"headers": {
"X-Request-Id": {
"description": "This header identifies the call",
"schema": {
"type": "string"
}
}
},
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
}
},
"429": {
"description": "Too many requests.",
"headers": {
"X-Request-Id": {
"description": "This header identifies the call",
"schema": {
"type": "string"
}
}
}
},
"500": {
"description": "The requested receipts is not in a status that can be elaborated.",
"headers": {
"X-Request-Id": {
"description": "This header identifies the call",
"schema": {
"type": "string"
}
}
},
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
}
},
"default": {
"description": "Unexpected error.",
"headers": {
"X-Request-Id": {
"description": "This header identifies the call",
"schema": {
"type": "string"
}
}
}
}
},
"security": [
{
"ApiKey": []
}
]
},
"parameters": [
{
"name": "X-Request-Id",
"in": "header",
"description": "This header identifies the call, if not passed it is self-generated. This ID is returned in the response.",
"schema": {
"type": "string"
}
}
]
}
},
"components": {
Expand Down Expand Up @@ -260,6 +402,24 @@
}
}
},
"NotNotifiedRecoveryRequest": {
"type": "object",
"description": "The request body for recoverNotNotified API, at least one of generatedStatus or ioErrorToNotifyStatus must be true. The field eventId when not provided enable the massive operation",
"properties": {
"eventId": {
"type": "string",
"description": "Id of the event to start recovering (optional)"
},
"generatedStatus": {
"type": "boolean",
"description": "True to recover the receipts in GENERATED status, false otherwise"
},
"ioErrorToNotifyStatus": {
"type": "boolean",
"description": "True to recover the receipts in IO_ERROR_TO_NOTIFY status, false otherwise"
}
}
},
"ProblemJson": {
"type": "object",
"properties": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ private void getEvent(String eventId, ExecutionContext context,
bizEventToReceiptService.handleSendMessageToQueue(bizEvent, receipt);
if(receipt.getStatus() != ReceiptStatusType.NOT_QUEUE_SENT){
receipt.setStatus(ReceiptStatusType.INSERTED);
receipt.setInserted_at(System.currentTimeMillis());
receipt.setInsertedAt(System.currentTimeMillis());
receipt.setReasonErr(null);
receipt.setReasonErrPayer(null);
}
Expand Down
Loading

0 comments on commit 0b6dec5

Please sign in to comment.