Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Composer } from '../../composition/composer.js';
import { AuditLogRepository } from '../../repositories/AuditLogRepository.js';
import { ContractRepository } from '../../repositories/ContractRepository.js';
import { FederatedGraphRepository } from '../../repositories/FederatedGraphRepository.js';
import { FeatureFlagRepository } from '../../repositories/FeatureFlagRepository.js';
import { GraphCompositionRepository } from '../../repositories/GraphCompositionRepository.js';
import { DefaultNamespace, NamespaceRepository } from '../../repositories/NamespaceRepository.js';
import { OrganizationRepository } from '../../repositories/OrganizationRepository.js';
Expand Down Expand Up @@ -420,6 +421,7 @@ export function createProposal(
const schemaCheckRepo = new SchemaCheckRepository(opts.db);
const contractRepo = new ContractRepository(logger, opts.db, authContext.organizationId);
const graphCompostionRepo = new GraphCompositionRepository(logger, opts.db);
const featureFlagRepo = new FeatureFlagRepository(logger, opts.db, authContext.organizationId);
const trafficInspector = new SchemaUsageTrafficInspector(opts.chClient!);
const composer = new Composer(
logger,
Expand All @@ -428,6 +430,7 @@ export function createProposal(
subgraphRepo,
contractRepo,
graphCompostionRepo,
featureFlagRepo,
opts.chClient,
opts.webhookProxyUrl,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { enrichLogger, getLogger, handleError } from '../../util.js';
import { AuditLogRepository } from '../../repositories/AuditLogRepository.js';
import { ContractRepository } from '../../repositories/ContractRepository.js';
import { FederatedGraphRepository } from '../../repositories/FederatedGraphRepository.js';
import { FeatureFlagRepository } from '../../repositories/FeatureFlagRepository.js';
import { GraphCompositionRepository } from '../../repositories/GraphCompositionRepository.js';
import { DefaultNamespace, NamespaceRepository } from '../../repositories/NamespaceRepository.js';
import { OrganizationRepository } from '../../repositories/OrganizationRepository.js';
Expand Down Expand Up @@ -485,6 +486,7 @@ export function updateProposal(
const schemaCheckRepo = new SchemaCheckRepository(opts.db);
const contractRepo = new ContractRepository(logger, opts.db, authContext.organizationId);
const graphCompostionRepo = new GraphCompositionRepository(logger, opts.db);
const featureFlagRepo = new FeatureFlagRepository(logger, opts.db, authContext.organizationId);
const trafficInspector = new SchemaUsageTrafficInspector(opts.chClient!);
const composer = new Composer(
logger,
Expand All @@ -493,6 +495,7 @@ export function updateProposal(
subgraphRepo,
contractRepo,
graphCompostionRepo,
featureFlagRepo,
opts.chClient,
opts.webhookProxyUrl,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { buildSchema } from '../../composition/composition.js';
import { OpenAIGraphql } from '../../openai-graphql/index.js';
import { ContractRepository } from '../../repositories/ContractRepository.js';
import { FederatedGraphRepository } from '../../repositories/FederatedGraphRepository.js';
import { FeatureFlagRepository } from '../../repositories/FeatureFlagRepository.js';
import { GraphCompositionRepository } from '../../repositories/GraphCompositionRepository.js';
import { DefaultNamespace, NamespaceRepository } from '../../repositories/NamespaceRepository.js';
import { OrganizationRepository } from '../../repositories/OrganizationRepository.js';
Expand All @@ -33,6 +34,7 @@ export function fixSubgraphSchema(
const subgraphRepo = new SubgraphRepository(logger, opts.db, authContext.organizationId);
const contractRepo = new ContractRepository(logger, opts.db, authContext.organizationId);
const graphCompositionRepo = new GraphCompositionRepository(logger, opts.db);
const featureFlagRepo = new FeatureFlagRepository(logger, opts.db, authContext.organizationId);
const namespaceRepo = new NamespaceRepository(opts.db, authContext.organizationId);

const composer = new Composer(
Expand All @@ -42,6 +44,7 @@ export function fixSubgraphSchema(
subgraphRepo,
contractRepo,
graphCompositionRepo,
featureFlagRepo,
opts.chClient,
opts.webhookProxyUrl,
);
Expand Down
26 changes: 16 additions & 10 deletions controlplane/src/core/composition/composer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,15 @@ import {
RouterConfigSchema,
} from '@wundergraph/cosmo-connect/dist/node/v1/node_pb';

import type {
FeatureFlagRouterExecutionConfig,
FeatureFlagRouterExecutionConfigs,
RouterConfig,
} from '@wundergraph/cosmo-connect/dist/node/v1/node_pb';
import type { FeatureFlagRouterExecutionConfig, RouterConfig } from '@wundergraph/cosmo-connect/dist/node/v1/node_pb';

import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
import { FederatedGraphDTO, Label, SubgraphDTO } from '../../types/index.js';
import { BlobStorage } from '../blobstorage/index.js';
import { audiences, nowInSeconds, signJwtHS256 } from '../crypto/jwt.js';
import { ContractRepository } from '../repositories/ContractRepository.js';
import { FederatedGraphRepository } from '../repositories/FederatedGraphRepository.js';
import { FeatureFlagRepository } from '../repositories/FeatureFlagRepository.js';
import { SubgraphRepository } from '../repositories/SubgraphRepository.js';
import {
AdmissionError,
Expand Down Expand Up @@ -157,6 +154,7 @@ export class Composer {
private subgraphRepo: SubgraphRepository,
private contractRepo: ContractRepository,
private graphCompositionRepository: GraphCompositionRepository,
private featureFlagRepo: FeatureFlagRepository,
private chClient?: ClickHouseClient,
private proxyUrl?: string,
) {}
Expand Down Expand Up @@ -462,9 +460,17 @@ export class Composer {
featureFlagId: string;
splitConfigEnabled: boolean;
}): Promise<CompositionDeployResult> {
const prevValidFederatedSDL = await this.federatedGraphRepo.getLatestValidSchemaVersion({
targetId: composedGraph.targetID,
});
// For a feature-flag composition the baseline is the previous composition of the same feature flag (not the base
// graph's latest valid version, which would produce a meaningless base-vs-feature-flag diff). Computed before
// addSchemaVersion inserts the new version, so it resolves to the chronologically prior feature-flag version.
const prevValidFederatedSDL = isFeatureFlagComposition
? await this.featureFlagRepo.getLatestValidFeatureFlagSchemaVersion({
targetId: composedGraph.targetID,
featureFlagId,
})
: await this.federatedGraphRepo.getLatestValidSchemaVersion({
targetId: composedGraph.targetID,
});

const updatedFederatedGraph = await this.federatedGraphRepo.addSchemaVersion({
targetId: composedGraph.targetID,
Expand All @@ -480,8 +486,8 @@ export class Composer {
splitConfigEnabled,
});

// If the composed schema is invalid, or it is a feature flag composition, we do not create a changelog
if (!routerExecutionConfig || !updatedFederatedGraph?.composedSchemaVersionId || isFeatureFlagComposition) {
// If the composed schema is invalid, we do not create a changelog
if (!routerExecutionConfig || !updatedFederatedGraph?.composedSchemaVersionId) {
return {
schemaVersionId: updatedFederatedGraph?.composedSchemaVersionId || '',
};
Expand Down
35 changes: 35 additions & 0 deletions controlplane/src/core/repositories/FeatureFlagRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1618,6 +1618,41 @@ export class FeatureFlagRepository {
return ffSchemaVersion;
}

public async getLatestValidFeatureFlagSchemaVersion(data: { targetId: string; featureFlagId: string }) {
const latest = await this.db
.select({
schema: schemaVersion.schemaSDL,
clientSchema: schemaVersion.clientSchema,
schemaVersionId: schemaVersion.id,
})
.from(federatedGraphsToFeatureFlagSchemaVersions)
.innerJoin(
schemaVersion,
eq(schemaVersion.id, federatedGraphsToFeatureFlagSchemaVersions.composedSchemaVersionId),
)
.innerJoin(graphCompositions, eq(graphCompositions.schemaVersionId, schemaVersion.id))
.where(
and(
eq(schemaVersion.targetId, data.targetId),
eq(schemaVersion.organizationId, this.organizationId),
eq(federatedGraphsToFeatureFlagSchemaVersions.featureFlagId, data.featureFlagId),
eq(graphCompositions.isFeatureFlagComposition, true),
eq(graphCompositions.isComposable, true),
or(isNull(graphCompositions.deploymentError), eq(graphCompositions.deploymentError, '')),
or(isNull(graphCompositions.admissionError), eq(graphCompositions.admissionError, '')),
),
)
.orderBy(desc(graphCompositions.createdAt))
.limit(1)
.execute();

if (latest.length === 0) {
return undefined;
}

return latest[0];
}

public async delete(featureFlagId: string) {
await this.db
.delete(featureFlags)
Expand Down
1 change: 1 addition & 0 deletions controlplane/src/core/repositories/SubgraphRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2515,6 +2515,7 @@ export class SubgraphRepository {
subgraphRepo,
contractRepo,
graphCompostionRepo,
featureFlagRepo,
chClient,
webhookProxyUrl,
);
Expand Down
2 changes: 2 additions & 0 deletions controlplane/src/core/services/CompositionService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ export class CompositionService {
new SubgraphRepository(this.logger, this.db, this.organizationId),
new ContractRepository(this.logger, this.db, this.organizationId),
new GraphCompositionRepository(this.logger, this.db),
new FeatureFlagRepository(this.logger, this.db, this.organizationId),
this.chClient,
this.webhookProxyUrl,
);
Expand Down Expand Up @@ -1328,6 +1329,7 @@ export class CompositionService {
new SubgraphRepository(this.logger, this.db, this.organizationId),
new ContractRepository(this.logger, this.db, this.organizationId),
new GraphCompositionRepository(this.logger, this.db),
new FeatureFlagRepository(this.logger, this.db, this.organizationId),
this.chClient,
this.webhookProxyUrl,
);
Expand Down
Loading
Loading