Skip to content

Commit

Permalink
fix!: fix event support for Bitbucket Cloud
Browse files Browse the repository at this point in the history
Fixes the event-based updates at `BitbucketCloudEntityProvider`.

Previously, this entity provider had optional event support for legacy backends
that could be enabled by passing `catalogApi`, `events`, and `tokenManager`.

For the new/current backend system, the `catalogModuleBitbucketCloudEntityProvider`
(`catalog.bitbucket-cloud-entity-provider`), event support was enabled by default.

A recent change removed `tokenManager` as a dependency from the module as well as removed it as input.
While this didn't break the instantiation of the module, it broke the event-based updates
and led to a runtime misbehavior, accompanied by an info log message.

This change will replace the use of `tokenManager` with the use of `auth` (`AuthService`).

Additionally, it will make `catalogApi` and `events` required dependencies.
For the current backend system, this change is transparent and doesn't require any action.
For the legacy backend system, this change will require you to pass those dependencies if you didn't do it already.

**BREAKING CHANGES:**

> _(For legacy backend users only.)_
>
>  Previously optional `catalogApi`, and `events` are required now.
>  A new required dependency `auth` was added.

Fixes: backstage#26925
Relates-to: PR backstage#26141
Signed-off-by: Patrick Jungermann <[email protected]>
  • Loading branch information
pjungermann committed Oct 1, 2024
1 parent 1b05958 commit 6343c8d
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 105 deletions.
29 changes: 29 additions & 0 deletions .changeset/rare-rabbits-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
'@backstage/plugin-catalog-backend-module-bitbucket-cloud': minor
---

Fixes the event-based updates at `BitbucketCloudEntityProvider`.

Previously, this entity provider had optional event support for legacy backends
that could be enabled by passing `catalogApi`, `events`, and `tokenManager`.

For the new/current backend system, the `catalogModuleBitbucketCloudEntityProvider`
(`catalog.bitbucket-cloud-entity-provider`), event support was enabled by default.

A recent change removed `tokenManager` as a dependency from the module as well as removed it as input.
While this didn't break the instantiation of the module, it broke the event-based updates,
and led to a runtime misbehavior, accompanied by an info log message.

This change will replace the use of `tokenManager` with the use of `auth` (`AuthService`).

Additionally, to simplify, it will make `catalogApi` and `events` required dependencies.
For the current backend system, this change is transparent and doesn't require any action.
For the legacy backend system, this change will require you to pass those dependencies
if you didn't do it already.

BREAKING CHANGES:

_(For legacy backend users only.)_

Previously optional `catalogApi`, and `events` are required now.
A new required dependency `auth` was added.
31 changes: 1 addition & 30 deletions docs/integrations/bitbucketCloud/discovery.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,33 +51,6 @@ Further documentation:

### Installation with Legacy Backend System

#### Installation without Events Support

And then add the entity provider to your catalog builder:

```ts title="packages/backend/src/plugins/catalog.ts"
/* highlight-add-next-line */
import { BitbucketCloudEntityProvider } from '@backstage/plugin-catalog-backend-module-bitbucket-cloud';

export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
const builder = await CatalogBuilder.create(env);
/* highlight-add-start */
builder.addEntityProvider(
BitbucketCloudEntityProvider.fromConfig(env.config, {
logger: env.logger,
scheduler: env.scheduler,
}),
);
/* highlight-add-end */

// ..
}
```

#### Installation with Events Support

Please follow the installation instructions at

- <https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md>
Expand All @@ -104,19 +77,17 @@ export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
const builder = await CatalogBuilder.create(env);
builder.addProcessor(new ScaffolderEntitiesProcessor());
/* highlight-add-start */
const bitbucketCloudProvider = BitbucketCloudEntityProvider.fromConfig(
env.config,
{
auth: env.auth,
catalogApi: new CatalogClient({ discoveryApi: env.discovery }),
events: env.events,
logger: env.logger,
scheduler: env.scheduler,
tokenManager: env.tokenManager,
},
);
env.eventBroker.subscribe(bitbucketCloudProvider);
builder.addEntityProvider(bitbucketCloudProvider);
/* highlight-add-end */
const { processingEngine, router } = await builder.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
"test": "backstage-cli package test"
},
"dependencies": {
"@backstage/backend-common": "^0.25.0",
"@backstage/backend-plugin-api": "workspace:^",
"@backstage/catalog-client": "workspace:^",
"@backstage/catalog-model": "workspace:^",
Expand Down
14 changes: 7 additions & 7 deletions plugins/catalog-backend-module-bitbucket-cloud/report.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { AuthService } from '@backstage/backend-plugin-api';
import { CatalogApi } from '@backstage/catalog-client';
import { Config } from '@backstage/config';
import { EntityProvider } from '@backstage/plugin-catalog-node';
Expand All @@ -12,7 +13,6 @@ import { EventsService } from '@backstage/plugin-events-node';
import { LoggerService } from '@backstage/backend-plugin-api';
import { SchedulerService } from '@backstage/backend-plugin-api';
import { SchedulerServiceTaskRunner } from '@backstage/backend-plugin-api';
import { TokenManager } from '@backstage/backend-common';

// @public
export class BitbucketCloudEntityProvider implements EntityProvider {
Expand All @@ -21,12 +21,12 @@ export class BitbucketCloudEntityProvider implements EntityProvider {
static fromConfig(
config: Config,
options: {
catalogApi?: CatalogApi;
events?: EventsService;
auth: AuthService;
catalogApi: CatalogApi;
events: EventsService;
logger: LoggerService;
schedule?: SchedulerServiceTaskRunner;
scheduler?: SchedulerService;
tokenManager?: TokenManager;
},
): BitbucketCloudEntityProvider[];
getProviderName(): string;
Expand All @@ -39,7 +39,7 @@ export class BitbucketCloudEntityProvider implements EntityProvider {

// Warnings were encountered during analysis:
//
// src/providers/BitbucketCloudEntityProvider.d.ts:28:5 - (ae-undocumented) Missing documentation for "fromConfig".
// src/providers/BitbucketCloudEntityProvider.d.ts:44:5 - (ae-undocumented) Missing documentation for "refresh".
// src/providers/BitbucketCloudEntityProvider.d.ts:47:5 - (ae-undocumented) Missing documentation for "onRepoPush".
// src/providers/BitbucketCloudEntityProvider.d.ts:26:5 - (ae-undocumented) Missing documentation for "fromConfig".
// src/providers/BitbucketCloudEntityProvider.d.ts:42:5 - (ae-undocumented) Missing documentation for "refresh".
// src/providers/BitbucketCloudEntityProvider.d.ts:44:5 - (ae-undocumented) Missing documentation for "onRepoPush".
```
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,25 @@ export const catalogModuleBitbucketCloudEntityProvider = createBackendModule({
register(env) {
env.registerInit({
deps: {
auth: coreServices.auth,
catalog: catalogProcessingExtensionPoint,
catalogApi: catalogServiceRef,
config: coreServices.rootConfig,
events: eventsServiceRef,
logger: coreServices.logger,
scheduler: coreServices.scheduler,
},
async init({ catalog, catalogApi, config, events, logger, scheduler }) {
async init({
auth,
catalog,
catalogApi,
config,
events,
logger,
scheduler,
}) {
const providers = BitbucketCloudEntityProvider.fromConfig(config, {
auth,
catalogApi,
events,
logger,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
* limitations under the License.
*/

import { TokenManager } from '@backstage/backend-common';
import {
SchedulerServiceTaskInvocationDefinition,
SchedulerServiceTaskRunner,
Expand Down Expand Up @@ -92,11 +91,6 @@ describe('BitbucketCloudEntityProvider', () => {
applyMutation: jest.fn(),
refresh: jest.fn(),
};
const tokenManager = {
getToken: async () => {
return { token: 'fake-token' };
},
} as any as TokenManager;
const repoPushEvent: Events.RepoPushEvent = {
actor: {
type: 'user',
Expand Down Expand Up @@ -158,8 +152,14 @@ describe('BitbucketCloudEntityProvider', () => {
});

it('no provider config', () => {
const auth = mockServices.auth.mock();
const catalogApi = catalogServiceMock.mock();
const config = new ConfigReader({});
const events = DefaultEventsService.create({ logger });
const providers = BitbucketCloudEntityProvider.fromConfig(config, {
auth,
catalogApi,
events,
logger,
schedule,
});
Expand All @@ -168,7 +168,13 @@ describe('BitbucketCloudEntityProvider', () => {
});

it('single simple provider config', () => {
const auth = mockServices.auth.mock();
const catalogApi = catalogServiceMock.mock();
const events = DefaultEventsService.create({ logger });
const providers = BitbucketCloudEntityProvider.fromConfig(simpleConfig, {
auth,
catalogApi,
events,
logger,
schedule,
});
Expand All @@ -180,14 +186,24 @@ describe('BitbucketCloudEntityProvider', () => {
});

it('fail without schedule and scheduler', () => {
const auth = mockServices.auth.mock();
const catalogApi = catalogServiceMock.mock();
const events = DefaultEventsService.create({ logger });

expect(() =>
BitbucketCloudEntityProvider.fromConfig(simpleConfig, {
auth,
catalogApi,
events,
logger,
}),
).toThrow('Either schedule or scheduler must be provided.');
});

it('fail with scheduler but no schedule config', () => {
const auth = mockServices.auth.mock();
const catalogApi = catalogServiceMock.mock();
const events = DefaultEventsService.create({ logger });
const scheduler = mockServices.scheduler.mock();
const config = new ConfigReader({
catalog: {
Expand All @@ -201,6 +217,9 @@ describe('BitbucketCloudEntityProvider', () => {

expect(() =>
BitbucketCloudEntityProvider.fromConfig(config, {
auth,
catalogApi,
events,
logger,
scheduler,
}),
Expand All @@ -210,6 +229,9 @@ describe('BitbucketCloudEntityProvider', () => {
});

it('single simple provider config with schedule in config', () => {
const auth = mockServices.auth.mock();
const catalogApi = catalogServiceMock.mock();
const events = DefaultEventsService.create({ logger });
const scheduler = mockServices.scheduler.mock();
const config = new ConfigReader({
catalog: {
Expand All @@ -226,6 +248,9 @@ describe('BitbucketCloudEntityProvider', () => {
});

const providers = BitbucketCloudEntityProvider.fromConfig(config, {
auth,
catalogApi,
events,
logger,
scheduler,
});
Expand All @@ -237,6 +262,8 @@ describe('BitbucketCloudEntityProvider', () => {
});

it('multiple provider configs', () => {
const auth = mockServices.auth.mock();
const catalogApi = catalogServiceMock.mock();
const config = new ConfigReader({
catalog: {
providers: {
Expand All @@ -251,7 +278,11 @@ describe('BitbucketCloudEntityProvider', () => {
},
},
});
const events = DefaultEventsService.create({ logger });
const providers = BitbucketCloudEntityProvider.fromConfig(config, {
auth,
catalogApi,
events,
logger,
schedule,
});
Expand All @@ -266,7 +297,13 @@ describe('BitbucketCloudEntityProvider', () => {
});

it('apply full update on scheduled execution', async () => {
const auth = mockServices.auth.mock();
const catalogApi = catalogServiceMock.mock();
const events = DefaultEventsService.create({ logger });
const provider = BitbucketCloudEntityProvider.fromConfig(defaultConfig, {
auth,
catalogApi,
events,
logger,
schedule,
})[0];
Expand Down Expand Up @@ -436,6 +473,9 @@ describe('BitbucketCloudEntityProvider', () => {
'added-module/catalog-custom.yaml',
);

const auth = mockServices.auth.mock({
getPluginRequestToken: async () => ({ token: 'fake-token' }),
});
const events = DefaultEventsService.create({ logger });
const catalogApi = catalogServiceMock.mock({
getEntities: async (
Expand All @@ -457,11 +497,11 @@ describe('BitbucketCloudEntityProvider', () => {
},
});
const provider = BitbucketCloudEntityProvider.fromConfig(defaultConfig, {
auth,
catalogApi,
events,
logger,
schedule,
tokenManager,
})[0];

server.use(
Expand Down Expand Up @@ -569,14 +609,15 @@ describe('BitbucketCloudEntityProvider', () => {
});

it('no onRepoPush update on non-matching workspace slug', async () => {
const auth = mockServices.auth.mock();
const catalogApi = catalogServiceMock.mock();
const events = DefaultEventsService.create({ logger });
const provider = BitbucketCloudEntityProvider.fromConfig(defaultConfig, {
auth,
catalogApi,
events,
logger,
schedule,
tokenManager,
})[0];

await provider.connect(entityProviderConnection);
Expand All @@ -599,14 +640,15 @@ describe('BitbucketCloudEntityProvider', () => {
});

it('no onRepoPush update on non-matching repo slug', async () => {
const auth = mockServices.auth.mock();
const catalogApi = catalogServiceMock.mock();
const events = DefaultEventsService.create({ logger });
const provider = BitbucketCloudEntityProvider.fromConfig(defaultConfig, {
auth,
catalogApi,
events,
logger,
schedule,
tokenManager,
})[0];

await provider.connect(entityProviderConnection);
Expand Down
Loading

0 comments on commit 6343c8d

Please sign in to comment.