Skip to content

Commit

Permalink
feature/es-phase-1 (#3648)
Browse files Browse the repository at this point in the history
* CUMULUS-3692: Update granules List endpoints to query postgres for basic queries (#3637)

* CUMULUS-3692:Granule list endpoint for basic postgres query

* CUMULUS-3694: Update granules List endpoints to query postgres - filter by field value (#3656)

* CUMULUS-3692:Granule list endpoint for basic postgres query

* refactor

* refactor

* typing

* add changelog entry

* skip search_after

* skip searchafter unit tests

* add granule list test

* rename

* refactor

* build query parameters

* update comment

* add field-mapping

* update jsdoc

* use type over interface,add log

* update test description

* build term/terms

* buildDbQueryParameters

* add unit test no terms search

* add doc

* rename

* add unit test

* add fields test

* add more unit tests

* support error.Error search

* fix lint

* rename functions

* ignore files

* add convert query unit tests

* add all types

* add unit test for fieldmapping types fix timestamp

* update timestamp test

* add multiple term field test

* ignore execution in granule list record

* CUMULUS-3689: Update Stats/Summary and Stats/Aggregate endpoints to use psql (#3659)

* first commit on new branch

* CHANGELOG change

* small fix

* PR feedback

* adding jsdoc + fixing spelling/grammar

* CUMULUS-3693: Update granules List endpoints to query postgres - range (#3660)

* add range query support

* CUMULUS-3695 - Update Granules endpoint to handle SortFields (#3663)

* first committ

* CHANGELOG change

* fixing sortQueryMethod

* simplifying code

* PR feedback

* merge conflicts + improving code

* small jsdoc fix

* PR feedback

* PR feedback

* PR feedback

* fixing test

* PR feedback

* PR feedback

* CUMULUS-3696: Update granules List endpoints to query postgres - match (#3674)

* add methods to convert terms,not,exists

* CUMULUS-3641 - Update Collections LIST endpoint to query Postgres basic  (#3681)

* reopening PR

* PR feedback

* small test fix

* small PR feedbacks

* adding new tests from match queries

* PR feedback/formatting

* temporary reversion to list endpoint for reconreport tests

* reverting changes

* adding logging

* more logging

* more logging

* removing logging + commenting reconrep test temp

* commenting out failing createReconReport spec

* removing comment

* reverting changes to reconReport test

* reverting previous change

* adding ts-check

* PR feedback

* PR feedback

* adding in test

* PR feedback fix

* PR feedback

* CUMULUS-3699 - Update collection List endpoints to query postgres - includeStats (#3688)

* first commit

* CHANGELOG

* fixing small things

* changes + fixes

* PR feedback

* splitting queries separately

* PR feedback

* PR feedback

* PR feedback

* CUMULUS-3639: Add support to db/CollectionSearch to retrieve active collections (#3693)

* CUMULUS-3639:Add support to db/CollectionSearch to retrieve active collections

* add test active collections

* add ts-check

* update /collections/active unit test

* test snyk

* fix field mapping

* parallel search and fix urlPath

* add cumulus-lp stack

* add limit 1 to subquery

* CUMULUS-3239 - Update Executions LIST endpoint to query Postgres basic (#3684)

* first commit

* adding changes

* storing changes

* updating progress

* linting + small fixes

* small fix

* changing timestamp to string in tests

* fixing timestamp

* commenting out tests failing in CI but not locally

* saving changes

* collection support

* adding async_ops support

* changing endpoint + tests

* fixing test

* uncommenting tests + adding var

* commenting out tests failing in CI but not locally

* adding parentArn support + changing tests

* added parentArn support + fixing tests

* small endpoint test fix

* Pr feedback + code improvements

* small CHANGELOG fix

* PR feedback

* PR feedback + linting

* PR feedback

* PR feedback

* fixing test

* fixing execution tests after removing asyncCumulusOPId from mapping

* PR feedback

* removed includeFullRecord from search classes

* PR feedback

* PR feedback

* reverting change

* fix changelog

* Cumulus 3640/3242- Update granule non-LIST endpoints and other granule related es queries to query postgres (#3727)

* removing granules

* fixing lint

* fixing test

* small change

* adding back in some deleted things

* removing more

* lint fix

* removing tests

* skipping execution search-by-granules tests

* skipping execution tests

* removing tests

* more removing

* adding in deleted test

* removing more

* adding back in needed code

* removing ES_HOST, query, and index from bulk_ops

* fixing bulk_ops tests

* adding back in ELK stack refs

* changing reconreports test to skip/adding back in getGranulesByPayload

* PR feedback

* adding back in skipped tests

* CHANGELOG

* PR feedback

* PR feedback' .
;

* PR feedback + syntax check

* adding back sort to write-granules test

* CUMULUS-3240: Remove Elasticsearch dependency from executions endpoints (#3723)

* CUMULUS-3240:Remove ElasticSearch dependency from Executions endpoints

* update test-executions

* remove es dependencies for execution

* update changelog

* fix lint and warning

* address PR feedback

* remove esClient from createExecutionRecords

* CUMULUS-3642: postgres query adjustment (#3731)

* estimate table row count

* add more indexes

* use count *

* fix test

* fix test

* fix lint and add file index

* add more index

* fix lint

* fix lint update test

* execution asyncOperationId is optional

* defautl stats last day

* fix granule patchByGranuleId put logic back

* vaccum tables

* update changelog

* remove sql script to another pr

* update changelog

* update active collection query

* Revert "update active collection query"

This reverts commit 88024c2.

* CUMULUS-3238: Remove ElasticSearch dependency from Collection POST, PUT, and DEL endpoints (#3746)

* first commit

* CHANGELOG change

* PR feedback

* PR feedback

* CUMULUS-3792: Add db indexes to improve search performance (#3751)

* CUMULUS-3792:Add table indexes to improve search performance

* fix changelog

---------

Co-authored-by: Naga Nages <66387215+Nnaga1@users.noreply.github.com>
Co-authored-by: Nate Pauzenga <npauzenga@gmail.com>
  • Loading branch information
3 people authored Aug 27, 2024
1 parent 311d0f8 commit 04845d7
Show file tree
Hide file tree
Showing 66 changed files with 5,874 additions and 2,977 deletions.
59 changes: 59 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,65 @@ All notable changes to this project will be documented in this file.

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

## [Unreleased]

### Breaking Changes

- This release includes `Replace ElasicSearch Phase 1` updates, we no longer save `collection/granule/execution` records to
ElasticSearch, the `collections/granules/executions` API endpoints are updated to perform operations on the postgres database.

### Migration Notes

#### CUMULUS-3792 Add database indexes. Please follow the instructions before upgrading Cumulus

- The updates in CUMULUS-3792 require a manual update to the postgres database in the production environment.
Please follow [Update Table Indexes for CUMULUS-3792]
(https://nasa.github.io/cumulus/docs/next/upgrade-notes/update_table_indexes_CUMULUS_3792)

### Replace ElasticSearch Phase 1

- **CUMULUS-3238**
- Removed elasticsearch dependency from collections endpoint
- **CUMULUS-3239**
- Updated `executions` list api endpoint and added `ExecutionSearch` class to query postgres
- **CUMULUS-3240**
- Removed Elasticsearch dependency from `executions` endpoints
- **CUMULUS-3639**
- Updated `/collections/active` endpoint to query postgres
- **CUMULUS-3640**
- Removed elasticsearch dependency from granules endpoint
- **CUMULUS-3641**
- Updated `collections` api endpoint to query postgres instead of elasticsearch except if `includeStats` is in the query parameters
- **CUMULUS-3642**
- Adjusted queries to improve performance:
- Used count(*) over count(id) to count rows
- Estimated row count for large tables (granules and executions) by default for basic query
- Updated stats summary to default to the last day
- Updated ExecutionSearch to not include asyncOperationId by default
- **CUMULUS-3688**
- Updated `stats` api endpoint to query postgres instead of elasticsearch
- **CUMULUS-3689**
- Updated `stats/aggregate` api endpoint to query postgres instead of elasticsearch
- Created a new StatsSearch class for querying postgres with the stats endpoint
- **CUMULUS-3692**
- Added `@cumulus/db/src/search` `BaseSearch` and `GranuleSearch` classes to
support basic queries for granules
- Updated granules List endpoint to query postgres for basic queries
- **CUMULUS-3693**
- Added functionality to `@cumulus/db/src/search` to support range queries
- **CUMULUS-3694**
- Added functionality to `@cumulus/db/src/search` to support term queries
- Updated `BaseSearch` and `GranuleSearch` classes to support term queries for granules
- Updated granules List endpoint to search postgres
- **CUMULUS-3695**
- Updated `granule` list api endpoint and BaseSearch class to handle sort fields
- **CUMULUS-3696**
- Added functionality to `@cumulus/db/src/search` to support terms, `not` and `exists` queries
- **CUMULUS-3699**
- Updated `collections` api endpoint to be able to support `includeStats` query string parameter
- **CUMULUS-3792**
- Added database indexes to improve search performance

## [v18.4.0] 2024-08-16

### Migration Notes
Expand Down
150 changes: 150 additions & 0 deletions docs/upgrade-notes/update-table-indexes-CUMULUS-3792.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
---
id: update_table_indexes_CUMULUS_3792
title: Update Table Indexes for CUMULUS-3792
hide_title: false
---

## Background

As part of the ElasticSearch removal efforts, Cumulus API endpoints which previously queried ElasticSearch
are being updated to query RDS instead. New database indexes are required to make RDS queries more efficient.

The updates will be automatically created as part of the bootstrap lambda function on deployment of the data-persistence module.

*In cases where the indexes are already applied, the updates will have no effect. If you have an existing index with the same definition
but a different name than the one we are creating, you can rename your existing index to the new index name.*

## Apply the Changes in Production Environment

With a large database (e.g. number of rows in executions table is greater than 100,000), the indexes must be applied manually since
the commands can take a significant amount of time and exceed the bootstrap lambda's 15 minute timeout.

## Tools Used

Since the update commands can take a few hours to run based on table size and IO throughput, it is recommended that the commands are run in an EC2 instance
in the AWS environment in a tmux or screen session. This will minimize the number of network hops and potential disconnects between the database client
and the database. Additionally, this will allow operators applying the patch to check on progress periodically and not worry about credential expiration or
other issues that would result in the client being killed.

## Upgrade Steps

1. Login into EC2 instance with database access

From AWS console: Go to EC2, pick a `<prefix>-CumulusECSCluster` instance, click Connect, click Session Manager
and click the Connect button.

From AWS CLI: aws ssm start-session --target `EC2 Instance ID`.

:::note Remember to take a note on which instance you run the commands.

2. Install tmux and postgres client

```sh
sudo yum install -y tmux
sudo amazon-linux-extras install postgresql13
```

Once installed, a tmux session is started with two windows, the Cumulus database is connected to each window
using the PostgreSQL client. The primary window is used for running the `CREATE INDEX` commands, while the secondary
window is used to monitor the database and `CREATE INDEX` statement. The tmux session can be detached from and
reattached to at a later time.

3. Run SQL commands

The database login credentials can be retrieved from the prefix_db_login secret.
When the SQL commands are running, perform step 5 to monitor the commands.

```sh
tmux new-session -s CumulusUpgrade -n AddIndexes
psql -h <Endpoint for writer instance> -p <Port for database or 5432> -d <cumulus database name> -U <database admin user> -W
#e.g. psql -h cumulus-dev-rds-cluster.cluster-xxx.us-east-1.rds.amazonaws.com -p 5432 -d cumulus_test_db -U cumulus_test -W
# Use -f option to run the SQL commands from a file, -o option to write output to file
psql -h <Endpoint for writer instance> -p <Port for database or 5432> -d <cumulus database name> -U <database admin user> -f 20240728101230_add_table_indexes.sql -W
```

The following are SQL commands, and 20240728101230_add_table_indexes.sql is available
[here](https://raw.githubusercontent.com/nasa/cumulus/master/packages/db/src/migrations/20240728101230_add_table_indexes.sql):

```sql
SELECT CURRENT_TIMESTAMP;
CREATE INDEX CONCURRENTLY IF NOT EXISTS async_operations_updated_at_index ON async_operations(updated_at);
SELECT CURRENT_TIMESTAMP;
CREATE INDEX CONCURRENTLY IF NOT EXISTS async_operations_status_operation_type_cumulus_id_index ON async_operations(status, operation_type, cumulus_id);
SELECT CURRENT_TIMESTAMP;
CREATE INDEX CONCURRENTLY IF NOT EXISTS collections_updated_at_index ON collections(updated_at);
SELECT CURRENT_TIMESTAMP;
CREATE INDEX CONCURRENTLY IF NOT EXISTS executions_updated_at_index ON executions(updated_at);
SELECT CURRENT_TIMESTAMP;
CREATE INDEX CONCURRENTLY IF NOT EXISTS executions_status_collection_cumulus_id_index ON executions(status, collection_cumulus_id, cumulus_id);
SELECT CURRENT_TIMESTAMP;
CREATE INDEX CONCURRENTLY IF NOT EXISTS files_updated_at_index ON files(updated_at);
SELECT CURRENT_TIMESTAMP;
CREATE INDEX CONCURRENTLY IF NOT EXISTS granules_updated_at_index ON granules(updated_at);
SELECT CURRENT_TIMESTAMP;
CREATE INDEX CONCURRENTLY IF NOT EXISTS granules_coll_status_processendtime_cumulus_id_index ON granules(collection_cumulus_id, status, processing_end_date_time, cumulus_id);
SELECT CURRENT_TIMESTAMP;
CREATE INDEX CONCURRENTLY IF NOT EXISTS granules_status_provider_collection_cumulus_id_index ON granules(status, provider_cumulus_id, collection_cumulus_id, cumulus_id);
SELECT CURRENT_TIMESTAMP;
CREATE INDEX CONCURRENTLY IF NOT EXISTS pdrs_updated_at_index ON pdrs(updated_at);
SELECT CURRENT_TIMESTAMP;
CREATE INDEX CONCURRENTLY IF NOT EXISTS pdrs_status_provider_collection_cumulus_id_index ON pdrs(status, provider_cumulus_id, collection_cumulus_id, cumulus_id);
SELECT CURRENT_TIMESTAMP;
CREATE INDEX CONCURRENTLY IF NOT EXISTS pdrs_execution_cumulus_id_index ON pdrs(execution_cumulus_id);
SELECT CURRENT_TIMESTAMP;
CREATE INDEX CONCURRENTLY IF NOT EXISTS pdrs_coll_status_cumulus_id_index ON pdrs(collection_cumulus_id, status, cumulus_id);
SELECT CURRENT_TIMESTAMP;
CREATE INDEX CONCURRENTLY IF NOT EXISTS pdrs_provider_collection_cumulus_id_name_index ON pdrs(provider_cumulus_id, collection_cumulus_id, name);
SELECT CURRENT_TIMESTAMP;
CREATE INDEX CONCURRENTLY IF NOT EXISTS providers_updated_at_index ON providers(updated_at);
SELECT CURRENT_TIMESTAMP;
CREATE INDEX CONCURRENTLY IF NOT EXISTS rules_updated_at_index ON rules(updated_at);
SELECT CURRENT_TIMESTAMP;
VACUUM (ANALYZE, VERBOSE) async_operations;
SELECT CURRENT_TIMESTAMP;
VACUUM (ANALYZE, VERBOSE) collections;
SELECT CURRENT_TIMESTAMP;
VACUUM (ANALYZE, VERBOSE) executions;
SELECT CURRENT_TIMESTAMP;
VACUUM (ANALYZE, VERBOSE) files;
SELECT CURRENT_TIMESTAMP;
VACUUM (ANALYZE, VERBOSE) granules;
SELECT CURRENT_TIMESTAMP;
VACUUM (ANALYZE, VERBOSE) pdrs;
SELECT CURRENT_TIMESTAMP;
VACUUM (ANALYZE, VERBOSE) providers;
SELECT CURRENT_TIMESTAMP;
VACUUM (ANALYZE, VERBOSE) rules;
SELECT CURRENT_TIMESTAMP;
```

4. Monitor the running command

```sh
# From tmux CumulusUpgrade session, open another window
Ctrl-b c
psql -h <Endpoint for writer instance> -p <Port for database or 5432> -d <cumulus database name> -U <database admin user> -W
select pid, query, state, wait_event_type, wait_event from pg_stat_activity where state = 'active';
```
5. Verify the updates
We can verify that the tables are updated successfully by checking the `\d tablename` results from psql, the indexes created should be listed.
If the concurrent index query fails for any reason, you may have an `invalid` index - if this occurs,
make sure to drop and create the index again to avoid resources being used for the invalid index.
6. Close the session
Close the tmux session after the task is complete by `exit` or `Ctrl-b x`.
12 changes: 11 additions & 1 deletion example/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ cumulus-sit:
apiUsername: jasmine
pdrNodeNameProviderBucket: cumulus-sit-pdr-node-name-provider

cumulus-es:
bucket: cumulus-sit-internal
apiUsername: jasmine
pdrNodeNameProviderBucket: cumulus-sit-pdr-node-name-provider

cumulus-lp:
bucket: cumulus-sit-internal
apiUsername: jasmine
pdrNodeNameProviderBucket: cumulus-sit-pdr-node-name-provider

mvd-tf:
bucket: mvd-internal

Expand Down Expand Up @@ -39,4 +49,4 @@ nnaga-tf:
bucket: nnaga-internal

ecarton:
bucket: ecarton-internal
bucket: ecarton-internal
3 changes: 3 additions & 0 deletions example/deployments/cumulus/cumulus-es.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
prefix = "cumulus-es"
archive_api_port = 8000
key_name = "lp"
3 changes: 3 additions & 0 deletions example/deployments/cumulus/cumulus-lp.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
prefix = "cumulus-lp"
archive_api_port = 8000
key_name = "lp"
1 change: 0 additions & 1 deletion example/deployments/cumulus/sit.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ launchpad_api = "https://api.launchpad.nasa.gov/icam/api/sm/v1"
launchpad_certificate = "launchpad.pfx"

oauth_user_group = "GSFC-Cumulus-Dev"
cmr_oauth_provider = "earthdata"

saml_idp_login = "https://auth.launchpad-sbx.nasa.gov/affwebservices/public/saml2sso"
saml_launchpad_metadata_url = "https://auth.launchpad-sbx.nasa.gov/unauth/metadata/launchpad-sbx.idp.xml"
Expand Down
1 change: 1 addition & 0 deletions example/deployments/data-persistence/cumulus-es.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
prefix = "cumulus-es"
1 change: 1 addition & 0 deletions example/deployments/data-persistence/cumulus-lp.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
prefix = "cumulus-lp"
1 change: 1 addition & 0 deletions example/deployments/db-migration/cumulus-es.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
prefix = "cumulus-es"
1 change: 1 addition & 0 deletions example/deployments/db-migration/cumulus-lp.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
prefix = "cumulus-lp"
1 change: 1 addition & 0 deletions example/spec/helpers/granuleUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ const waitForGranuleRecordUpdatedInList = async (stackName, granule, additionalQ
'beginningDateTime',
'endingDateTime',
'error',
'execution', // TODO remove after CUMULUS-3698
'files', // TODO -2714 this should be removed
'lastUpdateDateTime',
'productionDateTime',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,6 @@ describe('When there are granule differences and granule reconciliation is run',
await s3().putObject({ Body: 'delete-me', ...extraS3Object });

extraCumulusCollection = await createActiveCollection(config.stackName, config.bucket);

const testId = createTimestampedTestId(config.stackName, 'CreateReconciliationReport');
testSuffix = createTestSuffix(testId);
testDataFolder = createTestDataPath(testId);
Expand Down Expand Up @@ -428,7 +427,8 @@ describe('When there are granule differences and granule reconciliation is run',
if (beforeAllFailed) fail(beforeAllFailed);
});

describe('Create an Inventory Reconciliation Report to monitor inventory discrepancies', () => {
// TODO: fix tests in CUMULUS-3806 when CreateReconciliationReport lambda is changed to query postgres
xdescribe('Create an Inventory Reconciliation Report to monitor inventory discrepancies', () => {
// report record in db and report in s3
let reportRecord;
let report;
Expand Down Expand Up @@ -541,7 +541,7 @@ describe('When there are granule differences and granule reconciliation is run',
expect(report.granulesInCumulusCmr.okCount).toBe(1);
});

it('generates a filtered report showing granules that are in the Cumulus but not in CMR', () => {
it('generates a filtered report showing granules that are in Cumulus but not in CMR', () => {
if (beforeAllFailed) fail(beforeAllFailed);
// ingested (not published) granule should only in Cumulus
const cumulusGranuleIds = report.granulesInCumulusCmr.onlyInCumulus.map((gran) => gran.granuleId);
Expand Down Expand Up @@ -612,7 +612,8 @@ describe('When there are granule differences and granule reconciliation is run',
});
});

describe('Create an Internal Reconciliation Report to monitor internal discrepancies', () => {
// TODO: the internal report functionality will be removed after collections/granules is changed to no longer use ES
xdescribe('Create an Internal Reconciliation Report to monitor internal discrepancies', () => {
// report record in db and report in s3
let reportRecord;
let report;
Expand Down Expand Up @@ -833,7 +834,8 @@ describe('When there are granule differences and granule reconciliation is run',
});
});

describe('Create an ORCA Backup Reconciliation Report to monitor ORCA backup discrepancies', () => {
// TODO: fix tests in CUMULUS-3806 when CreateReconciliationReport lambda is changed to query postgres
xdescribe('Create an ORCA Backup Reconciliation Report to monitor ORCA backup discrepancies', () => {
// report record in db and report in s3
let reportRecord;
let report;
Expand Down
3 changes: 2 additions & 1 deletion example/spec/parallel/testAPI/granuleSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ describe('The Granules API', () => {
});

const searchedGranule = JSON.parse(searchResults.body).results[0];
expect(searchedGranule).toEqual(jasmine.objectContaining(randomGranuleRecord));
// TODO CUMULUS-3698 includes files
expect(searchedGranule).toEqual(jasmine.objectContaining(omit(randomGranuleRecord, 'files')));
});

it('can modify the granule via API.', async () => {
Expand Down
Loading

0 comments on commit 04845d7

Please sign in to comment.