diff --git a/graph-db/serverless/src/indexCmrCollection/__test__/handler.test.js b/graph-db/serverless/src/indexCmrCollection/__test__/handler.test.js index 8dca271a2d..d88de61404 100644 --- a/graph-db/serverless/src/indexCmrCollection/__test__/handler.test.js +++ b/graph-db/serverless/src/indexCmrCollection/__test__/handler.test.js @@ -5,10 +5,16 @@ import indexCmrCollection from '../handler' import { updateCollection, deleteCollection } from '../../testUtil/indexCollection' import { - verifyDocumentationExistInGraphDb, verifyDocumentationNotExistInGraphDb, - verifyCampaignExistInGraphDb, verifyCampaignNotExistInGraphDb, + verifyDocumentationExistInGraphDb, verifyDocumentationNotExistInGraphDb +} from '../../testUtil/verifyDocumentation' + +import { + verifyCampaignExistInGraphDb, verifyCampaignNotExistInGraphDb +} from '../../testUtil/verifyCampaign' + +import { verifyPlatformInstrumentsExistInGraphDb, verifyPlatformInstrumentsNotExistInGraphDb -} from '../../testUtil/verifyGraphDb' +} from '../../testUtil/verifyPlatformInstrument' beforeEach(() => { jest.clearAllMocks() diff --git a/graph-db/serverless/src/testUtil/verifyCampaign.js b/graph-db/serverless/src/testUtil/verifyCampaign.js new file mode 100644 index 0000000000..e3b7f3dd76 --- /dev/null +++ b/graph-db/serverless/src/testUtil/verifyCampaign.js @@ -0,0 +1,50 @@ +import gremlin from 'gremlin' + +const gremlinStatistics = gremlin.process.statics + +export const verifyCampaignExistInGraphDb = async (datasetTitle, campaignName) => { + // verify the dataset vertex with the given title exists + const dataset = await global.testGremlinConnection + .V() + .has('dataset', 'title', datasetTitle) + .next() + const { value: { id: datasetId } } = dataset + expect(datasetId).not.toBe(null) + + // verify the campaign vertex with the given name exists + const doc = await global.testGremlinConnection + .V() + .has('campaign', 'name', campaignName) + .next() + const { value: { id: docId } } = doc + expect(docId).not.toBe(null) + + // verify the edge exists between the two vertices + const record = await global.testGremlinConnection + .V() + .has('dataset', 'title', datasetTitle) + .outE('includedIn') + .filter(gremlinStatistics.inV() + .has('campaign', 'name', campaignName)) + .next() + const { value: { id: edgeId } } = record + expect(edgeId).not.toBe(null) +} + +export const verifyCampaignNotExistInGraphDb = async (datasetTitle, campaignName) => { + // verify the dataset vertex with the given title does not exist + const dataset = await global.testGremlinConnection + .V() + .has('dataset', 'title', datasetTitle) + .next() + const { value: datasetValue } = dataset + expect(datasetValue).toBe(null) + + // verify the campaign vertex with the given name does not exist + const doc = await global.testGremlinConnection + .V() + .has('campaign', 'name', campaignName) + .next() + const { value: docValue } = doc + expect(docValue).toBe(null) +} diff --git a/graph-db/serverless/src/testUtil/verifyDocumentation.js b/graph-db/serverless/src/testUtil/verifyDocumentation.js new file mode 100644 index 0000000000..286fe7f911 --- /dev/null +++ b/graph-db/serverless/src/testUtil/verifyDocumentation.js @@ -0,0 +1,50 @@ +import gremlin from 'gremlin' + +const gremlinStatistics = gremlin.process.statics + +export const verifyDocumentationExistInGraphDb = async (datasetTitle, docName) => { + // verify the dataset vertex with the given title exists + const dataset = await global.testGremlinConnection + .V() + .has('dataset', 'title', datasetTitle) + .next() + const { value: { id: datasetId } } = dataset + expect(datasetId).not.toBe(null) + + // verify the documentation vertex with the given name exists + const doc = await global.testGremlinConnection + .V() + .has('documentation', 'name', docName) + .next() + const { value: { id: docId } } = doc + expect(docId).not.toBe(null) + + // verify the edge exists between the two vertices + const record = await global.testGremlinConnection + .V() + .has('dataset', 'title', datasetTitle) + .outE('documentedBy') + .filter(gremlinStatistics.inV() + .has('documentation', 'name', docName)) + .next() + const { value: { id: edgeId } } = record + expect(edgeId).not.toBe(null) +} + +export const verifyDocumentationNotExistInGraphDb = async (datasetTitle, docName) => { + // verify the dataset vertex with the given title does not exist + const dataset = await global.testGremlinConnection + .V() + .has('dataset', 'title', datasetTitle) + .next() + const { value: datasetValue } = dataset + expect(datasetValue).toBe(null) + + // verify the documentation vertex with the given name does not exist + const doc = await global.testGremlinConnection + .V() + .has('documentation', 'name', docName) + .next() + const { value: docValue } = doc + expect(docValue).toBe(null) +} diff --git a/graph-db/serverless/src/testUtil/verifyGraphDb.js b/graph-db/serverless/src/testUtil/verifyPlatformInstrument.js similarity index 55% rename from graph-db/serverless/src/testUtil/verifyGraphDb.js rename to graph-db/serverless/src/testUtil/verifyPlatformInstrument.js index 8e1b2fafa3..d9cf9ffe9f 100644 --- a/graph-db/serverless/src/testUtil/verifyGraphDb.js +++ b/graph-db/serverless/src/testUtil/verifyPlatformInstrument.js @@ -3,100 +3,6 @@ import 'array-foreach-async' const gremlinStatistics = gremlin.process.statics -export const verifyDocumentationExistInGraphDb = async (datasetTitle, docName) => { - // verify the dataset vertex with the given title exists - const dataset = await global.testGremlinConnection - .V() - .has('dataset', 'title', datasetTitle) - .next() - const { value: { id: datasetId } } = dataset - expect(datasetId).not.toBe(null) - - // verify the documentation vertex with the given name exists - const doc = await global.testGremlinConnection - .V() - .has('documentation', 'name', docName) - .next() - const { value: { id: docId } } = doc - expect(docId).not.toBe(null) - - // verify the edge exists between the two vertices - const record = await global.testGremlinConnection - .V() - .has('dataset', 'title', datasetTitle) - .outE('documentedBy') - .filter(gremlinStatistics.inV() - .has('documentation', 'name', docName)) - .next() - const { value: { id: edgeId } } = record - expect(edgeId).not.toBe(null) -} - -export const verifyDocumentationNotExistInGraphDb = async (datasetTitle, docName) => { - // verify the dataset vertex with the given title does not exist - const dataset = await global.testGremlinConnection - .V() - .has('dataset', 'title', datasetTitle) - .next() - const { value: datasetValue } = dataset - expect(datasetValue).toBe(null) - - // verify the documentation vertex with the given name does not exist - const doc = await global.testGremlinConnection - .V() - .has('documentation', 'name', docName) - .next() - const { value: docValue } = doc - expect(docValue).toBe(null) -} - -export const verifyCampaignExistInGraphDb = async (datasetTitle, campaignName) => { - // verify the dataset vertex with the given title exists - const dataset = await global.testGremlinConnection - .V() - .has('dataset', 'title', datasetTitle) - .next() - const { value: { id: datasetId } } = dataset - expect(datasetId).not.toBe(null) - - // verify the campaign vertex with the given name exists - const doc = await global.testGremlinConnection - .V() - .has('campaign', 'name', campaignName) - .next() - const { value: { id: docId } } = doc - expect(docId).not.toBe(null) - - // verify the edge exists between the two vertices - const record = await global.testGremlinConnection - .V() - .has('dataset', 'title', datasetTitle) - .outE('includedIn') - .filter(gremlinStatistics.inV() - .has('campaign', 'name', campaignName)) - .next() - const { value: { id: edgeId } } = record - expect(edgeId).not.toBe(null) -} - -export const verifyCampaignNotExistInGraphDb = async (datasetTitle, campaignName) => { - // verify the dataset vertex with the given title does not exist - const dataset = await global.testGremlinConnection - .V() - .has('dataset', 'title', datasetTitle) - .next() - const { value: datasetValue } = dataset - expect(datasetValue).toBe(null) - - // verify the campaign vertex with the given name does not exist - const doc = await global.testGremlinConnection - .V() - .has('campaign', 'name', campaignName) - .next() - const { value: docValue } = doc - expect(docValue).toBe(null) -} - const verifyPlatformInstrumentExistInGraphDb = async ( datasetTitle, platformName, diff --git a/graph-db/serverless/src/utils/cmr/createAcquiredByEdge.js b/graph-db/serverless/src/utils/cmr/createAcquiredByEdge.js new file mode 100644 index 0000000000..2b2514a9ea --- /dev/null +++ b/graph-db/serverless/src/utils/cmr/createAcquiredByEdge.js @@ -0,0 +1,32 @@ +import gremlin from 'gremlin' + +const gremlinStatistics = gremlin.process.statics + +/** + * create the acquiredBy edge between platform/instrument and collection + * @param {String} piId the id of the platformInstrument vertex + * @param {Connection} gremlinConnection a connection to the gremlin server + * @param {Graph Node} dataset the parent collection vertex in the gremlin server + * @returns null + */ +export const createAcquiredByEdge = async (piId, gremlinConnection, dataset) => { + // Create an edge between the given platform and the collection + let platformEdge + try { + platformEdge = await gremlinConnection + .V(piId).as('p') + .V(dataset) + .coalesce( + gremlinStatistics.outE('acquiredBy').where(gremlinStatistics.inV().as('p')), + gremlinConnection.addE('acquiredBy').to('p') + ) + .next() + } catch (error) { + console.error(`ERROR creating acquiredBy edge: ${error}`) + } + + const { value: edgeValue = {} } = platformEdge + const { id: edgeId } = edgeValue + + console.log(`acquiredBy edge [${edgeId}] indexed to point to collection [${dataset}]`) +} diff --git a/graph-db/serverless/src/utils/cmr/indexInstrument.js b/graph-db/serverless/src/utils/cmr/indexInstrument.js new file mode 100644 index 0000000000..adb4acb5c0 --- /dev/null +++ b/graph-db/serverless/src/utils/cmr/indexInstrument.js @@ -0,0 +1,41 @@ +import gremlin from 'gremlin' + +import { createAcquiredByEdge } from './createAcquiredByEdge' + +const gremlinStatistics = gremlin.process.statics + +/** + * Given an Instrument object, Gremlin connection, and associated platform and collection, index instrument and build relationships between platform/instrument and collection + * @param {JSON} instrument the instrument + * @param {Connection} gremlinConnection a connection to the gremlin server + * @param {String} platformName the name of the platform + * @param {Graph Node} dataset the parent collection vertex in the gremlin server + * @returns null + */ +export const indexInstrument = async (instrument, gremlinConnection, platformName, dataset) => { + const { + ShortName: instrumentName + } = instrument + + let piVertex + try { + piVertex = await gremlinConnection + .V() + .has('platformInstrument', 'platform', platformName) + .has('instrument', instrumentName) + .fold() + .coalesce( + gremlinStatistics.unfold(), + gremlinConnection.addV('platformInstrument').property('platform', platformName).property('instrument', instrumentName) + ) + .next() + } catch (error) { + console.error(`ERROR indexing instrument: ${error}`) + } + + const { value: vertexValue = {} } = piVertex + const { id: piId } = vertexValue + console.log(`PlatformInstrument vertex [${piId}] indexed for collection [${dataset}]`) + + await createAcquiredByEdge(piId, gremlinConnection, dataset) +} diff --git a/graph-db/serverless/src/utils/cmr/indexPlatform.js b/graph-db/serverless/src/utils/cmr/indexPlatform.js index 64767fd95d..d8dedac40d 100644 --- a/graph-db/serverless/src/utils/cmr/indexPlatform.js +++ b/graph-db/serverless/src/utils/cmr/indexPlatform.js @@ -1,62 +1,9 @@ import gremlin from 'gremlin' -const gremlinStatistics = gremlin.process.statics - -/** - * create the acquiredBy edge between platform/instrument and collection - * @param {JSON} piVertex the platformInstrument vertex - * @param {Connection} gremlinConnection a connection to the gremlin server - * @param {Graph Node} dataset the parent collection vertex in the gremlin server - * @returns null - */ -const createAcquiredByEdge = async (piVertex, gremlinConnection, dataset) => { - const { value: vertexValue = {} } = piVertex - const { id: piId } = vertexValue - - console.log(`PlatformInstrument vertex [${piId}] indexed for collection [${dataset}]`) - - // Create an edge between this platform and its parent collection - const platformEdge = await gremlinConnection - .V(piId).as('p') - .V(dataset) - .coalesce( - gremlinStatistics.outE('acquiredBy').where(gremlinStatistics.inV().as('p')), - gremlinConnection.addE('acquiredBy').to('p') - ) - .next() - - const { value: edgeValue = {} } = platformEdge - const { id: edgeId } = edgeValue - - console.log(`acquiredBy edge [${edgeId}] indexed to point to collection [${dataset}]`) -} +import { createAcquiredByEdge } from './createAcquiredByEdge' +import { indexInstrument } from './indexInstrument' -/** - * Given an Instrument object, Gremlin connection, and associated platform and collection, index instrument and build relationships between platform/instrument and collection - * @param {JSON} instrument the instrument - * @param {Connection} gremlinConnection a connection to the gremlin server - * @param {String} platformName the name of the platform - * @param {Graph Node} dataset the parent collection vertex in the gremlin server - * @returns null - */ -const indexInstrument = async (instrument, gremlinConnection, platformName, dataset) => { - const { - ShortName: instrumentName - } = instrument - - const piVertex = await gremlinConnection - .V() - .has('platformInstrument', 'platform', platformName) - .has('instrument', instrumentName) - .fold() - .coalesce( - gremlinStatistics.unfold(), - gremlinConnection.addV('platformInstrument').property('platform', platformName).property('instrument', instrumentName) - ) - .next() - - await createAcquiredByEdge(piVertex, gremlinConnection, dataset) -} +const gremlinStatistics = gremlin.process.statics /** * Given a Platform object, Gremlin connection, and associated collection, index platform and instrument and build relationships between platform/instrument and collection @@ -89,10 +36,14 @@ const indexPlatform = async (platform, gremlinConnection, dataset, conceptId) => ) .next() - await createAcquiredByEdge(piVertex, gremlinConnection, dataset) + const { value: vertexValue = {} } = piVertex + const { id: piId } = vertexValue + console.log(`PlatformInstrument vertex [${piId}] indexed for collection [${dataset}]`) + + await createAcquiredByEdge(piId, gremlinConnection, dataset) } } catch (error) { - console.log(`ERROR indexing Platform for concept [${conceptId}] ${JSON.stringify(platform)}: \n Error: ${error}`) + console.error(`ERROR indexing Platform for concept [${conceptId}] ${JSON.stringify(platform)}: ${error}`) } }