Merge pull request #2074 from spotify/rugvip/discovery
[RFC] Add DiscoveryApi
This commit is contained in:
@@ -18,25 +18,21 @@ import { rest } from 'msw';
|
||||
import { setupServer } from 'msw/node';
|
||||
import { CatalogClient } from './CatalogClient';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { UrlPatternDiscovery } from '@backstage/core';
|
||||
|
||||
const server = setupServer();
|
||||
const mockBaseUrl = 'http://backstage:9191/i-am-a-mock-base';
|
||||
const discoveryApi = UrlPatternDiscovery.compile(mockBaseUrl);
|
||||
|
||||
describe('CatalogClient', () => {
|
||||
beforeAll(() => server.listen());
|
||||
afterEach(() => server.resetHandlers());
|
||||
afterAll(() => server.close());
|
||||
const mockApiOrigin = 'http://backstage:9191';
|
||||
const mockBasePath = '/i-am-a-mock-base';
|
||||
let client = new CatalogClient({
|
||||
apiOrigin: mockApiOrigin,
|
||||
basePath: mockBasePath,
|
||||
});
|
||||
|
||||
let client = new CatalogClient({ discoveryApi });
|
||||
|
||||
beforeEach(() => {
|
||||
client = new CatalogClient({
|
||||
apiOrigin: mockApiOrigin,
|
||||
basePath: mockBasePath,
|
||||
});
|
||||
client = new CatalogClient({ discoveryApi });
|
||||
});
|
||||
|
||||
describe('getEntiies', () => {
|
||||
@@ -61,7 +57,7 @@ describe('CatalogClient', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
server.use(
|
||||
rest.get(`${mockApiOrigin}${mockBasePath}/entities`, (_, res, ctx) => {
|
||||
rest.get(`${mockBaseUrl}/entities`, (_, res, ctx) => {
|
||||
return res(ctx.json(defaultResponse));
|
||||
}),
|
||||
);
|
||||
@@ -75,15 +71,12 @@ describe('CatalogClient', () => {
|
||||
it('builds entity search filters properly', async () => {
|
||||
expect.assertions(2);
|
||||
server.use(
|
||||
rest.get(
|
||||
`${mockApiOrigin}${mockBasePath}/entities`,
|
||||
(req, res, ctx) => {
|
||||
expect(req.url.searchParams.toString()).toBe(
|
||||
'a=1&b=2&b=3&%C3%B6=%3D',
|
||||
);
|
||||
return res(ctx.json([]));
|
||||
},
|
||||
),
|
||||
rest.get(`${mockBaseUrl}/entities`, (req, res, ctx) => {
|
||||
expect(req.url.searchParams.toString()).toBe(
|
||||
'a=1&b=2&b=3&%C3%B6=%3D',
|
||||
);
|
||||
return res(ctx.json([]));
|
||||
}),
|
||||
);
|
||||
|
||||
const entities = await client.getEntities({
|
||||
|
||||
@@ -20,24 +20,17 @@ import {
|
||||
LOCATION_ANNOTATION,
|
||||
} from '@backstage/catalog-model';
|
||||
import { CatalogApi, EntityCompoundName } from './types';
|
||||
import { DiscoveryApi } from '@backstage/core';
|
||||
|
||||
export class CatalogClient implements CatalogApi {
|
||||
private apiOrigin: string;
|
||||
private basePath: string;
|
||||
private readonly discoveryApi: DiscoveryApi;
|
||||
|
||||
constructor({
|
||||
apiOrigin,
|
||||
basePath,
|
||||
}: {
|
||||
apiOrigin: string;
|
||||
basePath: string;
|
||||
}) {
|
||||
this.apiOrigin = apiOrigin;
|
||||
this.basePath = basePath;
|
||||
constructor(options: { discoveryApi: DiscoveryApi }) {
|
||||
this.discoveryApi = options.discoveryApi;
|
||||
}
|
||||
|
||||
private async getRequired(path: string): Promise<any> {
|
||||
const url = `${this.apiOrigin}${this.basePath}${path}`;
|
||||
const url = `${await this.discoveryApi.getBaseUrl('catalog')}${path}`;
|
||||
const response = await fetch(url);
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -50,7 +43,7 @@ export class CatalogClient implements CatalogApi {
|
||||
}
|
||||
|
||||
private async getOptional(path: string): Promise<any | undefined> {
|
||||
const url = `${this.apiOrigin}${this.basePath}${path}`;
|
||||
const url = `${await this.discoveryApi.getBaseUrl('catalog')}${path}`;
|
||||
const response = await fetch(url);
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -100,7 +93,7 @@ export class CatalogClient implements CatalogApi {
|
||||
|
||||
async addLocation(type: string, target: string) {
|
||||
const response = await fetch(
|
||||
`${this.apiOrigin}${this.basePath}/locations`,
|
||||
`${await this.discoveryApi.getBaseUrl('catalog')}/locations`,
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -135,7 +128,7 @@ export class CatalogClient implements CatalogApi {
|
||||
|
||||
async removeEntityByUid(uid: string): Promise<void> {
|
||||
const response = await fetch(
|
||||
`${this.apiOrigin}${this.basePath}/entities/by-uid/${uid}`,
|
||||
`${await this.discoveryApi.getBaseUrl('catalog')}/entities/by-uid/${uid}`,
|
||||
{
|
||||
method: 'DELETE',
|
||||
},
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
githubAuthApiRef,
|
||||
GithubAuth,
|
||||
OAuthRequestManager,
|
||||
UrlPatternDiscovery,
|
||||
} from '@backstage/core';
|
||||
import { gitOpsApiRef, GitOpsRestApi } from '../../api';
|
||||
|
||||
@@ -37,8 +38,9 @@ describe('ProfileCatalog', () => {
|
||||
[
|
||||
githubAuthApiRef,
|
||||
GithubAuth.create({
|
||||
backendUrl: 'http://localhost:7000',
|
||||
basePath: '/auth/',
|
||||
discoveryApi: UrlPatternDiscovery.compile(
|
||||
'http://example.com/{{pluginId}}',
|
||||
),
|
||||
oauthRequestApi,
|
||||
}),
|
||||
],
|
||||
|
||||
@@ -20,20 +20,13 @@ import {
|
||||
RollbarProject,
|
||||
RollbarTopActiveItem,
|
||||
} from './types';
|
||||
import { DiscoveryApi } from '@backstage/core';
|
||||
|
||||
export class RollbarClient implements RollbarApi {
|
||||
private apiOrigin: string;
|
||||
private basePath: string;
|
||||
private readonly discoveryApi: DiscoveryApi;
|
||||
|
||||
constructor({
|
||||
apiOrigin,
|
||||
basePath,
|
||||
}: {
|
||||
apiOrigin: string;
|
||||
basePath: string;
|
||||
}) {
|
||||
this.apiOrigin = apiOrigin;
|
||||
this.basePath = basePath;
|
||||
constructor(options: { discoveryApi: DiscoveryApi }) {
|
||||
this.discoveryApi = options.discoveryApi;
|
||||
}
|
||||
|
||||
async getAllProjects(): Promise<RollbarProject[]> {
|
||||
@@ -59,7 +52,7 @@ export class RollbarClient implements RollbarApi {
|
||||
}
|
||||
|
||||
private async get(path: string): Promise<any> {
|
||||
const url = `${this.apiOrigin}${this.basePath}${path}`;
|
||||
const url = `${await this.discoveryApi.getBaseUrl('rollbar')}${path}`;
|
||||
const response = await fetch(url);
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createApiRef } from '@backstage/core';
|
||||
import { createApiRef, DiscoveryApi } from '@backstage/core';
|
||||
import { TemplateEntityV1alpha1 } from '@backstage/catalog-model';
|
||||
|
||||
export const scaffolderApiRef = createApiRef<ScaffolderApi>({
|
||||
@@ -23,18 +23,10 @@ export const scaffolderApiRef = createApiRef<ScaffolderApi>({
|
||||
});
|
||||
|
||||
export class ScaffolderApi {
|
||||
private apiOrigin: string;
|
||||
private basePath: string;
|
||||
private readonly discoveryApi: DiscoveryApi;
|
||||
|
||||
constructor({
|
||||
apiOrigin,
|
||||
basePath,
|
||||
}: {
|
||||
apiOrigin: string;
|
||||
basePath: string;
|
||||
}) {
|
||||
this.apiOrigin = apiOrigin;
|
||||
this.basePath = basePath;
|
||||
constructor(options: { discoveryApi: DiscoveryApi }) {
|
||||
this.discoveryApi = options.discoveryApi;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,7 +38,7 @@ export class ScaffolderApi {
|
||||
template: TemplateEntityV1alpha1,
|
||||
values: Record<string, any>,
|
||||
) {
|
||||
const url = `${this.apiOrigin}${this.basePath}/jobs`;
|
||||
const url = `${await this.discoveryApi.getBaseUrl('scaffolder')}/v1/jobs`;
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@@ -65,9 +57,9 @@ export class ScaffolderApi {
|
||||
}
|
||||
|
||||
async getJob(jobId: string) {
|
||||
const url = `${this.apiOrigin}${this.basePath}/job/${encodeURIComponent(
|
||||
jobId,
|
||||
)}`;
|
||||
const url = `${await this.discoveryApi.getBaseUrl(
|
||||
'scaffolder',
|
||||
)}/v1/job/${encodeURIComponent(jobId)}`;
|
||||
return fetch(url).then(x => x.json());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user