feature: improve local database functionality
1. make locally run app use real DB with locations support 2. add shell script for filling up DB with mock data
This commit is contained in:
@@ -6,19 +6,21 @@
|
||||
"license": "Apache-2.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "tsc-watch --onFirstSuccess \"cross-env NODE_ENV=development nodemon dist/run.js\"",
|
||||
"start": "tsc-watch --onFirstSuccess \"cross-env NODE_ENV=development nodemon -r esm dist/run.js\"",
|
||||
"build": "tsc",
|
||||
"lint": "backstage-cli lint",
|
||||
"test": "backstage-cli test",
|
||||
"prepack": "backstage-cli prepack",
|
||||
"postpack": "backstage-cli postpack",
|
||||
"clean": "backstage-cli clean"
|
||||
"clean": "backstage-cli clean",
|
||||
"mock-db": "sh ./scripts/mock-db"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.1.1-alpha.6",
|
||||
"@backstage/catalog-model": "^0.1.1-alpha.6",
|
||||
"compression": "^1.7.4",
|
||||
"cors": "^2.8.5",
|
||||
"esm": "^3.2.25",
|
||||
"express": "^4.17.1",
|
||||
"express-promise-router": "^3.0.3",
|
||||
"fs-extra": "^9.0.0",
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
curl --location --request POST 'localhost:3003/locations' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"type": "github",
|
||||
"target": "https://github.com/spotify/backstage/blob/master/plugins/catalog-backend/fixtures/one_component.yaml"
|
||||
}'
|
||||
curl --location --request POST 'localhost:3003/locations' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"type": "github",
|
||||
"target": "https://github.com/spotify/backstage/blob/master/plugins/catalog-backend/fixtures/two_components.yaml"
|
||||
}'
|
||||
@@ -14,26 +14,48 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { Entity, EntityPolicy } from '@backstage/catalog-model';
|
||||
import { Entity, EntityPolicy } from '@backstage/catalog-model';
|
||||
import Knex from 'knex';
|
||||
import lodash from 'lodash';
|
||||
import path from 'path';
|
||||
import { Logger } from 'winston';
|
||||
import type { IngestionModel } from '../ingestion/types';
|
||||
import { IngestionModel } from '../ingestion/types';
|
||||
import { CommonDatabase } from './CommonDatabase';
|
||||
import { DatabaseLocationUpdateLogStatus } from './types';
|
||||
import type { Database, DbEntityRequest } from './types';
|
||||
import {
|
||||
DatabaseLocationUpdateLogStatus,
|
||||
Database,
|
||||
DbEntityRequest,
|
||||
} from './types';
|
||||
|
||||
export class DatabaseManager {
|
||||
public static async createDatabase(
|
||||
knex: Knex,
|
||||
database: Knex,
|
||||
logger: Logger,
|
||||
): Promise<Database> {
|
||||
await knex.migrate.latest({
|
||||
await database.migrate.latest({
|
||||
directory: path.resolve(__dirname, 'migrations'),
|
||||
loadExtensions: ['.js'],
|
||||
});
|
||||
return new CommonDatabase(knex, logger);
|
||||
return new CommonDatabase(database, logger);
|
||||
}
|
||||
|
||||
public static async createInMemoryDatabase(
|
||||
logger: Logger,
|
||||
): Promise<Database> {
|
||||
const database = Knex({
|
||||
client: 'sqlite3',
|
||||
connection: ':memory:',
|
||||
useNullAsDefault: true,
|
||||
});
|
||||
database.client.pool.on('createSuccess', (_eventId: any, resource: any) => {
|
||||
resource.run('PRAGMA foreign_keys = ON', () => {});
|
||||
});
|
||||
|
||||
await database.migrate.latest({
|
||||
directory: path.resolve(__dirname, 'migrations'),
|
||||
loadExtensions: ['.js'],
|
||||
});
|
||||
return new CommonDatabase(database, logger);
|
||||
}
|
||||
|
||||
private static async logUpdateSuccess(
|
||||
|
||||
@@ -26,18 +26,26 @@ import helmet from 'helmet';
|
||||
import { Logger } from 'winston';
|
||||
import { EntitiesCatalog, LocationsCatalog } from '../catalog';
|
||||
import { createRouter } from './router';
|
||||
import { HigherOrderOperation } from '../ingestion/types';
|
||||
|
||||
export interface ApplicationOptions {
|
||||
enableCors: boolean;
|
||||
entitiesCatalog: EntitiesCatalog;
|
||||
locationsCatalog?: LocationsCatalog;
|
||||
higherOrderOperation?: HigherOrderOperation;
|
||||
logger: Logger;
|
||||
}
|
||||
|
||||
export async function createStandaloneApplication(
|
||||
options: ApplicationOptions,
|
||||
): Promise<express.Application> {
|
||||
const { enableCors, entitiesCatalog, locationsCatalog, logger } = options;
|
||||
const {
|
||||
enableCors,
|
||||
entitiesCatalog,
|
||||
locationsCatalog,
|
||||
logger,
|
||||
higherOrderOperation,
|
||||
} = options;
|
||||
const app = express();
|
||||
|
||||
app.use(helmet());
|
||||
@@ -49,7 +57,12 @@ export async function createStandaloneApplication(
|
||||
app.use(requestLoggingHandler());
|
||||
app.use(
|
||||
'/',
|
||||
await createRouter({ entitiesCatalog, locationsCatalog, logger }),
|
||||
await createRouter({
|
||||
entitiesCatalog,
|
||||
locationsCatalog,
|
||||
higherOrderOperation,
|
||||
logger,
|
||||
}),
|
||||
);
|
||||
app.use(notFoundHandler());
|
||||
app.use(errorHandler());
|
||||
|
||||
@@ -16,8 +16,14 @@
|
||||
|
||||
import { Server } from 'http';
|
||||
import { Logger } from 'winston';
|
||||
import { StaticEntitiesCatalog } from '../catalog';
|
||||
import knex from 'knex';
|
||||
import { createStandaloneApplication } from './standaloneApplication';
|
||||
import { DatabaseEntitiesCatalog } from '../catalog/DatabaseEntitiesCatalog';
|
||||
import { DatabaseManager } from '../database/DatabaseManager';
|
||||
import { DatabaseLocationsCatalog } from '../catalog/DatabaseLocationsCatalog';
|
||||
import { LocationReaders } from '../ingestion/source/LocationReaders';
|
||||
import { IngestionModels, DescriptorParsers, HigherOrderOperations } from '..';
|
||||
import { EntityPolicies } from '@backstage/catalog-model';
|
||||
|
||||
export interface ServerOptions {
|
||||
port: number;
|
||||
@@ -30,25 +36,27 @@ export async function startStandaloneServer(
|
||||
): Promise<Server> {
|
||||
const logger = options.logger.child({ service: 'catalog-backend' });
|
||||
|
||||
const entitiesCatalog = new StaticEntitiesCatalog([
|
||||
{
|
||||
apiVersion: 'backstage.io/v1beta1',
|
||||
kind: 'Component',
|
||||
metadata: { name: 'c1' },
|
||||
spec: { type: 'service' },
|
||||
},
|
||||
{
|
||||
apiVersion: 'backstage.io/v1beta1',
|
||||
kind: 'Component',
|
||||
metadata: { name: 'c2' },
|
||||
spec: { type: 'service' },
|
||||
},
|
||||
]);
|
||||
const db = await DatabaseManager.createInMemoryDatabase(logger);
|
||||
|
||||
const entitiesCatalog = new DatabaseEntitiesCatalog(db);
|
||||
const locationsCatalog = new DatabaseLocationsCatalog(db);
|
||||
const ingestionModel = new IngestionModels(
|
||||
new LocationReaders(),
|
||||
new DescriptorParsers(),
|
||||
new EntityPolicies(),
|
||||
);
|
||||
const higherOrderOperation = new HigherOrderOperations(
|
||||
entitiesCatalog,
|
||||
locationsCatalog,
|
||||
ingestionModel,
|
||||
);
|
||||
|
||||
logger.debug('Creating application...');
|
||||
const app = await createStandaloneApplication({
|
||||
enableCors: options.enableCors,
|
||||
entitiesCatalog,
|
||||
locationsCatalog,
|
||||
higherOrderOperation,
|
||||
logger,
|
||||
});
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import React, { FC } from 'react';
|
||||
import { Component } from '../../data/component';
|
||||
import { InfoCard, Progress, Table, TableColumn } from '@backstage/core';
|
||||
import { Typography, Link } from '@material-ui/core';
|
||||
import EditIcon from '@material-ui/icons/Edit';
|
||||
|
||||
const columns: TableColumn[] = [
|
||||
{
|
||||
@@ -66,7 +67,18 @@ const CatalogTable: FC<CatalogTableProps> = ({
|
||||
columns={columns}
|
||||
options={{ paging: false }}
|
||||
title={`${titlePreamble} (${(components && components.length) || 0})`}
|
||||
data={components}
|
||||
data={components.map(({ kind, name, description }) => ({
|
||||
kind,
|
||||
name,
|
||||
description: (
|
||||
<div>
|
||||
{description}
|
||||
<Link href="" target="_blank" rel="noopener" color="inherit">
|
||||
<EditIcon />
|
||||
</Link>
|
||||
</div>
|
||||
),
|
||||
}))}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user