Skip to content

Commit

Permalink
Conditions Endpoint (#2934)
Browse files Browse the repository at this point in the history
* Conditions endpoint

* Fixes to get SQLServer to run, and fix SQL query

* Unit tests

* Revert the complete removal of saveSource

* Remove debug statements, reduce size of test_type_system

* Update tests with order by

* Centralize SQL Server pool, and extended.sql

* Removed renamed db.ts

* [pre-commit.ci] auto fixes from pre-commit hooks

* Update postgres_db name

* Correct postgres spelling

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Josh Nygaard <[email protected]>
  • Loading branch information
3 people authored Nov 25, 2024
1 parent 594ea46 commit 4bc70ca
Show file tree
Hide file tree
Showing 14 changed files with 316 additions and 27 deletions.
3 changes: 2 additions & 1 deletion containers/ecr-viewer/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ services:
environment:
- APP_ENV=${APP_ENV:-test}
- METADATA_DATABASE_TYPE=${METADATA_DATABASE_TYPE:-postgres}
- METADATA_DATABASE_SCHEMA=${METADATA_DATABASE_SCHEMA}
- SOURCE=${SOURCE:-postgres}
- DATABASE_URL=postgres://postgres:pw@postgres:5432/ecr_viewer_db
- AWS_CUSTOM_ENDPOINT=http://aws-storage:4566
Expand All @@ -22,6 +21,7 @@ services:
- AZURE_CONTAINER_NAME=${AZURE_CONTAINER_NAME:-ecr-viewer-files}
- NEXT_PUBLIC_NON_INTEGRATED_VIEWER=${NEXT_PUBLIC_NON_INTEGRATED_VIEWER:-false}
- NEXT_PUBLIC_BASEPATH=${NEXT_PUBLIC_BASEPATH:-/ecr-viewer}
- METADATA_DATABASE_SCHEMA=${METADATA_DATABASE_SCHEMA:-core}
- SQL_SERVER_USER=${SQL_SERVER_USER}
- SQL_SERVER_PASSWORD=${SQL_SERVER_PASSWORD}
- SQL_SERVER_HOST=${SQL_SERVER_HOST:-sqlserver}
Expand All @@ -37,6 +37,7 @@ services:
- ./sql/core.sql:/docker-entrypoint-initdb.d/core.sql
- ./seed-scripts/sql/.pgpass/:/usr/local/lib/.pgpass
- db:/var/lib/postgresql/data
- ./sql/extended.sql:/var/opt/mssql/scripts/extended.sql
environment:
- POSTGRES_USER=postgres
- PGUSER=postgres
Expand Down
3 changes: 2 additions & 1 deletion containers/ecr-viewer/seed-scripts/sql/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ until /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P $MSSQL_SA_PASSWORD -Q
echo "Waiting for SQL Server to start..."
sleep 1
done
echo "SQL Server ready."

# Run your SQL script
/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P $MSSQL_SA_PASSWORD -d master -i /var/opt/mssql/scripts/extended.sql -C

wait
wait
22 changes: 22 additions & 0 deletions containers/ecr-viewer/src/app/api/conditions/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { NextResponse } from "next/server";
import { get_conditions_postgres, get_conditions_sqlserver } from "./service";

/**
* Retrieves FHIR data from PostgreSQL database based on eCR ID.
* @returns A promise resolving to a NextResponse object.
*/
export async function GET() {
const metadataSaveLocation = process.env.METADATA_DATABASE_TYPE;

switch (metadataSaveLocation) {
case "postgres":
return await get_conditions_postgres();
case "sqlserver":
return await get_conditions_sqlserver();
default:
return NextResponse.json(
{ message: "Invalid metadata save location: " + metadataSaveLocation },
{ status: 500 },
);
}
}
63 changes: 63 additions & 0 deletions containers/ecr-viewer/src/app/api/conditions/service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import pgPromise from "pg-promise";
import { database } from "../services/postgres_db";
import { NextResponse } from "next/server";
import sql from "mssql";
import { get_pool } from "../services/sqlserver_db";
/**
* Retrieves all unique conditions from the ecr_rr_conditions table in the PostgreSQL database.
* @returns A promise resolving to a NextResponse object.
* @throws An error if the connection to the PostgreSQL database fails.
*/
export const get_conditions_postgres = async () => {
const { ParameterizedQuery: PQ } = pgPromise;

try {
const response = await database.tx(async (t) => {
const getConditions = new PQ({
text: 'SELECT DISTINCT "condition" FROM ecr_rr_conditions ORDER BY "condition"',
});

const conditions = await t.any(getConditions);
return NextResponse.json(
conditions.map((c) => c.condition),
{ status: 200 },
);
});

return response;
} catch (error: any) {
console.error("Error fetching data:", error);
return NextResponse.json({ message: error.message }, { status: 500 });
}
};

/**
* Retrieves all unique conditions from the ecr_rr_conditions table in the SQL Server database.
* @returns A promise resolving to a NextResponse object.
* @throws An error if the connection to the SQL Server database fails.
*/
export const get_conditions_sqlserver = async () => {
try {
let pool = await get_pool();
if (!pool) {
return NextResponse.json(
{ message: "Failed to connect to SQL Server." },
{ status: 500 },
);
}

const transaction = new sql.Transaction(pool);
await transaction.begin();
const request = new sql.Request(transaction);

const result = await request.query(
"SELECT DISTINCT erc.[condition] FROM ecr_rr_conditions erc ORDER BY erc.[condition]",
);
const conditions: string[] = result.recordset.map((row) => row.condition);

return NextResponse.json(conditions, { status: 200 });
} catch (error: any) {
console.error("Error fetching data:", error);
return NextResponse.json({ message: error.message }, { status: 500 });
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
BlobServiceClient,
} from "@azure/storage-blob";
import { loadYamlConfig, streamToJson } from "../utils";
import { database } from "../services/db";
import { database } from "../services/postgres_db";
import { s3Client } from "../services/s3Client";

/**
Expand Down
6 changes: 1 addition & 5 deletions containers/ecr-viewer/src/app/api/save-fhir-data/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@ import { S3_SOURCE, AZURE_SOURCE, POSTGRES_SOURCE } from "@/app/api/utils";
export async function POST(request: NextRequest) {
let requestBody;
let fhirBundle;
let saveSource;
let ecrId;

try {
requestBody = await request.json();
fhirBundle = requestBody.fhirBundle;
saveSource = requestBody.saveSource;
ecrId = requestBody.fhirBundle.entry[0].resource.id;
} catch (error: any) {
console.error("Error reading request body:", error);
Expand All @@ -36,9 +34,7 @@ export async function POST(request: NextRequest) {
);
}

if (!saveSource) {
saveSource = process.env.SOURCE;
}
const saveSource = requestBody.saveSource || process.env.SOURCE;

if (
[S3_SOURCE, AZURE_SOURCE, POSTGRES_SOURCE].includes(saveSource) == false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { BlobServiceClient } from "@azure/storage-blob";
import { NextResponse } from "next/server";
import pgPromise from "pg-promise";
import { database, db_url } from "../services/db";
import { database, db_url } from "../services/postgres_db";
import { PutObjectCommand, PutObjectCommandOutput } from "@aws-sdk/client-s3";
import { Bundle } from "fhir/r4";
import { S3_SOURCE, AZURE_SOURCE, POSTGRES_SOURCE } from "@/app/api/utils";
import sql from "mssql";
import { randomUUID } from "crypto";
import { BundleExtendedMetadata, BundleMetadata } from "./types";
import { s3Client } from "../services/s3Client";
import { get_pool } from "../services/sqlserver_db";

/**
* Saves a FHIR bundle to a postgres database.
Expand Down Expand Up @@ -175,19 +176,11 @@ export const saveMetadataToSqlServer = async (
metadata: BundleExtendedMetadata,
ecrId: string,
) => {
let pool;
try {
pool = await sql.connect({
user: process.env.SQL_SERVER_USER,
password: process.env.SQL_SERVER_PASSWORD,
server: process.env.SQL_SERVER_HOST,
options: {
trustServerCertificate: true,
},
});
} catch (error: any) {
let pool = await get_pool();

if (!pool) {
return NextResponse.json(
{ message: "Failed to connect to SQL Server. " + error.message },
{ message: "Failed to connect to SQL Server." },
{ status: 500 },
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { database } from "@/app/api/services/db";
import { database } from "@/app/api/services/postgres_db";
import {
convertUTCToLocalString,
formatDate,
Expand Down
17 changes: 17 additions & 0 deletions containers/ecr-viewer/src/app/api/services/sqlserver_db.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import sql from "mssql";

/**
* Connect to the SQL Server database and return a connection pool.
* @returns A promise resolving to a connection pool.
*/
export const get_pool = async () => {
let pool = await sql.connect({
user: process.env.SQL_SERVER_USER,
password: process.env.SQL_SERVER_PASSWORD,
server: process.env.SQL_SERVER_HOST || "localhost",
options: {
trustServerCertificate: true,
},
});
return pool;
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
generateFilterConditionsStatement,
generateWhereStatement,
} from "@/app/api/services/listEcrDataService";
import { database } from "../services/db";
import { database } from "../services/postgres_db";
import {
convertUTCToLocalString,
formatDate,
Expand Down
Loading

0 comments on commit 4bc70ca

Please sign in to comment.