refactor: stop using the legacy standalone server

Signed-off-by: Camila Belo <camilaibs@gmail.com>
This commit is contained in:
Camila Belo
2024-05-16 14:46:37 +02:00
parent 8fb30a5afe
commit 8869b8ef30
34 changed files with 209 additions and 860 deletions
+12
View File
@@ -0,0 +1,12 @@
---
'@backstage/plugin-user-settings-backend': patch
'@backstage/plugin-devtools-backend': patch
'@backstage/plugin-techdocs-backend': patch
'@backstage/plugin-catalog-backend': patch
'@backstage/plugin-search-backend': patch
'@backstage/plugin-proxy-backend': patch
'@backstage/plugin-auth-backend': patch
'@backstage/plugin-app-backend': patch
---
Migrate the `dev` server to use the new backend system.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-common': patch
---
Deprecate the legacy `createServiceBuilder`.
+13 -1
View File
@@ -13,7 +13,19 @@ yarn --cwd packages/backend add @backstage/plugin-app-backend app
By adding the app package as a dependency we ensure that it is built as part of the backend, and that it can be resolved at runtime.
Now add the plugin router to your app, creating it for example like this:
Now add the plugin to your app, creating it for example like this:
### New Backend
```ts
import { createBackend } from '@backstage/backend-defaults';
const backend = createBackend();
backend.add(import('@backstage/plugin-app-backend/alpha'));
backend.start();
```
### Old Backend
```ts
const router = await createRouter({
@@ -1,5 +1,5 @@
/*
* Copyright 2020 The Backstage Authors
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,19 +14,8 @@
* limitations under the License.
*/
import { getRootLogger } from '@backstage/backend-common';
import { startStandaloneServer } from './service/standaloneServer';
import { createBackend } from '@backstage/backend-defaults';
const logger = getRootLogger();
startStandaloneServer({ logger }).catch(err => {
logger.error(err);
process.exit(1);
});
process.on('SIGINT', () => {
logger.info('CTRL+C pressed; exiting.');
process.exit(0);
});
module.hot?.accept();
const backend = createBackend();
backend.add(import('../src/alpha'));
backend.start();
+1
View File
@@ -66,6 +66,7 @@
},
"devDependencies": {
"@backstage/backend-app-api": "workspace:^",
"@backstage/backend-defaults": "workspace:^",
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@backstage/types": "workspace:^",
@@ -1,51 +0,0 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Server } from 'http';
import { createServiceBuilder } from '@backstage/backend-common';
import { Config } from '@backstage/config';
import { createRouter } from './router';
import { LoggerService } from '@backstage/backend-plugin-api';
export interface ServerOptions {
port: number;
enableCors: boolean;
config: Config;
logger: LoggerService;
}
export async function startStandaloneServer(
options: ServerOptions,
): Promise<Server> {
const logger = options.logger.child({ service: 'app-backend' });
logger.debug('Starting application server...');
const router = await createRouter({
logger,
config: options.config,
appPackageName: 'example-app',
});
const service = createServiceBuilder(module)
.setPort(options.port)
.addRouter('', router);
return await service.start().catch(err => {
logger.error(err);
process.exit(1);
});
}
module.hot?.accept();
@@ -1,66 +0,0 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
createServiceBuilder,
loadBackendConfig,
ServerTokenManager,
HostDiscovery,
DatabaseManager,
} from '@backstage/backend-common';
import { Server } from 'http';
import { LoggerService } from '@backstage/backend-plugin-api';
import { createRouter } from './router';
import { ConfigReader } from '@backstage/config';
export interface ServerOptions {
logger: LoggerService;
}
export async function startStandaloneServer(
options: ServerOptions,
): Promise<Server> {
const logger = options.logger.child({ service: 'auth-backend' });
const config = await loadBackendConfig({ logger, argv: process.argv });
const discovery = HostDiscovery.fromConfig(config);
const manager = DatabaseManager.fromConfig(
new ConfigReader({
backend: {
database: { client: 'better-sqlite3', connection: ':memory:' },
},
}),
);
const database = manager.forPlugin('auth');
logger.debug('Starting application server...');
const router = await createRouter({
logger,
config,
database,
discovery,
tokenManager: ServerTokenManager.noop(),
});
const service = createServiceBuilder(module)
.enableCors({ origin: 'http://localhost:3000', credentials: true })
.addRouter('/auth', router);
return await service.start().catch(err => {
logger.error(err);
process.exit(1);
});
}
+21
View File
@@ -0,0 +1,21 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createBackend } from '@backstage/backend-defaults';
const backend = createBackend();
backend.add(import('../src/alpha'));
backend.start();
+1
View File
@@ -91,6 +91,7 @@
"zod": "^3.22.4"
},
"devDependencies": {
"@backstage/backend-defaults": "workspace:^",
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@backstage/plugin-permission-common": "workspace:^",
-33
View File
@@ -1,33 +0,0 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { getRootLogger } from '@backstage/backend-common';
import yn from 'yn';
import { startStandaloneServer } from './service/standaloneServer';
const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007;
const enableCors = yn(process.env.PLUGIN_CORS, { default: false });
const logger = getRootLogger();
startStandaloneServer({ port, enableCors, logger }).catch(err => {
logger.error(err);
process.exit(1);
});
process.on('SIGINT', () => {
logger.info('CTRL+C pressed; exiting.');
process.exit(0);
});
@@ -1,86 +0,0 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
createServiceBuilder,
DatabaseManager,
HostDiscovery,
loadBackendConfig,
ServerTokenManager,
UrlReaders,
} from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { ServerPermissionClient } from '@backstage/plugin-permission-node';
import { Server } from 'http';
import { applyDatabaseMigrations } from '../database/migrations';
import { CatalogBuilder } from './CatalogBuilder';
import { LoggerService } from '@backstage/backend-plugin-api';
export interface ServerOptions {
port: number;
enableCors: boolean;
logger: LoggerService;
}
// TODO(freben): Migrate to the next catalog when it's in place
export async function startStandaloneServer(
options: ServerOptions,
): Promise<Server> {
const logger = options.logger.child({ service: 'catalog-backend' });
const config = await loadBackendConfig({ logger, argv: process.argv });
const reader = UrlReaders.default({ logger, config });
const manager = DatabaseManager.fromConfig(
new ConfigReader({
backend: {
database: { client: 'better-sqlite3', connection: ':memory:' },
},
}),
);
const database = manager.forPlugin('catalog');
const discovery = HostDiscovery.fromConfig(config);
const tokenManager = ServerTokenManager.fromConfig(config, {
logger,
});
const permissions = ServerPermissionClient.fromConfig(config, {
discovery,
tokenManager,
});
logger.debug('Creating application...');
await applyDatabaseMigrations(await database.getClient());
const builder = CatalogBuilder.create({
logger,
database,
config,
reader,
permissions,
});
const catalog = await builder.build();
logger.debug('Starting application server...');
let service = createServiceBuilder(module)
.setPort(options.port)
.addRouter('/catalog', catalog.router);
if (options.enableCors) {
service = service.enableCors({ origin: 'http://localhost:3000' });
}
return await service.start().catch(err => {
logger.error(err);
process.exit(1);
});
}
module.hot?.accept();
+21
View File
@@ -0,0 +1,21 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createBackend } from '@backstage/backend-defaults';
const backend = createBackend();
backend.add(import('../src'));
backend.start();
+1
View File
@@ -52,6 +52,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/backend-defaults": "workspace:^",
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@types/ping": "^0.4.1",
-33
View File
@@ -1,33 +0,0 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { getRootLogger } from '@backstage/backend-common';
import yn from 'yn';
import { startStandaloneServer } from './service/standaloneServer';
const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007;
const enableCors = yn(process.env.PLUGIN_CORS, { default: false });
const logger = getRootLogger();
startStandaloneServer({ port, enableCors, logger }).catch(err => {
logger.error(err);
process.exit(1);
});
process.on('SIGINT', () => {
logger.info('CTRL+C pressed; exiting.');
process.exit(0);
});
@@ -1,69 +0,0 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
createServiceBuilder,
HostDiscovery,
loadBackendConfig,
ServerTokenManager,
} from '@backstage/backend-common';
import { Server } from 'http';
import { ServerPermissionClient } from '@backstage/plugin-permission-node';
import { createRouter } from './router';
import { LoggerService } from '@backstage/backend-plugin-api';
export interface ServerOptions {
port: number;
enableCors: boolean;
logger: LoggerService;
}
export async function startStandaloneServer(
options: ServerOptions,
): Promise<Server> {
const logger = options.logger.child({ service: 'devtools-backend-backend' });
const config = await loadBackendConfig({ logger, argv: process.argv });
const discovery = HostDiscovery.fromConfig(config);
const tokenManager = ServerTokenManager.fromConfig(config, {
logger,
});
const permissions = ServerPermissionClient.fromConfig(config, {
discovery,
tokenManager,
});
logger.debug('Starting application server...');
const router = await createRouter({
logger,
config,
permissions,
discovery,
});
let service = createServiceBuilder(module)
.setPort(options.port)
.addRouter('/devtools-backend', router);
if (options.enableCors) {
service = service.enableCors({ origin: 'http://localhost:3000' });
}
return await service.start().catch(err => {
logger.error(err);
process.exit(1);
});
}
module.hot?.accept();
@@ -0,0 +1,21 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createBackend } from '@backstage/backend-defaults';
const backend = createBackend();
backend.add(import('../src'));
backend.start();
@@ -43,6 +43,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/backend-defaults": "workspace:^",
"@backstage/cli": "workspace:^",
"@types/supertest": "^2.0.8",
"@types/uuid": "^9.0.0",
@@ -1,33 +0,0 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { getRootLogger } from '@backstage/backend-common';
import yn from 'yn';
import { startStandaloneServer } from './service/standaloneServer';
const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007;
const enableCors = yn(process.env.PLUGIN_CORS, { default: false });
const logger = getRootLogger();
startStandaloneServer({ port, enableCors, logger }).catch(err => {
logger.error(err);
process.exit(1);
});
process.on('SIGINT', () => {
logger.info('CTRL+C pressed; exiting.');
process.exit(0);
});
@@ -1,61 +0,0 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
createServiceBuilder,
HostDiscovery,
loadBackendConfig,
} from '@backstage/backend-common';
import { DefaultIdentityClient } from '@backstage/plugin-auth-node';
import { Server } from 'http';
import { createRouter } from './router';
import { LoggerService } from '@backstage/backend-plugin-api';
export interface ServerOptions {
port: number;
enableCors: boolean;
logger: LoggerService;
}
export async function startStandaloneServer(
options: ServerOptions,
): Promise<Server> {
const logger = options.logger.child({ service: 'todo-list-backend' });
logger.debug('Starting application server...');
const config = await loadBackendConfig({ logger, argv: process.argv });
const discovery = HostDiscovery.fromConfig(config);
const router = await createRouter({
logger,
identity: DefaultIdentityClient.create({
discovery,
issuer: await discovery.getExternalBaseUrl('auth'),
}),
});
let service = createServiceBuilder(module)
.setPort(options.port)
.addRouter('/todo-list', router);
if (options.enableCors) {
service = service.enableCors({ origin: 'http://localhost:3000' });
}
return await service.start().catch(err => {
logger.error(err);
process.exit(1);
});
}
module.hot?.accept();
+21
View File
@@ -0,0 +1,21 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createBackend } from '@backstage/backend-defaults';
const backend = createBackend();
backend.add(import('../src/alpha'));
backend.start();
+1
View File
@@ -64,6 +64,7 @@
"yup": "^1.0.0"
},
"devDependencies": {
"@backstage/backend-defaults": "workspace:^",
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@backstage/config-loader": "workspace:^",
-33
View File
@@ -1,33 +0,0 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { getRootLogger } from '@backstage/backend-common';
import yn from 'yn';
import { startStandaloneServer } from './service/standaloneServer';
const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007;
const enableCors = yn(process.env.PLUGIN_CORS, { default: false });
const logger = getRootLogger();
startStandaloneServer({ port, enableCors, logger }).catch(err => {
logger.error(err);
process.exit(1);
});
process.on('SIGINT', () => {
logger.info('CTRL+C pressed; exiting.');
process.exit(0);
});
@@ -1,61 +0,0 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
createServiceBuilder,
loadBackendConfig,
HostDiscovery,
} from '@backstage/backend-common';
import { Server } from 'http';
import { Logger } from 'winston';
import { createRouter } from './router';
export interface ServerOptions {
port: number;
enableCors: boolean;
logger: Logger;
}
export async function startStandaloneServer(
options: ServerOptions,
): Promise<Server> {
const logger = options.logger.child({ service: 'proxy-backend' });
logger.debug('Creating application...');
const config = await loadBackendConfig({ logger, argv: process.argv });
const discovery = HostDiscovery.fromConfig(config);
const router = await createRouter({
config,
logger,
discovery,
});
let service = createServiceBuilder(module)
.setPort(options.port)
.addRouter('/proxy', router);
if (options.enableCors) {
service = service.enableCors({ origin: 'http://localhost:3000' });
}
logger.debug('Starting application server...');
return await service.start().catch(err => {
logger.error(err);
process.exit(1);
});
}
module.hot?.accept();
@@ -14,20 +14,8 @@
* limitations under the License.
*/
import { getRootLogger } from '@backstage/backend-common';
import yn from 'yn';
import { startStandaloneServer } from './service/standaloneServer';
import { createBackend } from '@backstage/backend-defaults';
const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007;
const enableCors = yn(process.env.PLUGIN_CORS, { default: false });
const logger = getRootLogger();
startStandaloneServer({ port, enableCors, logger }).catch(err => {
logger.error(err);
process.exit(1);
});
process.on('SIGINT', () => {
logger.info('CTRL+C pressed; exiting.');
process.exit(0);
});
const backend = createBackend();
backend.add(import('../src/alpha'));
backend.start();
+1
View File
@@ -49,6 +49,7 @@
},
"dependencies": {
"@backstage/backend-common": "workspace:^",
"@backstage/backend-defaults": "workspace:^",
"@backstage/backend-openapi-utils": "workspace:^",
"@backstage/backend-plugin-api": "workspace:^",
"@backstage/config": "workspace:^",
@@ -1,79 +0,0 @@
/*
* Copyright 2021 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
createServiceBuilder,
loadBackendConfig,
ServerTokenManager,
HostDiscovery,
} from '@backstage/backend-common';
import { Server } from 'http';
import { Logger } from 'winston';
import { createRouter } from './router';
import {
LunrSearchEngine,
IndexBuilder,
} from '@backstage/plugin-search-backend-node';
import { ServerPermissionClient } from '@backstage/plugin-permission-node';
export interface ServerOptions {
port: number;
enableCors: boolean;
logger: Logger;
}
export async function startStandaloneServer(
options: ServerOptions,
): Promise<Server> {
const logger = options.logger.child({ service: 'search-backend' });
const config = await loadBackendConfig({ logger, argv: process.argv });
const searchEngine = new LunrSearchEngine({ logger });
const indexBuilder = new IndexBuilder({ logger, searchEngine });
const discovery = HostDiscovery.fromConfig(config);
const tokenManager = ServerTokenManager.fromConfig(config, {
logger,
});
const permissions = ServerPermissionClient.fromConfig(config, {
discovery,
tokenManager,
});
logger.debug('Starting application server...');
// TODO: stub out some documents/indices?
const router = await createRouter({
engine: indexBuilder.getSearchEngine(),
types: indexBuilder.getDocumentTypes(),
discovery,
permissions,
config,
logger,
});
let service = createServiceBuilder(module)
.setPort(options.port)
.addRouter('/search', router);
if (options.enableCors) {
service = service.enableCors({ origin: 'http://localhost:3000' });
}
return await service.start().catch(err => {
logger.error(err);
process.exit(1);
});
}
module.hot?.accept();
+21
View File
@@ -0,0 +1,21 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createBackend } from '@backstage/backend-defaults';
const backend = createBackend();
backend.add(import('../src/alpha'));
backend.start();
+1
View File
@@ -73,6 +73,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/backend-defaults": "workspace:^",
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@types/dockerode": "^3.3.0",
@@ -1,105 +0,0 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
CacheManager,
createServiceBuilder,
DockerContainerRunner,
HostDiscovery,
UrlReader,
} from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import {
DirectoryPreparer,
Generators,
Preparers,
Publisher,
TechdocsGenerator,
} from '@backstage/plugin-techdocs-node';
import Docker from 'dockerode';
import { Server } from 'http';
import { Logger } from 'winston';
import { createRouter } from './router';
export interface ServerOptions {
port: number;
enableCors: boolean;
logger: Logger;
}
export async function startStandaloneServer(
options: ServerOptions,
): Promise<Server> {
const logger = options.logger.child({ service: 'techdocs-backend' });
const config = new ConfigReader({
techdocs: {
publisher: {
type: 'local',
},
},
});
const discovery = HostDiscovery.fromConfig(config);
const mockUrlReader: jest.Mocked<UrlReader> = {
readUrl: jest.fn(),
readTree: jest.fn(),
search: jest.fn(),
};
logger.debug('Creating application...');
const preparers = new Preparers();
const directoryPreparer = DirectoryPreparer.fromConfig(config, {
logger,
reader: mockUrlReader,
});
preparers.register('dir', directoryPreparer);
const dockerClient = new Docker();
const containerRunner = new DockerContainerRunner({ dockerClient });
const generators = new Generators();
const techdocsGenerator = TechdocsGenerator.fromConfig(config, {
logger,
containerRunner,
});
generators.register('techdocs', techdocsGenerator);
const publisher = await Publisher.fromConfig(config, { logger, discovery });
const cache = CacheManager.fromConfig(config).forPlugin('techdocs');
logger.debug('Starting application server...');
const router = await createRouter({
preparers,
generators,
logger,
publisher,
config,
discovery,
cache,
});
let service = createServiceBuilder(module)
.setPort(options.port)
.addRouter('/techdocs', router);
if (options.enableCors) {
service = service.enableCors({ origin: 'http://localhost:3000' });
}
return await service.start().catch(err => {
logger.error(err);
process.exit(1);
});
}
module.hot?.accept();
@@ -0,0 +1,49 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createBackend } from '@backstage/backend-defaults';
import {
coreServices,
createServiceFactory,
} from '@backstage/backend-plugin-api';
import { IdentityApi } from '@backstage/plugin-auth-node';
const identityMock: IdentityApi = {
async getIdentity({ request }) {
const token = request.headers.authorization?.split(' ')[1];
return {
identity: {
type: 'user',
ownershipEntityRefs: [],
userEntityRef: token || 'user:default/john_doe',
},
token: token || 'no-token',
};
},
};
const backend = createBackend();
backend.add(
createServiceFactory(() => ({
service: coreServices.identity,
deps: {},
async factory() {
return identityMock;
},
})),
);
backend.add(import('../src/alpha'));
backend.start();
@@ -60,6 +60,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/backend-defaults": "workspace:^",
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@types/supertest": "^2.0.8",
-34
View File
@@ -1,34 +0,0 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { getRootLogger } from '@backstage/backend-common';
import yn from 'yn';
import { startStandaloneServer } from './service/standaloneServer';
const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007;
const enableCors = yn(process.env.PLUGIN_CORS, { default: false });
const logger = getRootLogger();
startStandaloneServer({ port, enableCors, logger }).catch(err => {
logger.error(err);
process.exit(1);
});
process.on('SIGINT', () => {
logger.info('CTRL+C pressed; exiting.');
process.exit(0);
});
@@ -1,83 +0,0 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
createServiceBuilder,
DatabaseManager,
} from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { IdentityApi } from '@backstage/plugin-auth-node';
import { Server } from 'http';
import { Logger } from 'winston';
import { DatabaseUserSettingsStore } from '../database/DatabaseUserSettingsStore';
import { createRouterInternal } from './router';
export interface ServerOptions {
port: number;
enableCors: boolean;
logger: Logger;
}
export async function startStandaloneServer(
options: ServerOptions,
): Promise<Server> {
const logger = options.logger.child({ service: 'storage-backend' });
const manager = DatabaseManager.fromConfig(
new ConfigReader({
backend: {
database: { client: 'better-sqlite3', connection: ':memory:' },
},
}),
);
const database = manager.forPlugin('user-settings');
logger.debug('Starting application server...');
const identityMock: IdentityApi = {
async getIdentity({ request }) {
const token = request.headers.authorization?.split(' ')[1];
return {
identity: {
type: 'user',
ownershipEntityRefs: [],
userEntityRef: token || 'user:default/john_doe',
},
token: token || 'no-token',
};
},
};
const router = await createRouterInternal({
userSettingsStore: await DatabaseUserSettingsStore.create({ database }),
identity: identityMock,
});
let service = createServiceBuilder(module)
.setPort(options.port)
.addRouter('/user-settings', router);
if (options.enableCors) {
service = service.enableCors({ origin: 'http://localhost:3000' });
}
return await service.start().catch(err => {
logger.error(err);
process.exit(1);
});
}
module.hot?.accept();
+8
View File
@@ -4351,6 +4351,7 @@ __metadata:
dependencies:
"@backstage/backend-app-api": "workspace:^"
"@backstage/backend-common": "workspace:^"
"@backstage/backend-defaults": "workspace:^"
"@backstage/backend-plugin-api": "workspace:^"
"@backstage/backend-test-utils": "workspace:^"
"@backstage/cli": "workspace:^"
@@ -5268,6 +5269,7 @@ __metadata:
resolution: "@backstage/plugin-catalog-backend@workspace:plugins/catalog-backend"
dependencies:
"@backstage/backend-common": "workspace:^"
"@backstage/backend-defaults": "workspace:^"
"@backstage/backend-openapi-utils": "workspace:^"
"@backstage/backend-plugin-api": "workspace:^"
"@backstage/backend-tasks": "workspace:^"
@@ -5587,6 +5589,7 @@ __metadata:
resolution: "@backstage/plugin-devtools-backend@workspace:plugins/devtools-backend"
dependencies:
"@backstage/backend-common": "workspace:^"
"@backstage/backend-defaults": "workspace:^"
"@backstage/backend-plugin-api": "workspace:^"
"@backstage/backend-test-utils": "workspace:^"
"@backstage/cli": "workspace:^"
@@ -6331,6 +6334,7 @@ __metadata:
resolution: "@backstage/plugin-proxy-backend@workspace:plugins/proxy-backend"
dependencies:
"@backstage/backend-common": "workspace:^"
"@backstage/backend-defaults": "workspace:^"
"@backstage/backend-plugin-api": "workspace:^"
"@backstage/backend-test-utils": "workspace:^"
"@backstage/cli": "workspace:^"
@@ -7016,6 +7020,7 @@ __metadata:
resolution: "@backstage/plugin-search-backend@workspace:plugins/search-backend"
dependencies:
"@backstage/backend-common": "workspace:^"
"@backstage/backend-defaults": "workspace:^"
"@backstage/backend-openapi-utils": "workspace:^"
"@backstage/backend-plugin-api": "workspace:^"
"@backstage/backend-test-utils": "workspace:^"
@@ -7245,6 +7250,7 @@ __metadata:
resolution: "@backstage/plugin-techdocs-backend@workspace:plugins/techdocs-backend"
dependencies:
"@backstage/backend-common": "workspace:^"
"@backstage/backend-defaults": "workspace:^"
"@backstage/backend-plugin-api": "workspace:^"
"@backstage/backend-test-utils": "workspace:^"
"@backstage/catalog-client": "workspace:^"
@@ -7428,6 +7434,7 @@ __metadata:
resolution: "@backstage/plugin-user-settings-backend@workspace:plugins/user-settings-backend"
dependencies:
"@backstage/backend-common": "workspace:^"
"@backstage/backend-defaults": "workspace:^"
"@backstage/backend-plugin-api": "workspace:^"
"@backstage/backend-test-utils": "workspace:^"
"@backstage/cli": "workspace:^"
@@ -9482,6 +9489,7 @@ __metadata:
resolution: "@internal/plugin-todo-list-backend@workspace:plugins/example-todo-list-backend"
dependencies:
"@backstage/backend-common": "workspace:^"
"@backstage/backend-defaults": "workspace:^"
"@backstage/backend-plugin-api": "workspace:^"
"@backstage/cli": "workspace:^"
"@backstage/errors": "workspace:^"