diff --git a/__tests__/pages/api/findresources.test.js b/__tests__/pages/api/findresources.test.js index ccd0edc..81a79c9 100644 --- a/__tests__/pages/api/findresources.test.js +++ b/__tests__/pages/api/findresources.test.js @@ -4,11 +4,11 @@ import resources from "./resources.json" const originalEnv = process.env; global.fetch = jest.fn((url) => { - if (url.includes("data.mongodb-api")) { + if (url.includes("api.gem5")) { return Promise.resolve({ - json: () => Promise.resolve({ - 'documents': [], - }), + json: () => Promise.resolve( + [], + ), }) } @@ -18,14 +18,6 @@ global.fetch = jest.fn((url) => { }) } - if (url.includes("realm.mongodb.com")) { - return Promise.resolve({ - json: () => Promise.resolve({ - "access_token": "" - }), - }) - } - return Promise.resolve({ json: () => Promise.resolve({ "error": "Resource not found" @@ -146,9 +138,7 @@ describe('findResources', () => { dataSource: "gem5-vision", database: "gem5-vision", collection: "resources", - url: "https://data.mongodb-api.com/app/data-ejhjf/endpoint/data/v1", - authUrl: "https://realm.mongodb.com/api/client/v2.0/app/data-ejhjf/auth/providers/api-key/login", - apiKey: "pKkhRJGJaQ3NdJyDt69u4GPGQTDUIhHlx4a3lrKUNx2hxuc8uba8NrP3IVRvlzlo", + url: "https://api.gem5.org/api/resources", isMongo: true, } } @@ -169,9 +159,7 @@ describe('findResources', () => { dataSource: "gem5-vision", database: "gem5-vision", collection: "resources", - url: "https://data.mongodb-api.com/app/data-ejhjf/endpoint/data/v1", - authUrl: "https://realm.mongodb.com/api/client/v2.0/app/data-ejhjf/auth/providers/api-key/login", - apiKey: "pKkhRJGJaQ3NdJyDt69u4GPGQTDUIhHlx4a3lrKUNx2hxuc8uba8NrP3IVRvlzlo", + url: "https://api.gem5.org/api/resources", isMongo: true, } } diff --git a/__tests__/pages/api/getVersions.test.js b/__tests__/pages/api/getVersions.test.js index a257d7e..f40e109 100644 --- a/__tests__/pages/api/getVersions.test.js +++ b/__tests__/pages/api/getVersions.test.js @@ -4,11 +4,11 @@ import resources from "./resources.json" const originalEnv = process.env; global.fetch = jest.fn((url) => { - if (url.includes("data.mongodb-api")) { + if (url.includes("api.gem5")) { return Promise.resolve({ status: 200, - json: () => Promise.resolve({ - 'documents': [ + json: () => Promise.resolve( + [ { "category": "simpoint", "id": "batman", @@ -18,7 +18,6 @@ global.fetch = jest.fn((url) => { "database": "db1" } ] - } ), }) } @@ -30,15 +29,6 @@ global.fetch = jest.fn((url) => { }) } - if (url.includes("realm.mongodb.com")) { - return Promise.resolve({ - status: 200, - json: () => Promise.resolve({ - "access_token": "" - }), - }) - } - return Promise.resolve({ status: 200, json: () => Promise.resolve({ @@ -107,9 +97,7 @@ describe("getVersions", () => { dataSource: "gem5-vision", database: "gem5-vision", collection: "versions_test", - url: "https://data.mongodb-api.com/app/data-ejhjf/endpoint/data/v1", - authUrl: "https://realm.mongodb.com/api/client/v2.0/app/data-ejhjf/auth/providers/api-key/login", - apiKey: "pKkhRJGJaQ3NdJyDt69u4GPGQTDUIhHlx4a3lrKUNx2hxuc8uba8NrP3IVRvlzlo", + url: "https://api.gem5.org/api/resources", isMongo: true, }, } diff --git a/__tests__/pages/api/getfilters.test.js b/__tests__/pages/api/getfilters.test.js index 4dde54e..00e50c1 100644 --- a/__tests__/pages/api/getfilters.test.js +++ b/__tests__/pages/api/getfilters.test.js @@ -4,22 +4,20 @@ import resources from "./resources.json" const originalEnv = process.env; global.fetch = jest.fn((url) => { - if (url.includes("data.mongodb-api")) { + if (url.includes("api.gem5")) { return Promise.resolve({ status: 200, - json: () => Promise.resolve({ - 'documents': [ + json: () => Promise.resolve( { "category": ["simpoint", "file"], "id": "batman", - "architecture": ["X86", "ARM", null], + "architecture": ["X86", "ARM"], "tags": [], "resource_version": "1.0.0", "gem5_versions": ["22.0"], "database": "db1", }, - ] - }), + ), }) } @@ -30,15 +28,6 @@ global.fetch = jest.fn((url) => { }) } - if (url.includes("realm.mongodb.com")) { - return Promise.resolve({ - status: 200, - json: () => Promise.resolve({ - "access_token": "" - }), - }) - } - return Promise.resolve({ status: 200, json: () => Promise.resolve({ @@ -85,9 +74,7 @@ describe('getFilters', () => { dataSource: "gem5-vision", database: "gem5-vision", collection: "versions_test", - url: "https://data.mongodb-api.com/app/data-ejhjf/endpoint/data/v1", - authUrl: "https://realm.mongodb.com/api/client/v2.0/app/data-ejhjf/auth/providers/api-key/login", - apiKey: "pKkhRJGJaQ3NdJyDt69u4GPGQTDUIhHlx4a3lrKUNx2hxuc8uba8NrP3IVRvlzlo", + url: "https://api.gem5.org/api/resources", isMongo: true, }, } diff --git a/__tests__/pages/api/getresource.test.js b/__tests__/pages/api/getresource.test.js index d447e9a..2211490 100644 --- a/__tests__/pages/api/getresource.test.js +++ b/__tests__/pages/api/getresource.test.js @@ -4,11 +4,11 @@ import resources from "./resources.json" const originalEnv = process.env; global.fetch = jest.fn((url) => { - if (url.includes("data.mongodb-api")) { + if (url.includes("api.gem5")) { return Promise.resolve({ status: 200, - json: () => Promise.resolve({ - 'documents': [{ + json: () => Promise.resolve( + [{ category: 'simpoint', id: 'batman', description: 'Simpoints for running the \'x86-print-this\' resource with the parameters `"print this" 15000`. This is encapsulated in the \'x86-print-this-15000-with-simpoints\' workload.', @@ -32,7 +32,7 @@ global.fetch = jest.fn((url) => { workloads_mapping: [], database: 'db1' }], - }), + ), }) } @@ -43,15 +43,6 @@ global.fetch = jest.fn((url) => { }) } - if (url.includes("realm.mongodb.com")) { - return Promise.resolve({ - status: 200, - json: () => Promise.resolve({ - "access_token": "" - }), - }) - } - return Promise.resolve({ status: 200, json: () => Promise.resolve({ @@ -187,9 +178,7 @@ describe('getResource', () => { dataSource: "gem5-vision", database: "gem5-vision", collection: "resources", - url: "https://data.mongodb-api.com/app/data-ejhjf/endpoint/data/v1", - authUrl: "https://realm.mongodb.com/api/client/v2.0/app/data-ejhjf/auth/providers/api-key/login", - apiKey: "pKkhRJGJaQ3NdJyDt69u4GPGQTDUIhHlx4a3lrKUNx2hxuc8uba8NrP3IVRvlzlo", + url: "https://api.gem5.org/api/resources", isMongo: true, } } diff --git a/cypress/e2e/searchPage.cy.js b/cypress/e2e/searchPage.cy.js index 0bbd5ed..0a96cf0 100644 --- a/cypress/e2e/searchPage.cy.js +++ b/cypress/e2e/searchPage.cy.js @@ -5,7 +5,6 @@ describe('Search page', () => { cy.interceptAll() cy.visit('/resources') cy.waitAuto() - cy.waitAuto() window.localStorage.setItem('CookieConsent', "{\"userPreference\":\"all\"}") }) @@ -112,6 +111,7 @@ describe('Search page', () => { }) it('checks if changing page size works', () => { + // cy.waitAuto() cy.get('.results-sortBy-row').find('select').first().select('25') cy.waitAuto() // cy.wait(['@kiwi', '@resources', '@mongo']) diff --git a/cypress/fixtures/filters.json b/cypress/fixtures/filters.json index 46e3c1c..1e80eb1 100644 --- a/cypress/fixtures/filters.json +++ b/cypress/fixtures/filters.json @@ -1,28 +1,24 @@ { - "documents": [ - { - "_id": null, - "category": [ - "workload", - "simpoint", - "disk_image", - "binary", - "checkpoint", - "bootloader", - "resource", - "kernel" - ], - "architecture": [ - "X86", - "ARM", - "MIPS", - "RISCV", - "POWER", - "SPARC" - ], - "gem5_versions": [ - "23.0" - ] - } + "_id": null, + "category": [ + "workload", + "simpoint", + "disk_image", + "binary", + "checkpoint", + "bootloader", + "resource", + "kernel" + ], + "architecture": [ + "X86", + "ARM", + "MIPS", + "RISCV", + "POWER", + "SPARC" + ], + "gem5_versions": [ + "23.0" ] -} \ No newline at end of file +} diff --git a/cypress/fixtures/getResource.json b/cypress/fixtures/getResource.json index 5fc3c37..f88b6f8 100644 --- a/cypress/fixtures/getResource.json +++ b/cypress/fixtures/getResource.json @@ -1,70 +1,68 @@ -{ - "documents": [ - { - "_id": "60f6f1a3b3c9a5c6a0f3e7a6", - "category": "workload", - "id": "arm64-ubuntu-20.04-boot", - "description": "A full boot of Ubuntu 20.04 with Linux 5.4.49 for ARM64. It runs an `m5 exit` command when the boot is completed unless the readfile is specified. If specified the readfile will be executed after booting.", - "function": "set_kernel_disk_workload", - "resources": { - "kernel": "arm64-linux-kernel-5.4.49", - "disk_image": "arm64-ubuntu-20.04-img", - "bootloader": "arm64-bootloader-foundation" - }, - "additional_params": {}, - "architecture": "ARM", - "size": 0, - "tags": [ - "arm", - "arm64" - ], - "code_examples": [ - { - "example": "https://github.com/gem5/gem5/tree/develop/configs/example/gem5_library/arm-ubuntu-run.py", - "tested": true - } - ], - "license": "", - "author": [], - "source_url": "", - "resource_version": "1.0.0", - "gem5_versions": [ - "23.0" - ], - "example_usage": "Workload(\"arm64-ubuntu-20.04-boot\")" +[ + { + "_id": "60f6f1a3b3c9a5c6a0f3e7a6", + "category": "workload", + "id": "arm64-ubuntu-20.04-boot", + "description": "A full boot of Ubuntu 20.04 with Linux 5.4.49 for ARM64. It runs an `m5 exit` command when the boot is completed unless the readfile is specified. If specified the readfile will be executed after booting.", + "function": "set_kernel_disk_workload", + "resources": { + "kernel": "arm64-linux-kernel-5.4.49", + "disk_image": "arm64-ubuntu-20.04-img", + "bootloader": "arm64-bootloader-foundation" }, - { - "_id": "60f6f1a3b3c9a5c6a0f3e7a6", - "category": "workload", - "id": "arm64-ubuntu-20.04-boot", - "description": "New version", - "function": "set_kernel_disk_workload", - "resources": { - "kernel": "arm64-linux-kernel-5.4.49", - "disk_image": "arm64-ubuntu-20.04-img", - "bootloader": "arm64-bootloader-foundation" - }, - "additional_params": {}, - "architecture": "ARM", - "size": 0, - "tags": [ - "arm", - "arm64" - ], - "code_examples": [ - { - "example": "https://github.com/gem5/gem5/tree/develop/configs/example/gem5_library/arm-ubuntu-run.py", - "tested": true - } - ], - "license": "", - "author": [], - "source_url": "", - "resource_version": "0.1.0", - "gem5_versions": [ - "23.0" - ], - "example_usage": "Workload(\"arm64-ubuntu-20.04-boot\")" - } - ] -} \ No newline at end of file + "additional_params": {}, + "architecture": "ARM", + "size": 0, + "tags": [ + "arm", + "arm64" + ], + "code_examples": [ + { + "example": "https://github.com/gem5/gem5/tree/develop/configs/example/gem5_library/arm-ubuntu-run.py", + "tested": true + } + ], + "license": "", + "author": [], + "source_url": "", + "resource_version": "1.0.0", + "gem5_versions": [ + "23.0" + ], + "example_usage": "Workload(\"arm64-ubuntu-20.04-boot\")" + }, + { + "_id": "60f6f1a3b3c9a5c6a0f3e7a6", + "category": "workload", + "id": "arm64-ubuntu-20.04-boot", + "description": "New version", + "function": "set_kernel_disk_workload", + "resources": { + "kernel": "arm64-linux-kernel-5.4.49", + "disk_image": "arm64-ubuntu-20.04-img", + "bootloader": "arm64-bootloader-foundation" + }, + "additional_params": {}, + "architecture": "ARM", + "size": 0, + "tags": [ + "arm", + "arm64" + ], + "code_examples": [ + { + "example": "https://github.com/gem5/gem5/tree/develop/configs/example/gem5_library/arm-ubuntu-run.py", + "tested": true + } + ], + "license": "", + "author": [], + "source_url": "", + "resource_version": "0.1.0", + "gem5_versions": [ + "23.0" + ], + "example_usage": "Workload(\"arm64-ubuntu-20.04-boot\")" + } +] diff --git a/cypress/fixtures/getResource2.json b/cypress/fixtures/getResource2.json index edb895f..ad61d50 100644 --- a/cypress/fixtures/getResource2.json +++ b/cypress/fixtures/getResource2.json @@ -1,37 +1,35 @@ -{ - "documents": [ - { - "_id": "60f6f1a3b3c9a5c6a0f3e7a6", - "category": "workload", - "id": "arm64-ubuntu-20.04-boot", - "description": "New version", - "function": "set_kernel_disk_workload", - "resources": { - "kernel": "arm64-linux-kernel-5.4.49", - "disk_image": "arm64-ubuntu-20.04-img", - "bootloader": "arm64-bootloader-foundation" - }, - "additional_params": {}, - "architecture": "ARM", - "size": 0, - "tags": [ - "arm", - "arm64" - ], - "code_examples": [ - { - "example": "https://github.com/gem5/gem5/tree/develop/configs/example/gem5_library/arm-ubuntu-run.py", - "tested": true - } - ], - "license": "", - "author": [], - "source_url": "", - "resource_version": "0.1.0", - "gem5_versions": [ - "23.0" - ], - "example_usage": "Workload(\"arm64-ubuntu-20.04-boot\")" - } - ] -} \ No newline at end of file +[ + { + "_id": "60f6f1a3b3c9a5c6a0f3e7a6", + "category": "workload", + "id": "arm64-ubuntu-20.04-boot", + "description": "New version", + "function": "set_kernel_disk_workload", + "resources": { + "kernel": "arm64-linux-kernel-5.4.49", + "disk_image": "arm64-ubuntu-20.04-img", + "bootloader": "arm64-bootloader-foundation" + }, + "additional_params": {}, + "architecture": "ARM", + "size": 0, + "tags": [ + "arm", + "arm64" + ], + "code_examples": [ + { + "example": "https://github.com/gem5/gem5/tree/develop/configs/example/gem5_library/arm-ubuntu-run.py", + "tested": true + } + ], + "license": "", + "author": [], + "source_url": "", + "resource_version": "0.1.0", + "gem5_versions": [ + "23.0" + ], + "example_usage": "Workload(\"arm64-ubuntu-20.04-boot\")" + } +] diff --git a/cypress/fixtures/mongo.json b/cypress/fixtures/mongo.json index 61b1f88..fe51488 100644 --- a/cypress/fixtures/mongo.json +++ b/cypress/fixtures/mongo.json @@ -1,3 +1 @@ -{ - "documents": [] -} \ No newline at end of file +[] diff --git a/cypress/fixtures/search25.json b/cypress/fixtures/search25.json index 15b797b..e45ca72 100644 --- a/cypress/fixtures/search25.json +++ b/cypress/fixtures/search25.json @@ -983,5 +983,6 @@ "ver_latest": "23.0", "totalCount": 905 } - ] + ], + "totalCount": 905 } \ No newline at end of file diff --git a/cypress/fixtures/searchArchitecture.json b/cypress/fixtures/searchArchitecture.json index 94573ea..f4f2c53 100644 --- a/cypress/fixtures/searchArchitecture.json +++ b/cypress/fixtures/searchArchitecture.json @@ -340,5 +340,6 @@ "ver_latest": "23.0", "totalCount": 900 } - ] + ], + "totalCount": 900 } \ No newline at end of file diff --git a/cypress/fixtures/searchDiskimage.json b/cypress/fixtures/searchDiskimage.json index 524d011..69968bd 100644 --- a/cypress/fixtures/searchDiskimage.json +++ b/cypress/fixtures/searchDiskimage.json @@ -377,5 +377,6 @@ "ver_latest": "23.0", "totalCount": 10 } - ] + ], + "totalCount": 10 } \ No newline at end of file diff --git a/cypress/fixtures/searchExact.json b/cypress/fixtures/searchExact.json index 718a1c8..2f3262d 100644 --- a/cypress/fixtures/searchExact.json +++ b/cypress/fixtures/searchExact.json @@ -389,5 +389,6 @@ "ver_latest": "23.0", "totalCount": 905 } - ] + ], + "totalCount": 905 } \ No newline at end of file diff --git a/cypress/fixtures/searchTags.json b/cypress/fixtures/searchTags.json index 2887a2a..e8bc65b 100644 --- a/cypress/fixtures/searchTags.json +++ b/cypress/fixtures/searchTags.json @@ -350,5 +350,6 @@ "ver_latest": "23.0", "totalCount": 888 } - ] + ], + "totalCount": 888 } \ No newline at end of file diff --git a/cypress/support/commands.js b/cypress/support/commands.js index b3aff17..f484900 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -33,94 +33,105 @@ Cypress.Commands.add('assertValueCopiedToClipboard', value => { }) Cypress.Commands.add('interceptAll', () => { + // console.log('Intercepted:', req.method, req.url) cy.intercept('GET', /https.*json$/).as('jsonLink') cy.intercept('GET', /^\/\w*\.json$/).as('jsonLocal') - cy.intercept('POST', "https://data.mongodb-api.com/app/data-ejhjf/endpoint/data/v1/action/find", (req) => { - if (req.body.filter.id === 'arm64-ubuntu-20.04-boot') { - if (req.body.filter.resource_version) { - if (req.body.filter.resource_version === '0.1.0') { - req.reply({ - fixture: 'getResource2.json' - }) - } else { - req.reply({ - documents: [], - }) - } - } else { + cy.intercept('GET', '**/api/resources/find-resources-in-batch*', (req) => { + const url = new URL(req.url); + const ids = url.searchParams.getAll('id'); + const versions = url.searchParams.getAll('resource_version'); + console.log("in find", url) + console.log(ids) + console.log(versions) + // Check for specific resource requests + if (ids.includes('arm64-ubuntu-20.04-boot')) { + const versionIndex = ids.indexOf('arm64-ubuntu-20.04-boot'); + const requestedVersion = versions[versionIndex]; + + if (requestedVersion === '0.1.0') { + req.reply({ + fixture: 'getResource2.json' + }) + } else if (requestedVersion === 'None') { req.reply({ fixture: 'getResource.json' }) + } else { + req.reply([]) } } else { - req.reply({ - documents: [], - }) + req.reply([]) } }).as('find') - cy.intercept('POST', 'https://data.mongodb-api.com/app/data-ejhjf/endpoint/data/v1/action/aggregate', (req) => { - console.log(req.body.pipeline) - if (req.body.pipeline.length === 5) { - req.reply({ - documents: [], - }) - } - else if (req.body.pipeline.length === 2) { - req.reply({ - fixture: 'filters.json' - }) - } - else if (req.body.pipeline.length === 9) { - console.log(req.body.pipeline[8].$limit) - if (req.body.pipeline[8].$limit === 25) { + cy.intercept('GET', '**/api/resources/search*', (req) => { + const url = new URL(req.url); + const containsStr = url.searchParams.get('contains-str'); + const mustInclude = url.searchParams.get('must-include'); + const pageSize = parseInt(url.searchParams.get('page-size')) || 10; + const page = parseInt(url.searchParams.get('page')) || 1; + console.log("in cypress") + console.log('Search params:', { containsStr, mustInclude, pageSize, page }); + + if (mustInclude) { + // Parse must-include filters + const filters = mustInclude.split(';').reduce((acc, filter) => { + const [field, ...values] = filter.split(','); + acc[field] = values; + return acc; + }, {}); + + if (filters.category) { + console.log("category") req.reply({ - fixture: 'search25.json' + fixture: 'searchDiskimage.json' }) - } - else { + } else if (filters.architecture) { + console.log("architecture") + req.reply({ + fixture: 'searchArchitecture.json' + }) + } else if (filters.tags) { + req.reply({ + fixture: 'searchTags.json' + }) + } else { + console.log("exact") req.reply({ fixture: 'searchExact.json' }) } - } - else if (req.body.pipeline.length === 10) { - console.log(req.body.pipeline[0].$match.$and[0]) - // check if key is "category" - if (req.body.pipeline[0].$match.$and[0].category) { + } else if (pageSize) { + // Basic search with different page sizes + if (pageSize === 25) { + console.log("page 25") req.reply({ - fixture: 'searchDiskimage.json' + fixture: 'search25.json' }) - } else if (req.body.pipeline[0].$match.$and[0].architecture) { + } else { + console.log("default page exact") req.reply({ - fixture: 'searchArchitecture.json' + fixture: 'searchExact.json' }) } - } - else if (req.body.pipeline.length === 11) { - req.reply({ - fixture: 'searchExact.json' - }) - } - else if (req.body.pipeline.length === 14) { - req.reply({ - fixture: 'searchTags.json' - }) - } - else { + } else { + console.log("else") req.reply({ documents: [], + totalCount: 0 }) } }).as('mongo') - cy.intercept('POST', "https://realm.mongodb.com/api/client/v2.0/app/data-ejhjf/auth/providers/api-key/login", { - fixture: 'login.json' - }).as('login') + + // Intercept filters request (replaces old MongoDB aggregate for filters) + cy.intercept('GET', '**/api/resources/filters*', { + fixture: 'filters.json' + }).as('filters') }) Cypress.Commands.add('waitFirst', () => { const resource = Object.keys(Cypress.env('SOURCES'))[0] if (Cypress.env('SOURCES')[resource].isMongo) { - cy.wait(['@mongo']) + // cy.wait(['@mongo']) } else { cy.waitJSON(Cypress.env('SOURCES')[resource].url.includes('http')) } @@ -128,11 +139,11 @@ Cypress.Commands.add('waitFirst', () => { }) Cypress.Commands.add('waitAll', value => { - cy.wait(['@kiwi', '@resources', '@mongo']) + cy.wait(['@kiwi', '@resources', '@filters']) }) Cypress.Commands.add('waitMongo', () => { - cy.wait(['@mongo']) + cy.wait(['@filters']) }) Cypress.Commands.add('waitJSON', (isUrl) => { @@ -145,6 +156,7 @@ Cypress.Commands.add('waitJSON', (isUrl) => { Cypress.Commands.add('waitAuto', () => { const resources = Cypress.env('SOURCES') + console.log("resouces", resources) Object.keys(resources).forEach((i) => { if (resources[i].isMongo) { cy.wait(['@mongo']) diff --git a/gem5.config.json b/gem5.config.json index dab2bc4..4e73ddc 100644 --- a/gem5.config.json +++ b/gem5.config.json @@ -5,9 +5,7 @@ "dataSource": "gem5-vision", "database": "gem5-vision", "collection": "resources", - "url": "https://data.mongodb-api.com/app/data-ejhjf/endpoint/data/v1", - "authUrl": "https://realm.mongodb.com/api/client/v2.0/app/data-ejhjf/auth/providers/api-key/login", - "apiKey": "OIi5bAP7xxIGK782t8ZoiD2BkBGEzMdX3upChf9zdCxHSnMoiTnjI22Yw5kOSgy9", + "url": "https://api.gem5.org/api/resources", "isMongo": true } } diff --git a/pages/api/mongodb/getFilters.js b/pages/api/mongodb/getFilters.js index 4baa130..ad4236a 100644 --- a/pages/api/mongodb/getFilters.js +++ b/pages/api/mongodb/getFilters.js @@ -1,62 +1,45 @@ -import getToken from "./getToken"; - /** * @function getFilters * @async - * @description This asynchronous function fetches distinct categories, architectures, and gem5 versions from a specified data source using MongoDB aggregation pipeline. + * @description This asynchronous function fetches distinct categories, architectures, and gem5 versions from MongoDB database * It takes in an access token, URL, data source, database, and collection as input parameters, and returns an object containing the * distinct categories, architectures, and gem5 versions sorted in ascending or descending order. - * @param {string} accessToken - The access token for authentication. * @param {string} url - The URL of the data source. - * @param {string} dataSource - The name of the data source. - * @param {string} database - The name of the database. - * @param {string} collection - The name of the collection. * @returns {Object} - An object containing the distinct categories, architectures, and gem5 versions sorted in ascending or descending order. */ -async function getFilters(accessToken, url, dataSource, database, collection) { +async function getFilters(url) { // get all distinct categories from resources - const res = await fetch(`${url}/action/aggregate`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Access-Control-Request-Headers': '*', - "Authorization": "Bearer " + accessToken, - }, - body: JSON.stringify({ - "dataSource": dataSource, - "database": database, - "collection": collection, - "pipeline": [ - { - "$unwind": "$gem5_versions" - }, - { - "$group": { - "_id": null, - "category": { "$addToSet": "$category" }, - "architecture": { "$addToSet": "$architecture" }, - "gem5_versions": { "$addToSet": "$gem5_versions" } - } - } - ] - }) - }).catch(err => console.log(err)); - let filters = await res.json(); - if (res.status != 200 || filters['documents'].length == 0) { + try { + const res = await fetch(`${url}/filters`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }); + + // Check if status is not 200 + if (res.status !== 200) { + console.log("Error: " + res.status); + return { + "category": [], + "architecture": [], + "gem5_versions": [] + }; + } + + // Parse the response + const filters = await res.json(); + + // Return the filters directly since the API already formats them correctly + return filters; + } catch (err) { + console.log("Error fetching filters:", err); return { "category": [], "architecture": [], "gem5_versions": [] - } + }; } - filters['documents'][0]['architecture'] = filters['documents'][0]['architecture'].filter(architecture => architecture != null); - delete filters['documents'][0]['_id']; - - filters['documents'][0]['gem5_versions'] = filters['documents'][0]['gem5_versions'] - filters['documents'][0]['category'].sort(); - filters['documents'][0]['architecture'].sort(); - filters['documents'][0]['gem5_versions'].sort().reverse(); - return filters['documents'][0]; } /** @@ -68,7 +51,6 @@ async function getFilters(accessToken, url, dataSource, database, collection) { export default async function getFiltersMongoDB(database) { let privateResources = process.env.SOURCES; let privateResource = privateResources[database]; - let privateAccessToken = await getToken(database); - let privateFilters = await getFilters(privateAccessToken, privateResource.url, privateResource.dataSource, privateResource.database, privateResource.collection); + let privateFilters = await getFilters(privateResource.url); return privateFilters; } diff --git a/pages/api/mongodb/getResourceByID.js b/pages/api/mongodb/getResourceByID.js index 0fb515e..97dbcb8 100644 --- a/pages/api/mongodb/getResourceByID.js +++ b/pages/api/mongodb/getResourceByID.js @@ -1,92 +1,48 @@ import compareVersions from "../compareVersions"; -import getToken from "./getToken"; /** * @function * @async * @description Retrieves a resource by ID from a specified data source, database, and collection. * If a version is provided, it retrieves the resource with the matching ID and version. - * @param {string} token - The access token for authentication. * @param {string} url - The base URL of the API. - * @param {string} dataSource - The name of the data source. - * @param {string} database - The name of the database. - * @param {string} collection - The name of the collection. * @param {string} id - The ID of the resource to retrieve. * @param {string|null} version - The version of the resource to retrieve. * If not provided, the latest version will be retrieved. * @returns {Object} - The retrieved resource object, including its metadata and associated workloads. */ -async function getResourceByID(token, url, dataSource, database, collection, id, version = null) { - const res = await fetch(`${url}/action/find`, { - method: 'POST', +async function getResourceByID(url, id, version = null) { + + let params = new URLSearchParams(); + params.append("id", id) + if (version != null) { + params.append("resource_version", version) + } else { + params.append("resource_version", "None") + } + + const res = await fetch(`${url}/find-resources-in-batch?${params.toString()}`, { + method: 'GET', headers: { 'Content-Type': 'application/json', - // 'api-key': 'pKkhRJGJaQ3NdJyDt69u4GPGQTDUIhHlx4a3lrKUNx2hxuc8uba8NrP3IVRvlzlo', - 'Access-Control-Request-Headers': '*', - // 'origin': 'https://gem5vision.github.io', - "Authorization": "Bearer " + token, }, - body: JSON.stringify({ - "dataSource": dataSource, - "database": database, - "collection": collection, - "filter": version ? { - "id": id, - "resource_version": version - } : { - "id": id - } - }) }).catch(err => console.log(err)); let resource = await res.json(); - if (res.status != 200 || resource['documents'] === null || resource['documents'].length === 0) { + if (res.status != 200 || resource === null || resource.length === 0) { return { error: 'Resource not found' } } - resource = resource['documents'].sort((a, b) => -compareVersions(a.resource_version, b.resource_version))[0]; + resource = resource.sort((a, b) => -compareVersions(a.resource_version, b.resource_version))[0]; - const dependendWorkloads = await fetch(`${url}/action/aggregate`, { - method: 'POST', + const dependendWorkloads = await fetch(`${url}/get-dependent-workloads?${params.toString()}`, { + method: 'GET', headers: { 'Content-Type': 'application/json', - 'Access-Control-Request-Headers': '*', - 'Authorization': 'Bearer ' + token, - }, - body: JSON.stringify({ - "dataSource": dataSource, - "database": database, - "collection": collection, - "pipeline": [ - { - "$match": { - "category": "workload" - } - }, - { - "$addFields": { - "resources": { - "$objectToArray": "$resources" - } - } - }, - { - "$unwind": "$resources" - }, - { - "$match": { - "resources.v": id - } - }, - { - "$group": { - "_id": "$id", - } - } - ] - }) + } }).catch(err => console.log(err)); let workloads = await dependendWorkloads.json(); - resource.workloads_mapping = Object.values(workloads['documents']).map(workload => workload['_id']); + + resource.workloads_mapping = Object.values(workloads).map(workload => workload['_id']); return resource; } @@ -99,9 +55,8 @@ async function getResourceByID(token, url, dataSource, database, collection, id, * @returns {json} The resource in JSON format. */ export default async function getResourceByIDMongoDB(id, database = null, version = null) { - const token = await getToken(database); let privateResources = process.env.SOURCES[database]; - const resource = await getResourceByID(token, privateResources.url, privateResources.dataSource, privateResources.database, privateResources.collection, id, version); + const resource = await getResourceByID(privateResources.url,id, version); resource['database'] = database; return resource; } \ No newline at end of file diff --git a/pages/api/mongodb/getResourcesByQuery.js b/pages/api/mongodb/getResourcesByQuery.js index 4045658..9f64326 100644 --- a/pages/api/mongodb/getResourcesByQuery.js +++ b/pages/api/mongodb/getResourcesByQuery.js @@ -1,363 +1,75 @@ -import getToken from "./getToken"; - -/** - * @function getSort - * @description This function returns a sort object based on the provided sort parameter. - * The returned sort object can be used in a MongoDB query to specify the sorting order of the results. - * @param {string} sort - The sort parameter to determine the sorting order. - * Possible values are: "date" to sort by date in descending order, - * "name" to sort by name (or ID) in ascending order, - * "version" to sort by version in descending order, - * "id_asc" to sort by ID in ascending order, - * "id_desc" to sort by ID in descending order. - * If not provided or an invalid value is provided, resources will be sorted by score in descending order by default. - * @returns {Object} - A sort object that can be used in a MongoDB query to specify the sorting order of the results. - * @property {number} date - If "date" is provided as the sort parameter, - * the value of this property will be -1 to sort by date in descending order. - * @property {number} id - If "name", "id_asc", or "id_desc" is provided as the sort parameter, - * the value of this property will be either 1 or -1 to specify the sorting order of the ID field. - * @property {number} ver_latest - If "version" is provided as the sort parameter, - * the value of this property will be -1 to sort by version in descending order. - * @property {number} score - If an invalid or no sort parameter is provided, - * the value of this property will be -1 to sort by score in descending order by default. - */ -function getSort(sort) { - switch (sort) { - case "date": - return { date: -1 }; - case "name": - return { id: 1 }; - case "version": - return { ver_latest: -1 }; - case "id_asc": - return { id: 1 }; - case "id_desc": - return { id: -1 }; - default: - return { - score: -1, - }; - } -} - -/** - * @function getLatestVersionPipeline - * @description This function returns a MongoDB aggregation pipeline that can be used - * to retrieve documents with the latest version based on the "resource_version" field. - * The pipeline performs several stages to split the "resource_version" into parts, convert them to integers, - * sort them in descending order, group them by "id" field, and return the document with the latest version along - * with its "id" and "latest_version" fields. - * @returns {Array} - An array representing the MongoDB aggregation pipeline to retrieve documents with the latest version. - */ -function getLatestVersionPipeline() { - let pipeline = [ - { - $addFields: { - resource_version_parts: { - $map: { - input: { - $split: ["$resource_version", "."], - }, - in: { $toInt: "$$this" }, - }, - }, - }, - }, - { - $sort: { - id: 1, - "resource_version_parts.0": -1, - "resource_version_parts.1": -1, - "resource_version_parts.2": -1, - "resource_version_parts.3": -1, - }, - }, - { - $group: { - _id: "$id", - latest_version: { - $first: "$resource_version", - }, - document: { $first: "$$ROOT" }, - }, - }, - { - $replaceRoot: { - newRoot: { - $mergeObjects: [ - "$document", - { - id: "$_id", - latest_version: "$latest_version", - }, - ], - }, - }, - }, - ] - return pipeline; -} - -/** - * @function getSearchPipeline - * @description This function returns a MongoDB aggregation pipeline that can be used to perform text search - * on a collection based on the provided query object. - * The pipeline uses the $search stage to perform compound text search on multiple fields, - * including "id", "description", "category", "architecture", and "tags". - * It applies boost to the "id" field to prioritize matching results, - * and also adds a "score" field to each document to represent the search score. - * @param {Object} queryObject - The query object containing the search query and options. - * @param {string} queryObject.query - The search query string. - * @returns {Array} - An array representing the MongoDB aggregation pipeline to perform text search. - */ -function getSearchPipeline(queryObject) { - // getting current gem5_version to boost search for resources compatible with latest gem5 release - const gem5_version = process.env.GEM5_VERSION; - - let pipeline = [ - { - $search: { - compound: { - should: [ - { - text: { - path: "id", - query: queryObject.query, - score: { - boost: { - value: 10, - }, - }, - }, - }, - { - text: { - path: "gem5_versions", - query: gem5_version, - score: { - boost: { - value: 10, - }, - }, - }, - } - ], - must: [ - { - text: { - query: queryObject.query, - path: [ - "id", - "desciption", - "category", - "architecture", - "tags", - ], - fuzzy: { - maxEdits: 2, - maxExpansions: 100, - }, - }, - }, - ], - }, - }, - }, - { - $addFields: { - score: { - $meta: "searchScore", - }, - }, - }, - ]; - return pipeline; -} - -/** - * @function getFilterPipeline - * @description This function returns a MongoDB aggregation pipeline that can be used to apply filters - * to a collection based on the provided query object. - * The pipeline applies filters based on tags, gem5_versions, category, and architecture fields in the documents. - * It unwinds and matches the specified fields in the query object, and groups the results to eliminate duplicates. - * The resulting pipeline can be used in conjunction with other aggregation stages to further process the filtered documents. - * @param {Object} queryObject - The query object containing the filter criteria. - * @param {Array} queryObject.tags - An array of tags to filter by. - * @param {Array} queryObject.gem5_versions - An array of gem5 versions to filter by. - * @param {Array} queryObject.category - An array of categories to filter by. - * @param {Array} queryObject.architecture - An array of architectures to filter by. - * @returns {Array} - An array representing the MongoDB aggregation pipeline to apply filters. - */ -function getFilterPipeline(queryObject) { - let pipeline = [] - // adding filter by gem5 version if the user has selected one - if (queryObject.tags) { - pipeline.push(...[ - { - $addFields: { - tag: "$tags", - }, - }, - { - $unwind: "$tag", - }, - { - $match: { - tag: { - $in: queryObject.tags || [], - }, - }, - }, - { - $group: { - _id: "$_id", - doc: { - $first: "$$ROOT", - }, - }, - }, - { - $replaceRoot: { - newRoot: "$doc", - }, - }, - ]); - } - if (queryObject.gem5_versions) { - pipeline.push(...[ - { - $addFields: { - version: "$gem5_versions", - }, - }, - { - $unwind: "$version", - }, - { - $match: { - version: { - $in: queryObject.gem5_versions || [], - }, - }, - }, - { - $group: { - _id: "$_id", - doc: { - $first: "$$ROOT", - }, - }, - }, - { - $replaceRoot: { - newRoot: "$doc", - }, - }, - ]); - } - // adding the other fileters such as category and architecture to the serch pipeline - let match = []; - if (queryObject.category) { - match.push({ category: { $in: queryObject.category || [] } }); - } - if (queryObject.architecture) { - match.push({ architecture: { $in: queryObject.architecture || [] } }); - } - // adding the match to the pipeline if there are some filters selected - if (match.length > 0) { - pipeline.push({ - $match: { - $and: match, - }, - }); - } - return pipeline; -} - -/** - * @function getSortPipeline - * @description This function returns a MongoDB aggregation pipeline that can be used to apply sorting to a collection based on the provided query object. - * The pipeline adds a field "ver_latest" to each document in the collection, representing the maximum value in the "gem5_versions" array field. - * It then sorts the documents based on the specified sort criteria from the query object using the "getSort" helper function. - * @param {Object} queryObject - The query object containing the sort criteria. - * @param {string} queryObject.sort - The sort criteria to apply. - * Should be a string in the format "field:direction", where "field" is the field to sort by and "direction" - * is the sorting direction ("asc" for ascending, "desc" for descending). - * @returns {Array} - An array representing the MongoDB aggregation pipeline to apply sorting. - */ -function getSortPipeline(queryObject) { - let pipeline = [ - { - $addFields: { - ver_latest: { - $max: "$gem5_versions", - }, - }, - }, - { - $sort: getSort(queryObject.sort), - }]; - return pipeline; -} - -/** - * @function getPagePipeline - * @description This function returns a MongoDB aggregation pipeline that can be used to implement pagination for a collection, - * based on the provided current page number and page size. - * The pipeline uses the MongoDB $setWindowFields, $skip, and $limit stages to calculate the total count of documents in the collection, - * skip the appropriate number of documents based on the current page number and page size, and limit the number of documents returned per page. - * @param {number} currentPage - The current page number. - * @param {number} pageSize - The number of documents to display per page. - * @returns {Array} - An array representing the MongoDB aggregation pipeline to implement pagination. - */ -function getPagePipeline(currentPage, pageSize) { - let pipeline = [ - { - $setWindowFields: { output: { totalCount: { $count: {} } } }, - }, - { - $skip: (currentPage - 1) * pageSize, - }, - { - $limit: pageSize, - }, - ]; - return pipeline; -} - /** * @function getPipeline * @description This function returns a MongoDB aggregation pipeline based on the provided query object, * current page number, and page size. The pipeline includes stages for handling search query, filtering, sorting, and pagination. * It can be used to construct a MongoDB aggregation pipeline for retrieving filtered and paginated results from a collection based on the given query object. * @param {Object} queryObject - The query object containing search query, sort, and filter parameters. - * @param {string} queryObject.query - The search query. - * @param {string} queryObject.sort - The sorting parameter. * @param {number} currentPage - The current page number. * @param {number} pageSize - The number of documents to display per page. * @returns {Array} - An array representing the MongoDB aggregation pipeline for retrieving filtered and paginated results. */ function getPipeline(queryObject, currentPage, pageSize) { - let pipeline = []; + // Initialize URL parameters + let params = new URLSearchParams(); + if (queryObject.query.trim() === "") { if (queryObject.sort === "relevance") { queryObject.sort = "default"; } } - // adding search query if something is entered - if (queryObject.query.trim() !== "") { - pipeline.push(...getSearchPipeline(queryObject)); + // Add search term (contains-str) + if (queryObject.query && queryObject.query.trim() !== "") { + params.append('contains-str', queryObject.query.trim()); + } else { + // Default empty search term + params.append('contains-str', ''); + } + + // Add filter criteria (must-include) + const filterParams = buildMustIncludeParams(queryObject); + if (filterParams) { + params.append('must-include', filterParams); } - // adding the filters to the pipeline - pipeline.push(...getFilterPipeline(queryObject)); - // getting latest resource version for each resource and removing the rest - pipeline.push(...getLatestVersionPipeline()); - // adding the sorting to the pipeline - pipeline.push(...getSortPipeline(queryObject)); - // adding the pagination to the pipeline - pipeline.push(...getPagePipeline(currentPage, pageSize)); - return pipeline; + + // Add pagination parameters + params.append('page', currentPage); + params.append('page-size', pageSize); + params.append('sort', queryObject.sort); + + return params; +} +/** + * @function buildMustIncludeParams + * @description Converts filter object from the queryObject to the API's must-include format. + * Format: field1,value1,value2;field2,value1,value2 + * @param {Object} queryObject - The query object containing filter criteria. + * @returns {string} - Formatted filter string for the API. + */ +function buildMustIncludeParams(queryObject) { + const filters = []; + + // Handle tags filter + if (queryObject.tags && queryObject.tags.length > 0) { + filters.push(`tags,${queryObject.tags.join(',')}`); + } + + // Handle gem5_versions filter + if (queryObject.gem5_versions && queryObject.gem5_versions.length > 0) { + filters.push(`gem5_versions,${queryObject.gem5_versions.join(',')}`); + } + + // Handle category filter + if (queryObject.category && queryObject.category.length > 0) { + filters.push(`category,${queryObject.category.join(',')}`); + } + + // Handle architecture filter + if (queryObject.architecture && queryObject.architecture.length > 0) { + filters.push(`architecture,${queryObject.architecture.join(',')}`); + } + + return filters.join(';'); } /** @@ -366,57 +78,56 @@ function getPipeline(queryObject, currentPage, pageSize) { * @description This asynchronous function fetches search results from a specified data source using MongoDB aggregation pipeline. * It takes in an access token, URL, data source, database, collection, query object, current page number, and page size as input parameters, * and returns an array containing the search results and total count of documents matching the search criteria. - * @param {string} accessToken - The access token for authentication. * @param {string} url - The URL of the data source. - * @param {string} dataSource - The name of the data source. - * @param {string} database - The name of the database. - * @param {string} collection - The name of the collection. * @param {Object} queryObject - The query object containing search query, sort, and filter parameters. - * @param {string} queryObject.query - The search query. - * @param {string} queryObject.sort - The sorting parameter. * @param {number} currentPage - The current page number. * @param {number} pageSize - The number of documents to display per page. * @returns {Array} - An array containing the search results and total count of documents matching the search criteria. */ async function getSearchResults( - accessToken, url, - dataSource, - database, - collection, queryObject, currentPage, pageSize ) { - let resources = []; - const pipeline = getPipeline(queryObject, currentPage, pageSize); - const res = await fetch(`${url}/action/aggregate`, { - method: "POST", - headers: { - "Content-Type": "application/json", - "Access-Control-Request-Headers": "*", - Authorization: "Bearer " + accessToken, - }, - // also apply filters on - body: JSON.stringify({ - dataSource: dataSource, - database: database, - collection: collection, - pipeline: pipeline, - }), - }).catch((err) => console.log(err)); - resources = await res.json(); - // check if status is not 200 - if (res.status !== 200) { - console.log("Error: " + res.status); + try { + // Build the query parameters + const params = getPipeline(queryObject, currentPage, pageSize); + // Make the API call to the new endpoint + const res = await fetch(`${url}/search?${params.toString()}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + // "x-functions-key": accessToken, // Using API token as x-functions-key for Azure Functions + }, + }); + + // Check if status is not 200 + if (res.status !== 200) { + console.log("Error: " + res.status); + return [[], 0]; + } + + // Parse the response + const responseData = await res.json(); + let documents = responseData.documents + console.log(documents) + // If there are no results, return empty array and count 0 + if (!documents || !Array.isArray(documents) || documents.length === 0) { + return [[], 0]; + } + + // Calculate the total count + // Note: The API might return the total count in a different format + // If the API returns total count separately, this logic should be updated + const totalCount = responseData.totalCount; + + // Return in the same format as the original function + return [documents, totalCount]; + } catch (err) { + console.log("Error fetching resources:", err); return [[], 0]; } - return [ - resources["documents"], - resources["documents"].length > 0 - ? resources["documents"][0].totalCount - : 0, - ]; } @@ -431,12 +142,8 @@ async function getSearchResults( export default async function getResourcesByQueryMongoDB(queryObject, currentPage, pageSize, database) { let privateResources = process.env.SOURCES; let privateResource = privateResources[database]; - let privateAccessToken = await getToken(database); - let privateResourceResults = await getSearchResults(privateAccessToken, + let privateResourceResults = await getSearchResults( privateResource.url, - privateResource.dataSource, - privateResource.database, - privateResource.collection, queryObject, currentPage, pageSize); diff --git a/pages/api/mongodb/getToken.js b/pages/api/mongodb/getToken.js deleted file mode 100644 index ebd707c..0000000 --- a/pages/api/mongodb/getToken.js +++ /dev/null @@ -1,51 +0,0 @@ - -async function getAccessToken(url, key) { - let token = await fetch(url, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Access-Control-Request-Headers': '*', - }, - body: JSON.stringify({ - "key": key - }) - }).catch(err => console.log(err)); - let tokenJson = await token.json(); - return { - accessToken: tokenJson['access_token'], - expires: Date.now() + 30 * 60 * 1000, - refreshToken: tokenJson['refresh_token'] - } -} - -/** - * @function - * @async - * @description Retrieves an access token by sending an API key to the Realm API to authenticate annonymously. - * @returns {string} The access token string. -*/ -export default async function getToken(key = null) { - // Send API key to Realm API to retrieve access token - if (!key) { - key = Object.keys(process.env.SOURCES)[0]; - } - let privateENV = process.env.SOURCES[key]; - let token = sessionStorage.getItem('token'); - if (token) { - token = JSON.parse(token); - } else { - token = {}; - } - if (token && token[key] && token[key].expires >= Date.now()) { - return token[key].accessToken; - } - else { - token[key] = await getAccessToken(privateENV.authUrl, privateENV.apiKey); - if (!token[key].accessToken) { - console.log('Error: Could not retrieve access token.'); - return; - } - sessionStorage.setItem('token', JSON.stringify(token)); - return token[key].accessToken; - } -} \ No newline at end of file diff --git a/pages/api/mongodb/getVersionsByID.js b/pages/api/mongodb/getVersionsByID.js index e6f1bdf..553f0fc 100644 --- a/pages/api/mongodb/getVersionsByID.js +++ b/pages/api/mongodb/getVersionsByID.js @@ -1,43 +1,26 @@ -import getToken from "./getToken"; import compareVersions from "../compareVersions"; /** * @function * @async * @description Fetches versions of a resource with a specific ID from a specified data source, database, and collection using a Bearer token for authorization. - * @param {string} token - The access token used for authorization. * @param {string} url - The URL of the API endpoint. - * @param {string} dataSource - The data source to fetch resources from. - * @param {string} database - The database to fetch resources from. - * @param {string} collection - The collection to fetch resources from. * @param {string} id - The ID of the resource to retrieve versions for. * @returns {Array} - An array of resource versions retrieved from the specified data source, database, and collection, sorted in descending order of resource version. * @throws {Error} - Throws an error if the fetch request fails. */ -async function getVersionsByID(token, url, dataSource, database, collection, id) { - const res = await fetch(`${url}/action/find`, { - method: 'POST', +async function getVersionsByID(url, id) { + const res = await fetch(`${url}/find-resources-in-batch?id=${id}&resource_version=None`, { + method: 'GET', headers: { 'Content-Type': 'application/json', - // 'api-key': 'pKkhRJGJaQ3NdJyDt69u4GPGQTDUIhHlx4a3lrKUNx2hxuc8uba8NrP3IVRvlzlo', - 'Access-Control-Request-Headers': '*', - // 'origin': 'https://gem5vision.github.io', - "Authorization": "Bearer " + token, }, - body: JSON.stringify({ - "dataSource": dataSource, - "database": database, - "collection": collection, - "filter": { - "id": id - } - }) }).catch(err => console.log(err)); let resource = await res.json(); - if (res.status != 200 || resource['documents'] === null) { + if (res.status != 200 || resource === null) { return { error: 'Resource not found' } } - resource = resource['documents'].sort((a, b) => -compareVersions(a.resource_version, b.resource_version)); + resource = resource.sort((a, b) => -compareVersions(a.resource_version, b.resource_version)); return resource; } @@ -53,9 +36,8 @@ export default async function getVersionsByIDMongoDB(id, database = null) { if (!database) { database = Object.keys(process.env.SOURCES)[0]; } - const token = await getToken(database); let privateResources = process.env.SOURCES[database]; - const resource = await getVersionsByID(token, privateResources.url, privateResources.dataSource, privateResources.database, privateResources.collection, id); + const resource = await getVersionsByID(privateResources.url, id); resource.forEach(res => { res['database'] = database; });