Skip to content

Commit

Permalink
Merge pull request #655 from ustaxcourt/staging
Browse files Browse the repository at this point in the history
Merge Staging into Migration
  • Loading branch information
mmarcotte authored Dec 14, 2020
2 parents 703cbb8 + f691c55 commit 62bc3db
Show file tree
Hide file tree
Showing 19 changed files with 105 additions and 46 deletions.
2 changes: 2 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,7 @@ jobs:
-e "AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}" \
-e "CIRCLE_HONEYBADGER_API_KEY=${CIRCLE_HONEYBADGER_API_KEY}" \
-e "CIRCLE_SHA1=${CIRCLE_SHA1}" \
-e "CLIENT_STAGE=${CLIENT_STAGE}" \
-e "COGNITO_SUFFIX=${COGNITO_SUFFIX}" \
-e "CURRENT_COLOR=${CURRENT_COLOR}" \
-e "DEPLOYING_COLOR=${DEPLOYING_COLOR}" \
Expand All @@ -596,6 +597,7 @@ jobs:
-e "AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}" \
-e "AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}" \
-e "CIRCLE_SHA1=${CIRCLE_SHA1}" \
-e "CLIENT_STAGE=${CLIENT_STAGE}" \
-e "COGNITO_SUFFIX=${COGNITO_SUFFIX}" \
-e "CURRENT_COLOR=${CURRENT_COLOR}" \
-e "DEPLOYING_COLOR=${DEPLOYING_COLOR}" \
Expand Down
1 change: 1 addition & 0 deletions docs/environments/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ A prerequisite for a successful build within CircleCI is [access to CircleCI’s
| `IRS_SUPERUSER_EMAIL_PROD` | Email address used to serve all new petitions to the IRS for PROD |
| `DEFAULT_ACCOUNT_PASS` | Default password for all test accounts and some password resets |
| `STATUSPAGE_DNS_RECORD` | DNS record for Statuspage of CNAME `status.${EFCMS_DOMAIN}` (optional) |
| `CLIENT_STAGE` | The `process.env.STAGE` for the React application |

- Run a build in CircleCI.
- The build may fail the first time, as provisioning new security certificates can take some time (and cause a timeout). See [the troubleshooting guide](../TROUBLESHOOTING.md) for solutions to common problems.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,11 @@ resource "aws_cloudwatch_log_subscription_filter" "api_stage_logs_green" {
name = "api_stage_logs_lambda_filter"
log_group_name = "/aws/apigateway/gateway_api_${element(var.log_group_environments, count.index)}_green"
}

resource "aws_cloudwatch_log_subscription_filter" "legacy_documents_lambda_filter" {
count = length(var.log_group_environments)
destination_arn = aws_lambda_function.logs_to_es.arn
filter_pattern = ""
name = "legacy_documents_${element(var.log_group_environments, count.index)}_lambda_filter"
log_group_name = "/aws/lambda/legacy_documents_migration_lambda_${element(var.log_group_environments, count.index)}"
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ exports.fileCourtIssuedOrderInteractor = async ({

await applicationContext.getPersistenceGateway().saveDocumentFromLambda({
applicationContext,
contentType: 'application/json',
document: Buffer.from(JSON.stringify(contentToStore)),
key: documentContentsId,
useTempBucket: false,
Expand Down
11 changes: 0 additions & 11 deletions shared/src/business/useCases/health/getHealthCheckInteractor.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,6 @@ const getEmailServiceStatus = async ({ applicationContext }) => {
}
};

const getClamAVStatus = async () => {
// eslint-disable-next-line spellcheck/spell-checker
// TODO - implement once #6282 (Implement ClamAV Fargate Solution) has been completed
return false;
};

/**
* getHealthCheckInteractor
*
Expand All @@ -195,12 +189,7 @@ exports.getHealthCheckInteractor = async ({ applicationContext }) => {
applicationContext,
});

const clamAVStatus = await getClamAVStatus({
applicationContext,
});

return {
clamAV: clamAVStatus,
cognito: cognitoStatus,
dynamo: {
efcms: dynamoStatus,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ describe('getHealthCheckInteractor', () => {
});

expect(status).toEqual({
clamAV: false,
cognito: true,
dynamo: {
efcms: true,
Expand Down Expand Up @@ -110,7 +109,6 @@ describe('getHealthCheckInteractor', () => {
},
});
expect(status).toEqual({
clamAV: false,
cognito: false,
dynamo: {
efcms: false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const { Case } = require('../../entities/cases/Case');
const { DocketEntry } = require('../../entities/DocketEntry');

/**
*
Expand Down Expand Up @@ -61,6 +62,7 @@ exports.parseLegacyDocumentsInteractor = async ({
// Save text contents to JSON file in S3
await applicationContext.getPersistenceGateway().saveDocumentFromLambda({
applicationContext,
contentType: 'application/json',
document: Buffer.from(
JSON.stringify({ documentContents: pdfTextContents }),
),
Expand All @@ -74,10 +76,17 @@ exports.parseLegacyDocumentsInteractor = async ({

foundDocketEntry.documentContentsId = documentContentsId;

const validatedDocketEntry = new DocketEntry(foundDocketEntry, {
applicationContext,
}).validate();

await applicationContext.getPersistenceGateway().updateDocketEntry({
applicationContext,
docketEntryId: foundDocketEntry.docketEntryId,
docketNumber: caseEntity.docketNumber,
document: foundDocketEntry,
document: validatedDocketEntry,
});
applicationContext.logger.info(
`Successfully scraped ${docketNumber}: ${docketEntryId}`,
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,12 @@ describe('parseLegacyDocumentsInteractor', () => {
docketNumber: mockDocketNumber,
});

expect(
applicationContext.getPersistenceGateway().saveDocumentFromLambda.mock
.calls[0][0].key,
).toEqual(mockUniqueID);
expect(
applicationContext.getPersistenceGateway().saveDocumentFromLambda.mock
.calls[0][0].document,
).toEqual(
const saveParams = applicationContext.getPersistenceGateway()
.saveDocumentFromLambda.mock.calls[0][0];

expect(saveParams.key).toEqual(mockUniqueID);
expect(saveParams.contentType).toEqual('application/json');
expect(saveParams.document).toEqual(
Buffer.from(JSON.stringify({ documentContents: mockPdfTextContents })),
);
});
Expand Down
27 changes: 22 additions & 5 deletions web-api/terraform/template/lambdas/legacy-documents-migration.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,28 @@ exports.handler = async event => {
`About to process legacy document for case:${docketNumber}, docketEntryId: ${docketEntryId}`,
);

await applicationContext.getUseCases().parseLegacyDocumentsInteractor({
applicationContext,
docketEntryId,
docketNumber,
});
try {
await applicationContext.getUseCases().parseLegacyDocumentsInteractor({
applicationContext,
docketEntryId,
docketNumber,
});
} catch (err) {
applicationContext.logger.error(
`Failed processing legacy document ${docketNumber}, ${docketEntryId}: ${err.message}`,
err,
);

// try again if error does not have one of the following
if (
!(
err.message.includes('Docket entry document not found in S3.') ||
err.message.includes('Docket entry not found.')
)
) {
throw err;
}
}

const sqs = applicationContext.getQueueService();
await sqs
Expand Down
1 change: 1 addition & 0 deletions web-api/terraform/template/legacy-document-migration.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ resource "aws_lambda_function" "legacy_documents_migration_lambda" {
DYNAMODB_ENDPOINT = "dynamodb.us-east-1.amazonaws.com"
STAGE = var.environment
DYNAMODB_TABLE_NAME = var.destination_table
NODE_ENV = "production"
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion web-client/build-dist-public.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ CLIENT_ID=$(aws cognito-idp list-user-pool-clients --user-pool-id "${USER_POOL_I

COGNITO_LOGIN_URL="https://auth-${ENV}-${COGNITO_SUFFIX}.auth.us-east-1.amazoncognito.com/login?response_type=code&client_id=${CLIENT_ID}&redirect_uri=${COGNITO_REDIRECT_URL}"

COGNITO_LOGIN_URL="${COGNITO_LOGIN_URL}" CIRCLE_SHA1="${CIRCLE_SHA1}" SESSION_TIMEOUT=3300000 API_URL="${API_URL}" npm run build:public
STAGE="${CLIENT_STAGE}" COGNITO_LOGIN_URL="${COGNITO_LOGIN_URL}" CIRCLE_SHA1="${CIRCLE_SHA1}" SESSION_TIMEOUT=3300000 API_URL="${API_URL}" npm run build:public
3 changes: 1 addition & 2 deletions web-client/build-dist.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ DEPLOYING_COLOR=$2
[ -z "${ENV}" ] && echo 'You must pass ENV as argument $1' && exit 1
[ -z "${DEPLOYING_COLOR}" ] && echo 'You must pass DEPLOYING_COLOR as argument $2' && exit 1


REGION="us-east-1"
API_URL="https://api-${DEPLOYING_COLOR}.${EFCMS_DOMAIN}"
WS_URL="wss://ws-${DEPLOYING_COLOR}.${EFCMS_DOMAIN}"
Expand All @@ -27,4 +26,4 @@ else
SCANNER_RESOURCE_URI="${DYNAMSOFT_URL_OVERRIDE}/dynamic-web-twain-sdk-14.3.1"
fi

CIRCLE_SHA1="${CIRCLE_SHA1}" SESSION_TIMEOUT=3300000 COGNITO_CLIENT_ID="${CLIENT_ID}" SCANNER_RESOURCE_URI="${SCANNER_RESOURCE_URI}" COGNITO_TOKEN_URL="${COGNITO_TOKEN_URL}" COGNITO_REDIRECT_URI="${COGNITO_REDIRECT_URI}" WS_URL="${WS_URL}" API_URL="${API_URL}" COGNITO_LOGIN_URL="${COGNITO_LOGIN_URL}" CIRCLE_HONEYBADGER_API_KEY="${CIRCLE_HONEYBADGER_API_KEY}" npm run build:client
STAGE="${CLIENT_STAGE}" CIRCLE_SHA1="${CIRCLE_SHA1}" SESSION_TIMEOUT=3300000 COGNITO_CLIENT_ID="${CLIENT_ID}" SCANNER_RESOURCE_URI="${SCANNER_RESOURCE_URI}" COGNITO_TOKEN_URL="${COGNITO_TOKEN_URL}" COGNITO_REDIRECT_URI="${COGNITO_REDIRECT_URI}" WS_URL="${WS_URL}" API_URL="${API_URL}" COGNITO_LOGIN_URL="${COGNITO_LOGIN_URL}" CIRCLE_HONEYBADGER_API_KEY="${CIRCLE_HONEYBADGER_API_KEY}" npm run build:client
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ export const unauthedUserViewsHealthCheck = test => {

expect(test.getState('health')).toEqual(
expect.objectContaining({
clamAV: expect.anything(),
cognito: expect.anything(),
dynamo: expect.objectContaining({
efcms: expect.anything(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import { state } from 'cerebral';

/**
* changes the route to the practitioner detail page for the given props.barNumber
*
* @param {object} providers the providers object
* @param {object} providers.get the cerebral function to retrieve information from state
* @param {object} providers.router the riot.router object that is used for changing the route
* @param {object} providers.props the cerebral props object
* @returns {Promise} async action
*/
export const navigateToPractitionerDetailAction = async ({ props, router }) => {
const { barNumber } = props;
export const navigateToPractitionerDetailAction = async ({
get,
props,
router,
}) => {
const user = get(state.form);
const barNumber = props.barNumber || user.barNumber;

if (barNumber) {
await router.route(`/practitioner-detail/${barNumber}`);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { getUserContactEditCompleteAlertSuccessAction } from '../actions/getUserContactEditCompleteAlertSuccessAction';
import { setAlertSuccessAction } from '../actions/setAlertSuccessAction';
import { setSaveAlertsForNavigationAction } from '../actions/setSaveAlertsForNavigationAction';
import { stopWebSocketConnectionAction } from '../actions/webSocketConnection/stopWebSocketConnectionAction';
import { unsetUserContactEditProgressAction } from '../actions/unsetUserContactEditProgressAction';

export const adminContactUpdateCompleteSequence = [
stopWebSocketConnectionAction,
unsetUserContactEditProgressAction,
getUserContactEditCompleteAlertSuccessAction,
setAlertSuccessAction,
setSaveAlertsForNavigationAction,
];
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { navigateToPractitionerDetailAction } from '../actions/navigateToPractitionerDetailAction';
import { unsetWaitingForResponseAction } from '../actions/unsetWaitingForResponseAction';

export const adminContactUpdateInitialUpdateCompleteSequence = [
unsetWaitingForResponseAction,
navigateToPractitionerDetailAction,
];
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { clearAlertsAction } from '../actions/clearAlertsAction';
import { computeFormDateAction } from '../actions/computeFormDateAction';
import { navigateToPractitionerDetailAction } from '../actions/navigateToPractitionerDetailAction';
import { setAlertSuccessAction } from '../actions/setAlertSuccessAction';
import { setCurrentPageAction } from '../actions/setCurrentPageAction';
import { setPractitionerDetailAction } from '../actions/setPractitionerDetailAction';
import { setSaveAlertsForNavigationAction } from '../actions/setSaveAlertsForNavigationAction';
import { setShowModalFactoryAction } from '../actions/setShowModalFactoryAction';
import { setValidationAlertErrorsAction } from '../actions/setValidationAlertErrorsAction';
import { setValidationErrorsAction } from '../actions/setValidationErrorsAction';
Expand All @@ -23,7 +19,6 @@ export const submitUpdatePractitionerUserSequence = [
{
error: [setValidationErrorsAction, setValidationAlertErrorsAction],
success: [
setCurrentPageAction('Interstitial'),
setWaitingForResponseAction,
startWebSocketConnectionAction,
{
Expand All @@ -35,12 +30,7 @@ export const submitUpdatePractitionerUserSequence = [
updatePractitionerUserAction,
{
error: [],
success: [
setPractitionerDetailAction,
setSaveAlertsForNavigationAction,
navigateToPractitionerDetailAction,
setAlertSuccessAction,
],
success: [setPractitionerDetailAction],
},
],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,19 @@ exports.handler = (event, context, callback) => {
const localUrl = 'https://127.0.0.1:*';
const localWebsocketUrl = 'ws://127.0.0.1:*';
const s3Url = 'https://s3.us-east-1.amazonaws.com';
const statuspageUrl = 'https://lynmjtcq5px1.statuspage.io';
const contentSecurityPolicy = [
'base-uri resource://pdf.js',
`connect-src ${subdomainsUrl} ${applicationUrl} ${cognitoUrl} ${s3Url} ${dynamsoftUrl} ${localUrl} ${websocketUrl} ${localWebsocketUrl} ${honeybadgerApiUrl}`,
"default-src 'none'",
"manifest-src 'self'",
`form-action ${applicationUrl} ${subdomainsUrl}`,
`object-src ${subdomainsUrl} ${applicationUrl} ${s3Url}`,
`script-src 'self' 'unsafe-inline' ${dynamsoftUrl} resource://pdf.js`,
`script-src 'self' 'unsafe-inline' ${dynamsoftUrl} ${statuspageUrl} resource://pdf.js`,
`style-src 'self' 'unsafe-inline' ${dynamsoftUrl}`,
`img-src ${applicationUrl} ${subdomainsUrl} data:`,
`font-src ${applicationUrl} ${subdomainsUrl}`,
`frame-src ${s3Url} ${subdomainsUrl} blob: data:`,
`frame-src ${s3Url} ${subdomainsUrl} ${statuspageUrl} blob: data:`,
"frame-ancestors 'none'",
];
headers['content-security-policy'] = [
Expand Down
30 changes: 30 additions & 0 deletions web-client/terraform/main/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,33 @@ resource "aws_route53_health_check" "ui_health_check" {
failure_threshold = "2"
request_interval = "30"
}

resource "aws_cloudwatch_metric_alarm" "status_health_check" {
alarm_name = "${var.dns_domain} health check endpoint"
namespace = "AWS/Route53"
metric_name = "HealthCheckStatus"
comparison_operator = "LessThanThreshold"
statistic = "Minimum"
threshold = "1"
evaluation_periods = "2"
period = "60"

dimensions = {
HealthCheckId = aws_route53_health_check.status_health_check.id
}

alarm_actions = [data.aws_sns_topic.system_health_alarms.arn]
insufficient_data_actions = [data.aws_sns_topic.system_health_alarms.arn]
ok_actions = [data.aws_sns_topic.system_health_alarms.arn]
}

resource "aws_route53_health_check" "status_health_check" {
fqdn = "public-api.${var.dns_domain}"
port = 443
type = "HTTPS_STR_MATCH"
resource_path = "/public-api/health"
failure_threshold = "2"
request_interval = "30"
invert_healthcheck = true
search_string = "false" # Search for any JSON property returning "false"
}

0 comments on commit 62bc3db

Please sign in to comment.