Fix missing service url in supergraph (#134)

Fixes #133
This commit is contained in:
Kamil Kisiela 2022-06-07 11:02:05 -07:00 committed by GitHub
parent 17ff5c40f0
commit 51ba76eff6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 115 additions and 6 deletions

View file

@ -0,0 +1,8 @@
type Query {
users: [User!]!
}
type User {
id: ID!
email: String!
}

View file

@ -573,6 +573,28 @@ export async function fetchSchemaFromCDN(selector: TargetSelectorInput, token: s
};
}
export async function fetchSupergraphFromCDN(selector: TargetSelectorInput, token: string) {
const cdnAccessResult = await createCdnAccess(selector, token);
if (cdnAccessResult.body.errors) {
throw new Error(cdnAccessResult.body.errors[0].message);
}
const cdn = cdnAccessResult.body.data!.createCdnToken;
const res = await axios.get<string>(`${cdn.url}/supergraph`, {
headers: {
'X-Hive-CDN-Key': cdn.token,
},
responseType: 'text',
});
return {
body: res.data,
status: res.status,
};
}
export async function fetchMetadataFromCDN(selector: TargetSelectorInput, token: string) {
const cdnAccessResult = await createCdnAccess(selector, token);

View file

@ -1,7 +1,13 @@
import { TargetAccessScope, ProjectType } from '@app/gql/graphql';
import { schemaPublish, schemaCheck } from '../../testkit/cli';
import { authenticate } from '../../testkit/auth';
import { createOrganization, joinOrganization, createProject, createToken } from '../../testkit/flow';
import {
createOrganization,
joinOrganization,
createProject,
createToken,
fetchSupergraphFromCDN,
} from '../../testkit/flow';
test('can publish and check a schema with target:registry:read access', async () => {
const { access_token: owner_access_token } = await authenticate('main');
@ -62,3 +68,72 @@ test('can publish and check a schema with target:registry:read access', async ()
'EXIT: 1'
);
});
test('service url should be available in supergraph', async () => {
const { access_token: owner_access_token } = await authenticate('main');
const orgResult = await createOrganization(
{
name: 'foo',
},
owner_access_token
);
const org = orgResult.body.data!.createOrganization.ok!.createdOrganizationPayload.organization;
const code = org.inviteCode;
// Join
const { access_token: member_access_token } = await authenticate('extra');
await joinOrganization(code, member_access_token);
const projectResult = await createProject(
{
organization: org.cleanId,
type: ProjectType.Federation,
name: 'foo',
},
owner_access_token
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
// Create a token with write rights
const writeTokenResult = await createToken(
{
name: 'test',
organization: org.cleanId,
project: project.cleanId,
target: target.cleanId,
organizationScopes: [],
projectScopes: [],
targetScopes: [TargetAccessScope.RegistryRead, TargetAccessScope.RegistryWrite],
},
owner_access_token
);
expect(writeTokenResult.body.errors).not.toBeDefined();
const writeToken = writeTokenResult.body.data!.createToken.ok!.secret;
await schemaPublish([
'--token',
writeToken,
'--author',
'Kamil',
'--commit',
'abc123',
'--service',
'users',
'--url',
'https://api.com/users-subgraph',
'fixtures/federation-init.graphql',
]);
const supergraph = await fetchSupergraphFromCDN(
{
organization: org.cleanId,
project: project.cleanId,
target: target.cleanId,
},
writeToken
);
expect(supergraph.body).toMatch('(name: "users" url: "https://api.com/users-subgraph")');
});

View file

@ -447,7 +447,7 @@ export class SchemaPublisher {
url: incomingSchema.url ?? null,
});
this.publishToCDN({
await this.publishToCDN({
valid,
target,
project,
@ -457,7 +457,7 @@ export class SchemaPublisher {
}
if (incomingSchema.metadata && latest.version && previousSchema) {
this.publishToCDN({
await this.publishToCDN({
valid,
target,
project,
@ -505,7 +505,7 @@ export class SchemaPublisher {
errors,
initial: isInitialSchema,
});
this.publishToCDN({
await this.publishToCDN({
valid,
target,
project,
@ -619,7 +619,7 @@ export class SchemaPublisher {
}) {
try {
if (valid) {
this.updateCDN({
await this.updateCDN({
target,
project,
schemas,

View file

@ -141,6 +141,9 @@ export async function handleRequest(request: Request, keyValidator: typeof isKey
});
}
} else {
console.log(
`CDN Artifact not found for targetId=${targetId}, artifactType=${artifactType}, storageKeyType=${storageKeyType}`
);
return new CDNArtifactNotFound(artifactType, targetId);
}
}

View file

@ -85,13 +85,14 @@ interface CompositionFailure {
}
const createFederation: (redis: RedisInstance, logger: FastifyLoggerInstance) => Orchestrator = (redis, logger) => {
const compose = reuse<ValidationInput, CompositionSuccess | CompositionFailure>(
const compose = reuse<ValidationInput | SupergraphInput, CompositionSuccess | CompositionFailure>(
async schemas => {
const result = composeAndValidate(
schemas.map(schema => {
return {
typeDefs: trimDescriptions(parse(schema.raw)),
name: schema.source,
url: 'url' in schema && typeof schema.url === 'string' ? schema.url : undefined,
};
})
);