feat: remove the backstage.io/definition-at-location annotation

The annotation was superseded by the placeholder processor.
This commit is contained in:
Oliver Sand
2020-10-08 14:03:21 +02:00
parent 4922f1dff9
commit e6b00e3af9
6 changed files with 45 additions and 176 deletions
@@ -26,7 +26,6 @@ import { Config, ConfigReader } from '@backstage/config';
import { Logger } from 'winston';
import { CatalogRulesEnforcer } from './CatalogRules';
import { AnnotateLocationEntityProcessor } from './processors/AnnotateLocationEntityProcessor';
import { ApiDefinitionAtLocationProcessor } from './processors/ApiDefinitionAtLocationProcessor';
import { AzureApiReaderProcessor } from './processors/AzureApiReaderProcessor';
import { BitbucketApiReaderProcessor } from './processors/BitbucketApiReaderProcessor';
import { CodeOwnersProcessor } from './processors/CodeOwnersProcessor';
@@ -127,7 +126,6 @@ export class LocationReaders implements LocationReader {
new YamlProcessor(),
PlaceholderProcessor.default(),
new CodeOwnersProcessor(),
new ApiDefinitionAtLocationProcessor(),
new EntityPolicyProcessor(entityPolicy),
new LocationRefProcessor(),
new AnnotateLocationEntityProcessor(),
@@ -1,93 +0,0 @@
import { ApiEntity, Entity, LocationSpec } from '@backstage/catalog-model';
/*
* Copyright 2020 Spotify AB
*
* 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 { ApiDefinitionAtLocationProcessor } from './ApiDefinitionAtLocationProcessor';
describe('ApiDefinitionAtLocationProcessor', () => {
let processor: ApiDefinitionAtLocationProcessor;
let entity: Entity;
let location: LocationSpec;
beforeEach(() => {
processor = new ApiDefinitionAtLocationProcessor();
entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'API',
metadata: {
name: 'test',
},
spec: {
lifecycle: 'production',
owner: 'info@example.com',
type: 'openapi',
definition: 'Hello',
},
};
location = {
type: 'url',
target: `http://example.com/api.yaml`,
};
});
it('should skip entities without annotation', async () => {
const read = jest.fn().mockRejectedValue(new Error('boo'));
const generated = (await processor.processEntity(
entity,
location,
() => {},
read,
)) as ApiEntity;
expect(generated.spec.definition).toBe('Hello');
});
it('should load from location', async () => {
entity.metadata.annotations = {
'backstage.io/definition-at-location':
'url:http://example.com/openapi.yaml',
};
const read = jest.fn().mockResolvedValue(Buffer.from('Hello'));
const generated = (await processor.processEntity(
entity,
location,
() => {},
read,
)) as ApiEntity;
expect(generated.spec.definition).toBe('Hello');
expect(read.mock.calls[0][0]).toStrictEqual({
type: 'url',
target: 'http://example.com/openapi.yaml',
});
});
it('should throw errors while loading', async () => {
entity.metadata.annotations = {
'backstage.io/definition-at-location': 'missing',
};
const read = jest
.fn()
.mockRejectedValue(new Error('Failed to load location'));
await expect(
processor.processEntity(entity, location, () => {}, read),
).rejects.toThrow('Failed to load location');
});
});
@@ -1,59 +0,0 @@
/*
* Copyright 2020 Spotify AB
*
* 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 { ApiEntity, Entity, LocationSpec } from '@backstage/catalog-model';
import {
LocationProcessor,
LocationProcessorEmit,
LocationProcessorRead,
} from './types';
const DEFINITION_AT_LOCATION_ANNOTATION = 'backstage.io/definition-at-location';
export class ApiDefinitionAtLocationProcessor implements LocationProcessor {
async processEntity(
entity: Entity,
_location: LocationSpec,
_emit: LocationProcessorEmit,
read: LocationProcessorRead,
): Promise<Entity> {
if (
entity.kind !== 'API' ||
!entity.metadata.annotations ||
!entity.metadata.annotations[DEFINITION_AT_LOCATION_ANNOTATION]
) {
return entity;
}
const reference =
entity.metadata.annotations[DEFINITION_AT_LOCATION_ANNOTATION];
const { type, target } = extractReference(reference);
const data = await read({ type, target });
const definition = data.toString();
const apiEntity = entity as ApiEntity;
apiEntity.spec.definition = definition;
return entity;
}
}
function extractReference(reference: string): { type: string; target: string } {
const delimiterIndex = reference.indexOf(':');
const type = reference.slice(0, delimiterIndex);
const target = reference.slice(delimiterIndex + 1);
return { type, target };
}
@@ -20,7 +20,6 @@ export { results };
export * from './types';
export { AnnotateLocationEntityProcessor } from './AnnotateLocationEntityProcessor';
export { ApiDefinitionAtLocationProcessor } from './ApiDefinitionAtLocationProcessor';
export { AzureApiReaderProcessor } from './AzureApiReaderProcessor';
export { BitbucketApiReaderProcessor } from './BitbucketApiReaderProcessor';
export { CodeOwnersProcessor } from './CodeOwnersProcessor';