Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BHBC-2151: Enhance EML call to BioHub EML Submission API when Project or Survey Metadata Updated #954

Merged
merged 2 commits into from
Feb 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions api/src/models/survey-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export type SurveyObject = {

export class GetSurveyData {
id: number;
project_id: number;
uuid: string;
survey_name: string;
start_date: string;
Expand All @@ -25,6 +26,7 @@ export class GetSurveyData {

constructor(obj?: any) {
this.id = obj?.survey_id || null;
this.project_id = obj?.project_id || null;
this.uuid = obj?.uuid || null;
this.survey_name = obj?.name || '';
this.start_date = obj?.start_date || null;
Expand Down
3 changes: 0 additions & 3 deletions api/src/paths/project/create.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import * as db from '../../database/db';
import { HTTPError } from '../../errors/http-error';
import { PlatformService } from '../../services/platform-service';
import { ProjectService } from '../../services/project-service';
import { getMockDBConnection, getRequestHandlerMocks } from '../../__mocks__/db';
import { createProject, POST } from './create';
Expand Down Expand Up @@ -33,8 +32,6 @@ describe('create', () => {

sinon.stub(ProjectService.prototype, 'createProject').resolves(1);

sinon.stub(PlatformService.prototype, 'submitDwCAMetadataPackage').resolves();

const { mockReq, mockRes, mockNext } = getRequestHandlerMocks();

try {
Expand Down
9 changes: 0 additions & 9 deletions api/src/paths/project/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { getDBConnection } from '../../database/db';
import { PostProjectObject } from '../../models/project-create';
import { projectCreatePostRequestObject, projectIdResponseObject } from '../../openapi/schemas/project';
import { authorizeRequestHandler } from '../../request-handlers/security/authorization';
import { PlatformService } from '../../services/platform-service';
import { ProjectService } from '../../services/project-service';
import { getLogger } from '../../utils/logger';

Expand Down Expand Up @@ -90,14 +89,6 @@ export function createProject(): RequestHandler {

const projectId = await projectService.createProject(sanitizedProjectPostData);

try {
const platformService = new PlatformService(connection);
await platformService.submitDwCAMetadataPackage(projectId);
} catch (error) {
// Don't fail the rest of the endpoint if submitting metadata fails
defaultLog.error({ label: 'createProject->submitDwCAMetadataPackage', message: 'error', error });
}

await connection.commit();

return res.status(200).json({ id: projectId });
Expand Down
3 changes: 0 additions & 3 deletions api/src/paths/project/{projectId}/survey/create.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import * as db from '../../../../database/db';
import { HTTPError } from '../../../../errors/http-error';
import { PlatformService } from '../../../../services/platform-service';
import { SurveyService } from '../../../../services/survey-service';
import { getMockDBConnection, getRequestHandlerMocks } from '../../../../__mocks__/db';
import { createSurvey } from './create';
Expand All @@ -24,8 +23,6 @@ describe('survey/create', () => {

sinon.stub(SurveyService.prototype, 'createSurvey').resolves(2);

sinon.stub(PlatformService.prototype, 'submitDwCAMetadataPackage').resolves();

const { mockReq, mockRes, mockNext } = getRequestHandlerMocks();

mockReq.params = { projectId: '1' };
Expand Down
9 changes: 0 additions & 9 deletions api/src/paths/project/{projectId}/survey/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { getDBConnection } from '../../../../database/db';
import { PostSurveyObject } from '../../../../models/survey-create';
import { geoJsonFeature } from '../../../../openapi/schemas/geoJson';
import { authorizeRequestHandler } from '../../../../request-handlers/security/authorization';
import { PlatformService } from '../../../../services/platform-service';
import { SurveyService } from '../../../../services/survey-service';
import { getLogger } from '../../../../utils/logger';

Expand Down Expand Up @@ -251,14 +250,6 @@ export function createSurvey(): RequestHandler {

const surveyId = await surveyService.createSurvey(projectId, sanitizedPostSurveyData);

try {
const platformService = new PlatformService(connection);
await platformService.submitDwCAMetadataPackage(projectId);
} catch (error) {
// Don't fail the rest of the endpoint if submitting metadata fails
defaultLog.error({ label: 'createSurvey->submitDwCAMetadataPackage', message: 'error', error });
}

await connection.commit();

return res.status(200).json({ id: surveyId });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import * as db from '../../../../../database/db';
import { HTTPError } from '../../../../../errors/http-error';
import { PlatformService } from '../../../../../services/platform-service';
import { SurveyService } from '../../../../../services/survey-service';
import { getMockDBConnection, getRequestHandlerMocks } from '../../../../../__mocks__/db';
import { updateSurvey } from './update';
Expand All @@ -23,8 +22,6 @@ describe('updateSurvey', () => {

sinon.stub(SurveyService.prototype, 'updateSurvey').resolves();

sinon.stub(PlatformService.prototype, 'submitDwCAMetadataPackage').resolves();

const { mockReq, mockRes, mockNext } = getRequestHandlerMocks();

mockReq.params = {
Expand Down
10 changes: 0 additions & 10 deletions api/src/paths/project/{projectId}/survey/{surveyId}/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { getDBConnection } from '../../../../../database/db';
import { PutSurveyObject } from '../../../../../models/survey-update';
import { geoJsonFeature } from '../../../../../openapi/schemas/geoJson';
import { authorizeRequestHandler } from '../../../../../request-handlers/security/authorization';
import { PlatformService } from '../../../../../services/platform-service';
import { SurveyService } from '../../../../../services/survey-service';
import { getLogger } from '../../../../../utils/logger';

Expand Down Expand Up @@ -275,7 +274,6 @@ PUT.apiDoc = {

export function updateSurvey(): RequestHandler {
return async (req, res) => {
const projectId = Number(req.params.projectId);
const surveyId = Number(req.params.surveyId);

const sanitizedPutSurveyData = new PutSurveyObject(req.body);
Expand All @@ -289,14 +287,6 @@ export function updateSurvey(): RequestHandler {

await surveyService.updateSurvey(surveyId, sanitizedPutSurveyData);

try {
const platformService = new PlatformService(connection);
await platformService.submitDwCAMetadataPackage(projectId);
} catch (error) {
// Don't fail the rest of the endpoint if submitting metadata fails
defaultLog.error({ label: 'updateSurvey->submitDwCAMetadataPackage', message: 'error', error });
}

await connection.commit();

return res.status(200).json({ id: surveyId });
Expand Down
3 changes: 0 additions & 3 deletions api/src/paths/project/{projectId}/update.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import * as db from '../../../database/db';
import { HTTPError } from '../../../errors/http-error';
import { PlatformService } from '../../../services/platform-service';
import { ProjectService } from '../../../services/project-service';
import { getMockDBConnection, getRequestHandlerMocks } from '../../../__mocks__/db';
import * as update from './update';
Expand Down Expand Up @@ -157,8 +156,6 @@ describe('update', () => {

sinon.stub(ProjectService.prototype, 'updateProject').resolves();

sinon.stub(PlatformService.prototype, 'submitDwCAMetadataPackage').resolves();

const requestHandler = update.updateProject();

await requestHandler(mockReq, mockRes, mockNext);
Expand Down
9 changes: 0 additions & 9 deletions api/src/paths/project/{projectId}/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { HTTP400 } from '../../../errors/http-error';
import { geoJsonFeature } from '../../../openapi/schemas/geoJson';
import { projectIdResponseObject, projectUpdatePutRequestObject } from '../../../openapi/schemas/project';
import { authorizeRequestHandler } from '../../../request-handlers/security/authorization';
import { PlatformService } from '../../../services/platform-service';
import { ProjectService } from '../../../services/project-service';
import { getLogger } from '../../../utils/logger';

Expand Down Expand Up @@ -439,14 +438,6 @@ export function updateProject(): RequestHandler {

await projectService.updateProject(projectId, entities);

try {
const platformService = new PlatformService(connection);
await platformService.submitDwCAMetadataPackage(projectId);
} catch (error) {
// Don't fail the rest of the endpoint if submitting metadata fails
defaultLog.error({ label: 'updateProject->submitDwCAMetadataPackage', message: 'error', error });
}

await connection.commit();

return res.status(200).json({ id: projectId });
Expand Down
41 changes: 24 additions & 17 deletions api/src/services/platform-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import FormData from 'form-data';
import { URL } from 'url';
import { HTTP400 } from '../errors/http-error';
import { getFileFromS3 } from '../utils/file-utils';
import { getLogger } from '../utils/logger';
import { DBService } from './db-service';
import { EmlService } from './eml-service';
import { KeycloakService } from './keycloak-service';
Expand Down Expand Up @@ -33,7 +34,7 @@ export interface IDwCADataset {
export class PlatformService extends DBService {
BACKBONE_INTAKE_ENABLED = process.env.BACKBONE_INTAKE_ENABLED === 'true' || false;
BACKBONE_API_HOST = process.env.BACKBONE_API_HOST;
BACKBONE_INTAKE_PATH = process.env.BACKBONE_INTAKE_PATH || '/api/dwc/submission/intake';
BACKBONE_INTAKE_PATH = process.env.BACKBONE_INTAKE_PATH || '/api/dwc/submission/queue';

/**
* Submit a Darwin Core Archive (DwCA) data package, that only contains the project/survey metadata, to the BioHub
Expand All @@ -50,27 +51,33 @@ export class PlatformService extends DBService {
* @memberof PlatformService
*/
async submitDwCAMetadataPackage(projectId: number) {
if (!this.BACKBONE_INTAKE_ENABLED) {
return;
}
try {
if (!this.BACKBONE_INTAKE_ENABLED) {
return;
}

const emlService = new EmlService({ projectId: projectId }, this.connection);
const emlService = new EmlService({ projectId: projectId }, this.connection);

const emlString = await emlService.buildProjectEml();
const emlString = await emlService.buildProjectEml();

const dwcArchiveZip = new AdmZip();
dwcArchiveZip.addFile('eml.xml', Buffer.from(emlString));
const dwcArchiveZip = new AdmZip();
dwcArchiveZip.addFile('eml.xml', Buffer.from(emlString));

const dwCADataset = {
archiveFile: {
data: dwcArchiveZip.toBuffer(),
fileName: 'DwCA.zip',
mimeType: 'application/zip'
},
dataPackageId: emlService.packageId
};
const dwCADataset = {
archiveFile: {
data: dwcArchiveZip.toBuffer(),
fileName: 'DwCA.zip',
mimeType: 'application/zip'
},
dataPackageId: emlService.packageId
};

return this._submitDwCADatasetToBioHubBackbone(dwCADataset);
return this._submitDwCADatasetToBioHubBackbone(dwCADataset);
} catch (error) {
const defaultLog = getLogger('platformService->submitDwCAMetadataPackage');
// Don't fail the rest of the endpoint if submitting metadata fails
defaultLog.error({ label: 'platformService->submitDwCAMetadataPackage', message: 'error', error });
}
}

/**
Expand Down
9 changes: 9 additions & 0 deletions api/src/services/project-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,19 @@ import { ProjectRepository } from '../repositories/project-repository';
import { deleteFileFromS3 } from '../utils/file-utils';
import { AttachmentService } from './attachment-service';
import { DBService } from './db-service';
import { PlatformService } from './platform-service';
import { SurveyService } from './survey-service';

export class ProjectService extends DBService {
attachmentService: AttachmentService;
projectRepository: ProjectRepository;
platformService: PlatformService;

constructor(connection: IDBConnection) {
super(connection);
this.attachmentService = new AttachmentService(connection);
this.projectRepository = new ProjectRepository(connection);
this.platformService = new PlatformService(connection);
}

/**
Expand Down Expand Up @@ -338,6 +341,9 @@ export class ProjectService extends DBService {
// The user that creates a project is automatically assigned a project lead role, for this project
await this.insertParticipantRole(projectId, PROJECT_ROLE.PROJECT_LEAD);

//Submit Eml to biohub
await this.platformService.submitDwCAMetadataPackage(projectId);

return projectId;
}

Expand Down Expand Up @@ -389,6 +395,9 @@ export class ProjectService extends DBService {
}

await Promise.all(promises);

//Update Eml to biohub
await this.platformService.submitDwCAMetadataPackage(projectId);
}

async updateIUCNData(projectId: number, entities: IUpdateProject): Promise<void> {
Expand Down
21 changes: 19 additions & 2 deletions api/src/services/survey-service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import {
GetSurveyFundingSources,
GetSurveyLocationData,
GetSurveyProprietorData,
GetSurveyPurposeAndMethodologyData
GetSurveyPurposeAndMethodologyData,
SurveyObject
} from '../models/survey-view';
import { IPermitModel } from '../repositories/permit-repository';
import {
Expand All @@ -26,6 +27,7 @@ import {
} from '../repositories/survey-repository';
import { getMockDBConnection } from '../__mocks__/db';
import { PermitService } from './permit-service';
import { PlatformService } from './platform-service';
import { SurveyService } from './survey-service';
import { TaxonomyService } from './taxonomy-service';

Expand Down Expand Up @@ -108,6 +110,12 @@ describe('SurveyService', () => {
const updateSurveyProprietorDataStub = sinon
.stub(SurveyService.prototype, 'updateSurveyProprietorData')
.resolves();
const getSurveyByIdStub = sinon
.stub(SurveyService.prototype, 'getSurveyById')
.resolves(({ survey_details: { project_id: 1 } } as unknown) as SurveyObject);
const submitDwCAMetadataPackageStub = sinon
.stub(PlatformService.prototype, 'submitDwCAMetadataPackage')
.resolves();

const surveyService = new SurveyService(dbConnectionObj);

Expand All @@ -122,6 +130,8 @@ describe('SurveyService', () => {
expect(updateSurveyPermitDataStub).not.to.have.been.called;
expect(updateSurveyFundingDataStub).not.to.have.been.called;
expect(updateSurveyProprietorDataStub).not.to.have.been.called;
expect(getSurveyByIdStub).to.have.been.called;
expect(submitDwCAMetadataPackageStub).to.have.been.called;
});

it('updates everything when all data provided', async () => {
Expand All @@ -137,7 +147,12 @@ describe('SurveyService', () => {
const updateSurveyProprietorDataStub = sinon
.stub(SurveyService.prototype, 'updateSurveyProprietorData')
.resolves();

const getSurveyByIdStub = sinon
.stub(SurveyService.prototype, 'getSurveyById')
.resolves(({ survey_details: { project_id: 1 } } as unknown) as SurveyObject);
const submitDwCAMetadataPackageStub = sinon
.stub(PlatformService.prototype, 'submitDwCAMetadataPackage')
.resolves();
const surveyService = new SurveyService(dbConnectionObj);

const surveyId = 2;
Expand All @@ -159,6 +174,8 @@ describe('SurveyService', () => {
expect(updateSurveyPermitDataStub).to.have.been.calledOnce;
expect(updateSurveyFundingDataStub).to.have.been.calledOnce;
expect(updateSurveyProprietorDataStub).to.have.been.calledOnce;
expect(getSurveyByIdStub).to.have.been.called;
expect(submitDwCAMetadataPackageStub).to.have.been.called;
});
});

Expand Down
9 changes: 9 additions & 0 deletions api/src/services/survey-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
import { getLogger } from '../utils/logger';
import { DBService } from './db-service';
import { PermitService } from './permit-service';
import { PlatformService } from './platform-service';
import { TaxonomyService } from './taxonomy-service';

const defaultLog = getLogger('services/survey-service');
Expand All @@ -41,12 +42,14 @@ export interface IMessageTypeGroup {
export class SurveyService extends DBService {
attachmentRepository: AttachmentRepository;
surveyRepository: SurveyRepository;
platformService: PlatformService;

constructor(connection: IDBConnection) {
super(connection);

this.attachmentRepository = new AttachmentRepository(connection);
this.surveyRepository = new SurveyRepository(connection);
this.platformService = new PlatformService(connection);
}

async getSurveyIdsByProjectId(projectId: number): Promise<{ id: number }[]> {
Expand Down Expand Up @@ -246,6 +249,8 @@ export class SurveyService extends DBService {

await Promise.all(promises);

await this.platformService.submitDwCAMetadataPackage(projectId);

return surveyId;
}

Expand Down Expand Up @@ -323,6 +328,10 @@ export class SurveyService extends DBService {
}

await Promise.all(promises);

const surveyData = await this.getSurveyById(surveyId);

await this.platformService.submitDwCAMetadataPackage(surveyData.survey_details.project_id);
}

async updateSurveyDetailsData(surveyId: number, surveyData: PutSurveyObject) {
Expand Down