Merge pull request #24260 from Bonial-International-GmbH/pjungermann/events-service/github-providers

feat(events,github)!: remove use of `EventBroker` and `EventSubscriber`
This commit is contained in:
Patrik Oldsberg
2024-04-15 12:24:29 +02:00
committed by GitHub
6 changed files with 75 additions and 87 deletions
+19
View File
@@ -0,0 +1,19 @@
---
'@backstage/plugin-catalog-backend-module-github': minor
---
Remove use of `EventBroker` and `EventSubscriber` for the GitHub org data providers.
BREAKING CHANGE:
- `GithubOrgEntityProvider.onEvent` made private
- `GithubOrgEntityProvider.supportsEventTopics` removed
- `eventBroker` option was removed from `GithubMultiOrgEntityProvider.fromConfig`
- `GithubMultiOrgEntityProvider.supportsEventTopics` removed
This change only impacts users who still use the legacy backend system
**and** who still use `eventBroker` as option when creating these
entity providers.
Please pass the `EventsService` instance as option `events` instead.
You can find more information at the [installation documentation](https://backstage.io/docs/integrations/github/org/#legacy-backend-system).
@@ -11,7 +11,6 @@ import { Config } from '@backstage/config';
import { Entity } from '@backstage/catalog-model';
import { EntityProvider } from '@backstage/plugin-catalog-node';
import { EntityProviderConnection } from '@backstage/plugin-catalog-node';
import { EventBroker } from '@backstage/plugin-events-node';
import { EventParams } from '@backstage/plugin-events-node';
import { EventsService } from '@backstage/plugin-events-node';
import { EventSubscriber } from '@backstage/plugin-events-node';
@@ -166,8 +165,6 @@ export class GithubMultiOrgEntityProvider implements EntityProvider {
// @public
export interface GithubMultiOrgEntityProviderOptions {
// @deprecated
eventBroker?: EventBroker;
events?: EventsService;
githubCredentialsProvider?: GithubCredentialsProvider;
githubUrl: string;
@@ -219,9 +216,7 @@ export class GitHubOrgEntityProvider extends GithubOrgEntityProvider {
}
// @public
export class GithubOrgEntityProvider
implements EntityProvider, EventSubscriber
{
export class GithubOrgEntityProvider implements EntityProvider {
constructor(options: {
events?: EventsService;
id: string;
@@ -241,11 +236,7 @@ export class GithubOrgEntityProvider
): GithubOrgEntityProvider;
// (undocumented)
getProviderName(): string;
// (undocumented)
onEvent(params: EventParams): Promise<void>;
read(options?: { logger?: LoggerService }): Promise<void>;
// (undocumented)
supportsEventTopics(): string[];
}
// @public @deprecated (undocumented)
@@ -19,7 +19,10 @@ import { GroupEntity, UserEntity } from '@backstage/catalog-model';
import { ConfigReader } from '@backstage/config';
import { GithubCredentialsProvider } from '@backstage/integration';
import { EntityProviderConnection } from '@backstage/plugin-catalog-node';
import { EventSubscriber } from '@backstage/plugin-events-node';
import {
DefaultEventsService,
EventsService,
} from '@backstage/plugin-events-node';
import { graphql } from '@octokit/graphql';
import {
GithubMultiOrgEntityProvider,
@@ -717,15 +720,16 @@ describe('GithubMultiOrgEntityProvider', () => {
});
describe('events', () => {
let onEvent: Function;
let events: EventsService;
const entityProviderConnection: EntityProviderConnection = {
applyMutation: jest.fn(),
refresh: jest.fn(),
};
beforeEach(() => {
beforeEach(async () => {
const logger = getVoidLogger();
events = DefaultEventsService.create({ logger });
const config = new ConfigReader({
integrations: {
github: [
@@ -745,29 +749,22 @@ describe('GithubMultiOrgEntityProvider', () => {
getCredentials: mockGetCredentials,
};
const mockEventBroker = {
publish: async () => {},
subscribe: (subscriber: EventSubscriber) => {
onEvent = subscriber.onEvent;
},
};
const entityProvider = GithubMultiOrgEntityProvider.fromConfig(config, {
events,
id: 'my-id',
githubCredentialsProvider,
githubUrl: 'https://github.com',
logger,
orgs: ['orgA', 'orgB'],
eventBroker: mockEventBroker,
});
entityProvider.connect(entityProviderConnection);
await entityProvider.connect(entityProviderConnection);
});
afterEach(() => jest.resetAllMocks());
it('should ignore events from non-applicable orgs', async () => {
await onEvent({
await events.publish({
topic: 'github.organization',
eventPayload: {
action: 'member_added',
@@ -787,7 +784,7 @@ describe('GithubMultiOrgEntityProvider', () => {
expect(entityProviderConnection.applyMutation).not.toHaveBeenCalled();
await onEvent({
await events.publish({
topic: 'github.installation',
eventPayload: {
action: 'created',
@@ -901,7 +898,7 @@ describe('GithubMultiOrgEntityProvider', () => {
(graphql.defaults as jest.Mock).mockReturnValue(mockClient);
await onEvent({
await events.publish({
topic: 'github.installation',
eventPayload: {
action: 'created',
@@ -1033,7 +1030,7 @@ describe('GithubMultiOrgEntityProvider', () => {
(graphql.defaults as jest.Mock).mockReturnValue(mockClient);
await onEvent({
await events.publish({
topic: 'github.organization',
eventPayload: {
action: 'member_added',
@@ -1103,7 +1100,7 @@ describe('GithubMultiOrgEntityProvider', () => {
(graphql.defaults as jest.Mock).mockReturnValue(mockClient);
await onEvent({
await events.publish({
topic: 'github.organization',
eventPayload: {
action: 'member_removed',
@@ -1198,7 +1195,7 @@ describe('GithubMultiOrgEntityProvider', () => {
(graphql.defaults as jest.Mock).mockReturnValue(mockClient);
await onEvent({
await events.publish({
topic: 'github.organization',
eventPayload: {
action: 'member_removed',
@@ -1253,7 +1250,7 @@ describe('GithubMultiOrgEntityProvider', () => {
describe('team', () => {
it('should create a new group from a new team', async () => {
await onEvent({
await events.publish({
topic: 'github.team',
eventPayload: {
action: 'created',
@@ -1312,7 +1309,7 @@ describe('GithubMultiOrgEntityProvider', () => {
});
it('should remove a group from a deleted team', async () => {
await onEvent({
await events.publish({
topic: 'github.team',
eventPayload: {
action: 'deleted',
@@ -1467,7 +1464,7 @@ describe('GithubMultiOrgEntityProvider', () => {
(graphql.defaults as jest.Mock).mockReturnValue(mockClient);
await onEvent({
await events.publish({
topic: 'github.team',
eventPayload: {
action: 'edited',
@@ -1676,7 +1673,7 @@ describe('GithubMultiOrgEntityProvider', () => {
(graphql.defaults as jest.Mock).mockReturnValue(mockClient);
await onEvent({
await events.publish({
topic: 'github.membership',
eventPayload: {
action: 'added',
@@ -1848,7 +1845,7 @@ describe('GithubMultiOrgEntityProvider', () => {
(graphql.defaults as jest.Mock).mockReturnValue(mockClient);
await onEvent({
await events.publish({
topic: 'github.membership',
eventPayload: {
action: 'removed',
@@ -38,11 +38,7 @@ import {
EntityProvider,
EntityProviderConnection,
} from '@backstage/plugin-catalog-node';
import {
EventBroker,
EventParams,
EventsService,
} from '@backstage/plugin-events-node';
import { EventParams, EventsService } from '@backstage/plugin-events-node';
import { graphql } from '@octokit/graphql';
import {
InstallationCreatedEvent,
@@ -157,13 +153,6 @@ export interface GithubMultiOrgEntityProviderOptions {
* By default, groups will be namespaced according to their GitHub org.
*/
teamTransformer?: TeamTransformer;
/**
* An EventBroker to subscribe this provider to GitHub events to trigger delta mutations
*
* @deprecated Use `events` instead.
*/
eventBroker?: EventBroker;
}
type CreateDeltaOperation = (entities: Entity[]) => {
@@ -213,13 +202,6 @@ export class GithubMultiOrgEntityProvider implements EntityProvider {
provider.schedule(options.schedule);
if (options.eventBroker) {
options.eventBroker.subscribe({
supportsEventTopics: provider.supportsEventTopics.bind(provider),
onEvent: provider.onEvent.bind(provider),
});
}
return provider;
}
@@ -336,10 +318,6 @@ export class GithubMultiOrgEntityProvider implements EntityProvider {
markCommitComplete();
}
private supportsEventTopics(): string[] {
return EVENT_TOPICS;
}
private async onEvent(params: EventParams): Promise<void> {
const { logger } = this.options;
logger.debug(`Received event from ${params.topic}`);
@@ -22,7 +22,10 @@ import {
} from '@backstage/integration';
import { EntityProviderConnection } from '@backstage/plugin-catalog-node';
import { graphql } from '@octokit/graphql';
import { EventParams } from '@backstage/plugin-events-node';
import {
DefaultEventsService,
EventParams,
} from '@backstage/plugin-events-node';
import { GithubOrgEntityProvider } from './GithubOrgEntityProvider';
import { withLocations } from '../lib/withLocations';
@@ -267,6 +270,7 @@ describe('GithubOrgEntityProvider', () => {
};
const logger = getVoidLogger();
const events = DefaultEventsService.create({ logger });
const gitHubConfig: GithubIntegrationConfig = {
host: 'github.com',
};
@@ -281,6 +285,7 @@ describe('GithubOrgEntityProvider', () => {
};
const entityProvider = new GithubOrgEntityProvider({
events,
id: 'my-id',
githubCredentialsProvider,
orgUrl: 'https://github.com/backstage',
@@ -288,7 +293,7 @@ describe('GithubOrgEntityProvider', () => {
logger,
});
entityProvider.connect(entityProviderConnection);
await entityProvider.connect(entityProviderConnection);
const expectedEntity = {
apiVersion: 'backstage.io/v1alpha1',
@@ -330,8 +335,7 @@ describe('GithubOrgEntityProvider', () => {
},
},
};
await entityProvider.onEvent(event);
await events.publish(event);
expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1);
expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({
@@ -353,6 +357,7 @@ describe('GithubOrgEntityProvider', () => {
};
const logger = getVoidLogger();
const events = DefaultEventsService.create({ logger });
const gitHubConfig: GithubIntegrationConfig = {
host: 'github.com',
};
@@ -367,6 +372,7 @@ describe('GithubOrgEntityProvider', () => {
};
const entityProvider = new GithubOrgEntityProvider({
events,
id: 'my-id',
githubCredentialsProvider,
orgUrl: 'https://github.com/backstage',
@@ -374,7 +380,7 @@ describe('GithubOrgEntityProvider', () => {
logger,
});
entityProvider.connect(entityProviderConnection);
await entityProvider.connect(entityProviderConnection);
const expectedEntity = {
apiVersion: 'backstage.io/v1alpha1',
@@ -416,8 +422,7 @@ describe('GithubOrgEntityProvider', () => {
},
},
};
await entityProvider.onEvent(event);
await events.publish(event);
expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1);
expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({
@@ -439,6 +444,7 @@ describe('GithubOrgEntityProvider', () => {
};
const logger = getVoidLogger();
const events = DefaultEventsService.create({ logger });
const gitHubConfig: GithubIntegrationConfig = {
host: 'github.com',
};
@@ -453,6 +459,7 @@ describe('GithubOrgEntityProvider', () => {
};
const entityProvider = new GithubOrgEntityProvider({
events,
id: 'my-id',
githubCredentialsProvider,
orgUrl: 'https://github.com/backstage',
@@ -508,7 +515,7 @@ describe('GithubOrgEntityProvider', () => {
},
};
await entityProvider.onEvent(event);
await events.publish(event);
expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1);
expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({
@@ -530,6 +537,7 @@ describe('GithubOrgEntityProvider', () => {
};
const logger = getVoidLogger();
const events = DefaultEventsService.create({ logger });
const gitHubConfig: GithubIntegrationConfig = {
host: 'github.com',
};
@@ -544,6 +552,7 @@ describe('GithubOrgEntityProvider', () => {
};
const entityProvider = new GithubOrgEntityProvider({
events,
id: 'my-id',
githubCredentialsProvider,
orgUrl: 'https://github.com/backstage',
@@ -551,7 +560,7 @@ describe('GithubOrgEntityProvider', () => {
logger,
});
entityProvider.connect(entityProviderConnection);
await entityProvider.connect(entityProviderConnection);
const expectedEntity = {
apiVersion: 'backstage.io/v1alpha1',
@@ -600,7 +609,7 @@ describe('GithubOrgEntityProvider', () => {
},
};
await entityProvider.onEvent(event);
await events.publish(event);
expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1);
expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({
@@ -622,6 +631,7 @@ describe('GithubOrgEntityProvider', () => {
};
const logger = getVoidLogger();
const events = DefaultEventsService.create({ logger });
const gitHubConfig: GithubIntegrationConfig = {
host: 'github.com',
};
@@ -636,6 +646,7 @@ describe('GithubOrgEntityProvider', () => {
};
const entityProvider = new GithubOrgEntityProvider({
events,
id: 'my-id',
githubCredentialsProvider,
orgUrl: 'https://github.com/backstage',
@@ -717,7 +728,7 @@ describe('GithubOrgEntityProvider', () => {
(graphql.defaults as jest.Mock).mockReturnValue(mockClient);
entityProvider.connect(entityProviderConnection);
await entityProvider.connect(entityProviderConnection);
const event: EventParams = {
topic: 'github.team',
@@ -744,7 +755,7 @@ describe('GithubOrgEntityProvider', () => {
},
};
await entityProvider.onEvent(event);
await events.publish(event);
await new Promise(process.nextTick);
expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1);
@@ -871,6 +882,7 @@ describe('GithubOrgEntityProvider', () => {
};
const logger = getVoidLogger();
const events = DefaultEventsService.create({ logger });
const gitHubConfig: GithubIntegrationConfig = {
host: 'github.com',
};
@@ -885,6 +897,7 @@ describe('GithubOrgEntityProvider', () => {
};
const entityProvider = new GithubOrgEntityProvider({
events,
id: 'my-id',
githubCredentialsProvider,
orgUrl: 'https://github.com/backstage',
@@ -965,7 +978,7 @@ describe('GithubOrgEntityProvider', () => {
});
(graphql.defaults as jest.Mock).mockReturnValue(mockClient);
entityProvider.connect(entityProviderConnection);
await entityProvider.connect(entityProviderConnection);
const event: EventParams = {
topic: 'github.membership',
@@ -989,7 +1002,7 @@ describe('GithubOrgEntityProvider', () => {
},
};
await entityProvider.onEvent(event);
await events.publish(event);
await new Promise(process.nextTick);
expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1);
@@ -1117,6 +1130,7 @@ describe('GithubOrgEntityProvider', () => {
};
const logger = getVoidLogger();
const events = DefaultEventsService.create({ logger });
const gitHubConfig: GithubIntegrationConfig = {
host: 'github.com',
};
@@ -1131,6 +1145,7 @@ describe('GithubOrgEntityProvider', () => {
};
const entityProvider = new GithubOrgEntityProvider({
events,
id: 'my-id',
githubCredentialsProvider,
orgUrl: 'https://github.com/backstage',
@@ -1187,7 +1202,7 @@ describe('GithubOrgEntityProvider', () => {
});
(graphql.defaults as jest.Mock).mockReturnValue(mockClient);
entityProvider.connect(entityProviderConnection);
await entityProvider.connect(entityProviderConnection);
const event: EventParams = {
topic: 'github.membership',
@@ -1211,7 +1226,7 @@ describe('GithubOrgEntityProvider', () => {
},
};
await entityProvider.onEvent(event);
await events.publish(event);
await new Promise(process.nextTick);
expect(entityProviderConnection.applyMutation).toHaveBeenCalledTimes(1);
@@ -28,11 +28,7 @@ import {
EntityProvider,
EntityProviderConnection,
} from '@backstage/plugin-catalog-node';
import {
EventParams,
EventsService,
EventSubscriber,
} from '@backstage/plugin-events-node';
import { EventParams, EventsService } from '@backstage/plugin-events-node';
import { graphql } from '@octokit/graphql';
import {
MembershipEvent,
@@ -138,9 +134,7 @@ export interface GithubOrgEntityProviderOptions {
*
* @public
*/
export class GithubOrgEntityProvider
implements EntityProvider, EventSubscriber
{
export class GithubOrgEntityProvider implements EntityProvider {
private readonly credentialsProvider: GithubCredentialsProvider;
private connection?: EntityProviderConnection;
private scheduleFn?: () => Promise<void>;
@@ -268,8 +262,7 @@ export class GithubOrgEntityProvider
markCommitComplete();
}
/** {@inheritdoc @backstage/plugin-events-node#EventSubscriber.onEvent} */
async onEvent(params: EventParams): Promise<void> {
private async onEvent(params: EventParams): Promise<void> {
const { logger } = this.options;
logger.debug(`Received event from ${params.topic}`);
@@ -335,11 +328,6 @@ export class GithubOrgEntityProvider
return;
}
/** {@inheritdoc @backstage/plugin-events-node#EventSubscriber.supportsEventTopics} */
supportsEventTopics(): string[] {
return EVENT_TOPICS;
}
private async onTeamEditedInOrganization(
event: TeamEditedEvent,
createDeltaOperation: DeferredEntitiesBuilder,