Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

Commit

Permalink
feat: add Subscription validator (#156)
Browse files Browse the repository at this point in the history
Co-authored-by: Yanyu Zheng <yz2690@columbia.edu>
  • Loading branch information
carvantes and Bingjiling committed Mar 3, 2022
1 parent e521ba0 commit 03aff0d
Show file tree
Hide file tree
Showing 13 changed files with 493 additions and 20 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"cors": "^2.8.5",
"errorhandler": "^1.5.1",
"express": "^4.17.1",
"fhir-works-on-aws-interface": "^11.3.0",
"fhir-works-on-aws-interface": "^12.0.0",
"flat": "^5.0.0",
"http-errors": "^1.8.0",
"lodash": "^4.17.15",
Expand Down
4 changes: 4 additions & 0 deletions src/router/__mocks__/dynamoDbDataService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,5 +121,9 @@ const DynamoDbDataService: Persistence = class {
static getExportStatus(jobId: string): Promise<GetExportStatusResponse> {
throw new Error('Method not implemented');
}

static getActiveSubscriptions(params: { tenantId?: string }): Promise<Record<string, any>[]> {
throw new Error('Method not implemented');
}
};
export default DynamoDbDataService;
4 changes: 4 additions & 0 deletions src/router/__mocks__/elasticSearchService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,9 @@ const ElasticSearchService: Search = class {
static async getCapabilities(): Promise<SearchCapabilityStatement> {
throw new Error('Method not implemented.');
}

static validateSubscriptionSearchCriteria(searchCriteria: string): void {
console.log(searchCriteria);
}
};
export default ElasticSearchService;
2 changes: 1 addition & 1 deletion src/router/bundle/bundleHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export default class BundleHandler implements BundleHandlerInterface {
) {
const startTime = new Date();

await validateResource(this.validators, bundleRequestJson);
await validateResource(this.validators, bundleRequestJson, { tenantId });

let requests: BatchReadWriteRequest[];
try {
Expand Down
4 changes: 4 additions & 0 deletions src/router/handlers/resourceHandler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,10 @@ describe('ERROR CASES: Testing create, read, update, delete of resources', () =>
): Promise<GenericResponse> {
throw new Error('Method not implemented.');
}

static getActiveSubscriptions(params: { tenantId?: string }): Promise<Record<string, any>[]> {
throw new Error('Method not implemented');
}
};

const resourceHandler = new ResourceHandler(
Expand Down
4 changes: 2 additions & 2 deletions src/router/handlers/resourceHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ export default class ResourceHandler implements CrudHandlerInterface {
}

async create(resourceType: string, resource: any, tenantId?: string) {
await validateResource(this.validators, resource);
await validateResource(this.validators, resource, { tenantId, typeOperation: 'create' });

const createResponse = await this.dataService.createResource({ resourceType, resource, tenantId });
return createResponse.resource;
}

async update(resourceType: string, id: string, resource: any, tenantId?: string) {
await validateResource(this.validators, resource);
await validateResource(this.validators, resource, { tenantId, typeOperation: 'update' });

const updateResponse = await this.dataService.updateResource({ resourceType, id, resource, tenantId });
return updateResponse.resource;
Expand Down
9 changes: 5 additions & 4 deletions src/router/validation/hapiFhirLambdaValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { InvalidResourceError, Validator } from 'fhir-works-on-aws-interface';
import { InvalidResourceError, TypeOperation, Validator } from 'fhir-works-on-aws-interface';
import { Lambda } from 'aws-sdk';
import AWS from '../../AWS';
import getComponentLogger from '../../loggerBuilder';
Expand Down Expand Up @@ -35,14 +35,15 @@ export default class HapiFhirLambdaValidator implements Validator {
});
}

async validate(resource: any): Promise<void> {
const params = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async validate(resource: any, params: { tenantId?: string; typeOperation?: TypeOperation } = {}): Promise<void> {
const lambdaParams = {
FunctionName: this.hapiValidatorLambdaArn,
InvocationType: 'RequestResponse',
Payload: JSON.stringify(JSON.stringify(resource)),
};

const lambdaResponse = await this.lambdaClient.invoke(params).promise();
const lambdaResponse = await this.lambdaClient.invoke(lambdaParams).promise();

if (lambdaResponse.FunctionError) {
// this means that the lambda function crashed, not necessarily that the resource is invalid.
Expand Down
8 changes: 3 additions & 5 deletions src/router/validation/jsonSchemaValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

import Ajv from 'ajv';
// @ts-ignore
import schemaDraft06 from 'ajv/lib/refs/json-schema-draft-06.json';
import schemaDraft04 from 'ajv/lib/refs/json-schema-draft-04.json';

// @ts-ignore
import { FhirVersion, InvalidResourceError, Validator } from 'fhir-works-on-aws-interface';
import { FhirVersion, InvalidResourceError, TypeOperation, Validator } from 'fhir-works-on-aws-interface';
import fhirV4Schema from './schemas/fhir.schema.v4.json';
import fhirV3Schema from './schemas/fhir.schema.v3.json';

Expand All @@ -34,7 +31,8 @@ export default class JsonSchemaValidator implements Validator {
this.ajv = ajv;
}

async validate(resource: any): Promise<void> {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async validate(resource: any, params: { tenantId?: string; typeOperation?: TypeOperation } = {}): Promise<void> {
const definitionName = resource.resourceType;
if (!definitionName) {
throw new InvalidResourceError("resource should have required property 'resourceType'");
Expand Down
54 changes: 54 additions & 0 deletions src/router/validation/subscriptionSchema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"type": "object",
"properties": {
"resourceType": {
"const": "Subscription"
},
"status": {
"type": "string",
"enum": ["requested", "off"],
"errorMessage": "should be 'requested' or 'off'"
},
"reason": {
"type": "string"
},
"criteria": {
"type": "string"
},
"channel": {
"type": "object",
"properties": {
"type": {
"const": "rest-hook",
"errorMessage": "should be equal to 'rest-hook'"
},
"endpoint": {
"type": "string",
"pattern": "^https:"
},
"payload": {
"const": "application/fhir+json",
"errorMessage": "should be equal to 'application/fhir+json'"
},
"header": {
"type": "array",
"items": [
{
"type": "string"
}
]
}
},
"required": [
"type",
"endpoint"
]
}
},
"required": [
"resourceType",
"status",
"criteria",
"channel"
]
}
Loading

0 comments on commit 03aff0d

Please sign in to comment.