# lambda-nr-ownership-ingest

Lambda for NR Ownership Ingestion

## Requirements
* yarn
* AWS credentials (using awsume if building locally using Docker)
* Install [docker](https://docs.docker.com/get-docker/) desktop for Mac.

## Building with Docker

Building and testing the lambda requires a `GITHUB_TOKEN` for installing TS packages from the Github monorepo.

If you want to build the image locally you will need to stage the `GITHUB_TOKEN` secret in `.env` and run the following command:

```shell
DOCKER_BUILDKIT=1 docker build --secret id=github_token,env=GITHUB_TOKEN -t <lambda_name_tag> .
```
This will create an image locally that you could push to the AWS Dev account ECR.
A `yarn` command is available to run the same command and will tag the container with the `tag` provided in the `package.json` config:
example:
```json
    "config": {
        "name": "lambda-nr-ownership-ingest-participant-deduplicator",
        "tag": "nr-ownership-ingest-participant-deduplicator"
    }
```

The yarn command `dev:docker:build` will essentially run
```shell
DOCKER_BUILDKIT=1 docker build --no-cache --secret id=tokens,src=.env -t $npm_package_config_tag .
```

You can also build the container with `docker-compose`
```shell
docker-compose build --no-cache function
```
The `--no-cache` flag is optional, creating a fresh image from scratch. 

The `setup.sh` script will:

* source the staged secrets by BuildKit `source /run/secrets/tokens`
* generate `.npmrc` file
* run `yarn install --frozen-lockfile`
* delete .npmrc

## Running

### AWS Credentials
If the lambda in question is using the Split client, or interacting with S3 or DynamoDB, you will need to provide AWS credentials to the container.
Run `awsume <env>` in your shell before running the container. `awsume` will set your AWS credentials as environment variables and the `docker-compose` file will pass them to the container as environment variables.
```Dockerfile
    environment:
      - AWS_ACCESS_KEY_ID
      - AWS_SECRET_ACCESS_KEY
      - AWS_SESSION_TOKEN
      - AWS_REGION
```

### Start Container
```
$ docker-compose up function
```

You also have the option to build and run using one command - `yarn start` which runs `docker-compose up --build -d function`.


### Execute Function
If using Docker, use the HTTP client of your choice. The body of the request is the `event` passed into the function.

```sh
curl --request POST \
  --url http://localhost:9000/2015-03-31/functions/function/invocations \
  --header 'Content-Type: application/json' \
  --data '{}'
```

If not using Docker, the `yarn dev:local:run` can also be used to run the lambda code.

### Load Changes

Given that the TS files are compiled in the container, loading changes requires recompiling the TS files and restarting the function. There is an attempt to use `nodemon` and restart the container when the source changes but its not working quite right yet.

## Deploy to AWS Dev
First you need to make sure that you have a container repository. You can use `Terraform` to create one
or simply create it in the UI. The repository name should be the lambda name, found in `package.json`, example:
`lambda-nr-ownership-ingest-participant-deduplicator`.

You can now login to the AWS Dev account and push the image to ECR using `awsume`.
`awsume dev`.

Run `yarn dev:docker:build` to build the image.
Run `yarn dev:docker:push` to push the image to ECR.

Assuming you have already created your lambda function in the AWS Dev account, you can now update the lambda with the new image.
```shell
yarn dev:lambda:update
```

## Linting and Testing
It's fine running the lint and test tasks directly on your local machine.
```sh
yarn
yarn test // which runs yarn:test:unit && yarn lint
```
However, we are using Docker on Jenkins to run the tests and linting.
The `lint-and-test` service will run the `yarn test` command which runs the linter and the unit tests. 

### Run Container
```sh
$ docker-compose up --build lint-and-test
```

### Capture Exit Code
Unless the container itself crashes, or is killed, the exit code will be `0`. 
The exit code of `yarn test` matters, and we need to use it in Jenkins to reflect the status of tests and linting tasks.
The following snippet should be used in the Jenkins shell block of the `pull request`, `unit-test-and-lint`, and `integration-tests` jobs.
```sh
$ docker-compose up --exit-code-from lint-and-test --abort-on-container-exit --build lint-and-test
```

### Jenkins Pipeline
Make sure you have the following in the Jenkins shell block
```shell
set +x
cd lambda/${LAMBDA_DIR}
printf "GITHUB_TOKEN=${GITHUB_TOKEN}" > .env
docker compose run --rm --build lint-and-test
rm -f .env
```
* `set +x` is used to stop printing the commands in the console.
* `cd lambda/${LAMBDA_DIR}` is used to change the directory to the lambda directory that is changed in the PR.
* `docker compose build --no-cache lint-and-test` is used to build the `lint-and-test` container.
* `docker compose up --exit-code-from lint-and-test --abort-on-container-exit --build lint-and-test` is used to run the `lint-and-test` container and capture the exit code.
* `rm -f .env` is used to remove the `.env` file that contains the `GITHUB_TOKEN` secret from the workspace.
