diff --git a/e2e/cypress/tests/19-api-v3/07-endpoints.ts b/e2e/cypress/tests/19-api-v3/07-endpoints.ts new file mode 100644 index 000000000..1ca6a1a90 --- /dev/null +++ b/e2e/cypress/tests/19-api-v3/07-endpoints.ts @@ -0,0 +1,25 @@ +describe('Endpoints', () => { + it('GET /routes/availability', () => { + cy.callAPI( + 'ds/api/v3/routes/availability?gatewayId=gw-1234&serviceName=testme', + 'GET' + ).then(({ apiRes: { status, body } }: any) => { + const match = { + available: true, + suggestion: { + serviceName: 'testme', + names: ['testme', 'testme-dev', 'testme-test'], + hosts: [ + 'testme.api.gov.bc.ca', + 'testme.api.dev.gov.bc.ca', + 'testme.api.test.gov.bc.ca', + 'testme-api-gov-bc-ca.dev.api.gov.bc.ca', + 'testme-api-gov-bc-ca.test.api.gov.bc.ca', + ], + }, + } + expect(status).to.be.equal(200) + expect(JSON.stringify(body)).to.be.equal(JSON.stringify(match)) + }) + }) +}) diff --git a/src/controllers/v3/EndpointsController.ts b/src/controllers/v3/EndpointsController.ts index fa44fc6e9..2f386928f 100644 --- a/src/controllers/v3/EndpointsController.ts +++ b/src/controllers/v3/EndpointsController.ts @@ -12,7 +12,13 @@ import { import { KeystoneService } from '../ioc/keystoneInjector'; import { inject, injectable } from 'tsyringe'; import { getRecords, removeEmpty } from '../../batch/feed-worker'; -import { GatewayRoute } from './types'; +import { GatewayRoute, GatewayService } from './types'; + +interface MatchList { + serviceName: string; + names: string[]; + hosts: string[]; +} @injectable() @Route('/routes') @@ -28,50 +34,57 @@ export class EndpointsController extends Controller { @OperationId('check-availability') public async check( @Query() serviceName: string, + @Query() gatewayId: string, @Request() request: any ): Promise { const ctx = this.keystone.sudo(); - const records = await getRecords( - ctx, - 'GatewayRoute', - 'allGatewayRoutes', - [] - ); + const records = await getRecords(ctx, 'GatewayRoute', 'allGatewayRoutes', [ + 'service', + ]); let counter = 0; - let matchHostList; + let matchHostList: MatchList; do { counter++; matchHostList = this.getMatchHostList( - counter == 1 ? serviceName : `${serviceName}-${counter}` + counter == 1 + ? serviceName + : counter == 2 + ? `${gatewayId}-${serviceName}` + : `${gatewayId}-${counter}-${serviceName}` ); - } while (this.isTaken(records, matchHostList.hosts)); + } while (this.isTaken(records, matchHostList)); return { available: counter == 1, - name: matchHostList.serviceName, - host: matchHostList.hosts[0], + suggestion: matchHostList, }; } - private getMatchHostList( - serviceName: string - ): { serviceName: string; hosts: string[] } { + private getMatchHostList(serviceName: string): MatchList { return { serviceName, + names: [`${serviceName}`, `${serviceName}-dev`, `${serviceName}-test`], hosts: [ `${serviceName}.api.gov.bc.ca`, + `${serviceName}.api.dev.gov.bc.ca`, + `${serviceName}.api.test.gov.bc.ca`, `${serviceName}-api-gov-bc-ca.dev.api.gov.bc.ca`, `${serviceName}-api-gov-bc-ca.test.api.gov.bc.ca`, ], }; } - private isTaken(records: any[], matchHosts: string[]): boolean { + private isTaken(records: any[], matchList: MatchList): boolean { return ( records.filter( (r: GatewayRoute) => - r.hosts.filter((h: string) => matchHosts.indexOf(h) >= 0).length > 0 + r.hosts.filter((h: string) => matchList.hosts.indexOf(h) >= 0) + .length > 0 || + matchList.names.filter((n: string) => n == r.name).length > 0 || + matchList.names.filter( + (n: string) => n == (r.service as GatewayService).name + ).length > 0 ).length > 0 ); } diff --git a/src/controllers/v3/openapi.yaml b/src/controllers/v3/openapi.yaml index 64a12a4ec..cd84dd256 100644 --- a/src/controllers/v3/openapi.yaml +++ b/src/controllers/v3/openapi.yaml @@ -853,6 +853,12 @@ paths: required: true schema: type: string + - + in: query + name: gatewayId + required: true + schema: + type: string /gateways/report: get: operationId: report diff --git a/src/controllers/v3/routes.ts b/src/controllers/v3/routes.ts index 2a90d4a04..3de19b1d6 100644 --- a/src/controllers/v3/routes.ts +++ b/src/controllers/v3/routes.ts @@ -645,6 +645,7 @@ export function RegisterRoutes(app: express.Router) { async function EndpointsController_check(request: any, response: any, next: any) { const args = { serviceName: {"in":"query","name":"serviceName","required":true,"dataType":"string"}, + gatewayId: {"in":"query","name":"gatewayId","required":true,"dataType":"string"}, request: {"in":"request","name":"request","required":true,"dataType":"object"}, };