Skip to content

Commit

Permalink
fix: refactor accentuate backend to use REST API instead of database
Browse files Browse the repository at this point in the history
  • Loading branch information
dweber019 committed Aug 29, 2024
1 parent 2409aaa commit e77d210
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 122 deletions.
5 changes: 5 additions & 0 deletions .changeset/brave-beds-cry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@dweber019/backstage-plugin-accentuate-backend': patch
---

Refactor accentuate backend to use REST API instead of database.
1 change: 0 additions & 1 deletion plugins/accentuate-backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
"postpack": "backstage-cli package postpack"
},
"dependencies": {
"@backstage/backend-common": "^0.24.0",
"@backstage/backend-defaults": "^0.4.3",
"@backstage/backend-plugin-api": "^0.8.0",
"@backstage/catalog-model": "^1.6.0",
Expand Down
10 changes: 5 additions & 5 deletions plugins/accentuate-backend/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
import { createRouterFromConfig } from './service/router';
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';
import { AccentuateEntitiesProcessor } from './processor';
import { DatabaseManager } from '@backstage/backend-common';

/**
* @public
Expand Down Expand Up @@ -49,15 +48,16 @@ export const catalogModuleAccentuateProcessor = createBackendModule({
catalog: catalogProcessingExtensionPoint,
logger: coreServices.logger,
config: coreServices.rootConfig,
discovery: coreServices.discovery,
auth: coreServices.auth,
},
async init({ catalog, logger, config }) {
const databaseManager = DatabaseManager.fromConfig(config);
const databaseService = databaseManager.forPlugin('accentuate');
async init({ catalog, logger, config, discovery, auth }) {
catalog.addProcessor(
await AccentuateEntitiesProcessor.fromEnv({
logger,
config,
database: databaseService,
discovery,
auth
}),
);
},
Expand Down
84 changes: 54 additions & 30 deletions plugins/accentuate-backend/src/processor/processor.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { AccentuateEntitiesProcessor } from './processor';
import { ConfigReader } from '@backstage/config';
import { getVoidLogger } from '@backstage/backend-common';
import { AccentuateBackendClient } from '../api';
import { Entity } from '@backstage/catalog-model';
import { ANNOTATION_ACCENTUATE_DISABLE } from '@dweber019/backstage-plugin-accentuate-common';
import { mockCredentials, mockServices } from '@backstage/backend-test-utils';
import { registerMswTestHooks } from '@backstage/test-utils';
import { rest } from 'msw';
import { setupServer } from 'msw/node';

const logger = getVoidLogger();
const logger = mockServices.logger.mock();
const config = new ConfigReader({
accentuate: {
allowedKinds: [
Expand All @@ -20,21 +22,33 @@ const config = new ConfigReader({
});

describe('processor', () => {
const server = setupServer();
registerMswTestHooks(server);

const discovery = mockServices.discovery.mock({
getBaseUrl: jest.fn().mockResolvedValue('http://example.com'),
});
const auth = mockServices.auth();

test('should merge entity with stored data', async () => {
function mockAccentuateBackendClient(): jest.Mocked<AccentuateBackendClient> {
const mock = {
get: jest
.fn()
.mockReturnValue({
data: { spec: { owner: 'group:default/group-1' } },
server.use(
rest.get('http://example.com', async (req, res, ctx) => {
expect(req.headers.get('Authorization')).toBe(
mockCredentials.service.header({
onBehalfOf: await auth.getOwnServiceCredentials(),
targetPluginId: 'accentuate',
}),
};
return mock as unknown as jest.Mocked<AccentuateBackendClient>;
}
);
return res(ctx.json({
data: { spec: { owner: 'group:default/group-1' } },
}));
}),
);
const processor = new AccentuateEntitiesProcessor({
logger,
config,
accentuateBackendClient: mockAccentuateBackendClient(),
discovery,
auth,
});

const entity = {
Expand All @@ -59,20 +73,24 @@ describe('processor', () => {
});

test('should not merge entity if not allowed kind', async () => {
function mockAccentuateBackendClient(): jest.Mocked<AccentuateBackendClient> {
const mock = {
get: jest
.fn()
.mockReturnValue({
data: { spec: { owner: 'group:default/group-1' } },
server.use(
rest.get('http://example.com', async (req, res, ctx) => {
expect(req.headers.get('Authorization')).toBe(
mockCredentials.service.header({
onBehalfOf: await auth.getOwnServiceCredentials(),
targetPluginId: 'accentuate',
}),
};
return mock as unknown as jest.Mocked<AccentuateBackendClient>;
}
);
return res(ctx.json({
data: { spec: { owner: 'group:default/group-1' } },
}));
}),
);
const processor = new AccentuateEntitiesProcessor({
logger,
config,
accentuateBackendClient: mockAccentuateBackendClient(),
discovery,
auth,
});

const entity = {
Expand All @@ -97,16 +115,22 @@ describe('processor', () => {
});

test('should not merge entity if nothing found', async () => {
function mockAccentuateBackendClient(): jest.Mocked<AccentuateBackendClient> {
const mock = {
get: jest.fn().mockReturnValue(undefined),
};
return mock as unknown as jest.Mocked<AccentuateBackendClient>;
}
server.use(
rest.get('http://example.com', async (req, res, ctx) => {
expect(req.headers.get('Authorization')).toBe(
mockCredentials.service.header({
onBehalfOf: await auth.getOwnServiceCredentials(),
targetPluginId: 'accentuate',
}),
);
return res(ctx.status(404));
}),
);
const processor = new AccentuateEntitiesProcessor({
logger,
config,
accentuateBackendClient: mockAccentuateBackendClient(),
discovery,
auth,
});

const entity = {
Expand Down
55 changes: 36 additions & 19 deletions plugins/accentuate-backend/src/processor/processor.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,41 @@
import { CatalogProcessor } from '@backstage/plugin-catalog-node';
import { Entity, stringifyEntityRef } from '@backstage/catalog-model';
import { AccentuateBackendDatabase } from '../db';
import { AccentuateBackendClient } from '../api';
import deepmerge from 'deepmerge';
import {
ANNOTATION_ACCENTUATE_DISABLE,
DEFAULT_ALLOWED_KINDS,
isAllowedKind,
} from '@dweber019/backstage-plugin-accentuate-common';
import { Config } from '@backstage/config';
import { DatabaseService, LoggerService } from '@backstage/backend-plugin-api';
import { AuthService, DiscoveryService, LoggerService } from '@backstage/backend-plugin-api';
import { AccentuateResponse } from '../api/AccentuateBackendClient';

export type PluginEnvironment = {
logger: LoggerService;
config: Config;
database: DatabaseService;
discovery: DiscoveryService;
auth: AuthService;
};

export class AccentuateEntitiesProcessor implements CatalogProcessor {
private readonly logger: LoggerService;
private readonly config: Config;
private readonly accentuateBackendClient: AccentuateBackendClient;
private readonly discovery: DiscoveryService;
private readonly auth: AuthService;

constructor(options: {
logger: LoggerService;
config: Config;
accentuateBackendClient: AccentuateBackendClient;
discovery: DiscoveryService;
auth: AuthService;
}) {
this.logger = options.logger.child({
type: 'processor',
processor: this.getProcessorName(),
});
this.config = options.config;
this.accentuateBackendClient = options.accentuateBackendClient;
this.discovery = options.discovery;
this.auth = options.auth;
}

getProcessorName(): string {
Expand All @@ -53,10 +56,30 @@ export class AccentuateEntitiesProcessor implements CatalogProcessor {
}) as any;
}

const accentuate = await this.accentuateBackendClient.get(
stringifyEntityRef(entity),
);
this.logger.debug('Does accentuate for entity exists', {
const baseUrl = await this.discovery.getBaseUrl('accentuate');
const { token } = await this.auth.getPluginRequestToken({
onBehalfOf: await this.auth.getOwnServiceCredentials(),
targetPluginId: 'accentuate',
});

const response = await fetch(`${baseUrl}?entityRef=${stringifyEntityRef(entity)}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
Authorization: `Bearer ${token}`,
},
});
if (response.status === 404) {
return entity;
}
if (!response.ok) {
throw new Error(`Request failed with status ${response.status}`);
}

const accentuate = await response.json() as AccentuateResponse;

this.logger.info('Does accentuate for entity exists', {
entity: stringifyEntityRef(entity),
exists: !!accentuate,
});
Expand All @@ -68,17 +91,11 @@ export class AccentuateEntitiesProcessor implements CatalogProcessor {
}

public static async fromEnv(env: PluginEnvironment) {
const accentuateBackendStore = await AccentuateBackendDatabase.create(
await env.database.getClient(),
);
const accentuateBackendClient = new AccentuateBackendClient(
env.logger,
accentuateBackendStore,
);
return new AccentuateEntitiesProcessor({
logger: env.logger,
config: env.config,
accentuateBackendClient,
discovery: env.discovery,
auth: env.auth,
});
}
}
17 changes: 0 additions & 17 deletions plugins/accentuate-backend/src/run.ts

This file was deleted.

49 changes: 0 additions & 49 deletions plugins/accentuate-backend/src/service/standaloneServer.ts

This file was deleted.

1 change: 0 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5922,7 +5922,6 @@ __metadata:
version: 0.0.0-use.local
resolution: "@dweber019/backstage-plugin-accentuate-backend@workspace:plugins/accentuate-backend"
dependencies:
"@backstage/backend-common": ^0.24.0
"@backstage/backend-defaults": ^0.4.3
"@backstage/backend-plugin-api": ^0.8.0
"@backstage/catalog-model": ^1.6.0
Expand Down

0 comments on commit e77d210

Please sign in to comment.