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 @@ -7,7 +7,7 @@

import { createQueryService } from "@bufbuild/connect-query";
import { MethodIdempotency, MethodKind } from "@bufbuild/protobuf";
import { CheckFederatedGraphRequest, CheckFederatedGraphResponse, CheckSubgraphSchemaRequest, CheckSubgraphSchemaResponse, CreateAPIKeyRequest, CreateAPIKeyResponse, CreateFederatedGraphRequest, CreateFederatedGraphResponse, CreateFederatedGraphTokenRequest, CreateFederatedGraphTokenResponse, CreateFederatedSubgraphRequest, CreateFederatedSubgraphResponse, DeleteAPIKeyRequest, DeleteAPIKeyResponse, DeleteFederatedGraphRequest, DeleteFederatedGraphResponse, DeleteFederatedSubgraphRequest, DeleteFederatedSubgraphResponse, FixSubgraphSchemaRequest, FixSubgraphSchemaResponse, GetAnalyticsViewRequest, GetAnalyticsViewResponse, GetAPIKeysRequest, GetAPIKeysResponse, GetCheckDetailsRequest, GetCheckDetailsResponse, GetChecksByFederatedGraphNameRequest, GetChecksByFederatedGraphNameResponse, GetDashboardAnalyticsViewRequest, GetDashboardAnalyticsViewResponse, GetFederatedGraphByNameRequest, GetFederatedGraphByNameResponse, GetFederatedGraphChangelogRequest, GetFederatedGraphChangelogResponse, GetFederatedGraphSDLByNameRequest, GetFederatedGraphSDLByNameResponse, GetFederatedGraphsRequest, GetFederatedGraphsResponse, GetFederatedSubgraphSDLByNameRequest, GetFederatedSubgraphSDLByNameResponse, GetOrganizationMembersRequest, GetOrganizationMembersResponse, GetSubgraphByNameRequest, GetSubgraphByNameResponse, GetSubgraphsRequest, GetSubgraphsResponse, GetTraceRequest, GetTraceResponse, InviteUserRequest, InviteUserResponse, PublishFederatedSubgraphRequest, PublishFederatedSubgraphResponse, RemoveInvitationRequest, RemoveInvitationResponse, UpdateFederatedGraphRequest, UpdateFederatedGraphResponse, UpdateSubgraphRequest, UpdateSubgraphResponse } from "./platform_pb.js";
import { CheckFederatedGraphRequest, CheckFederatedGraphResponse, CheckSubgraphSchemaRequest, CheckSubgraphSchemaResponse, CreateAPIKeyRequest, CreateAPIKeyResponse, CreateFederatedGraphRequest, CreateFederatedGraphResponse, CreateFederatedGraphTokenRequest, CreateFederatedGraphTokenResponse, CreateFederatedSubgraphRequest, CreateFederatedSubgraphResponse, DeleteAPIKeyRequest, DeleteAPIKeyResponse, DeleteFederatedGraphRequest, DeleteFederatedGraphResponse, DeleteFederatedSubgraphRequest, DeleteFederatedSubgraphResponse, FixSubgraphSchemaRequest, FixSubgraphSchemaResponse, GetAnalyticsViewRequest, GetAnalyticsViewResponse, GetAPIKeysRequest, GetAPIKeysResponse, GetCheckDetailsRequest, GetCheckDetailsResponse, GetChecksByFederatedGraphNameRequest, GetChecksByFederatedGraphNameResponse, GetDashboardAnalyticsViewRequest, GetDashboardAnalyticsViewResponse, GetFederatedGraphByNameRequest, GetFederatedGraphByNameResponse, GetFederatedGraphChangelogRequest, GetFederatedGraphChangelogResponse, GetFederatedGraphSDLByNameRequest, GetFederatedGraphSDLByNameResponse, GetFederatedGraphsRequest, GetFederatedGraphsResponse, GetFederatedSubgraphSDLByNameRequest, GetFederatedSubgraphSDLByNameResponse, GetOrganizationMembersRequest, GetOrganizationMembersResponse, GetSubgraphByNameRequest, GetSubgraphByNameResponse, GetSubgraphsRequest, GetSubgraphsResponse, GetTraceRequest, GetTraceResponse, InviteUserRequest, InviteUserResponse, MigrateFromApolloRequest, MigrateFromApolloResponse, PublishFederatedSubgraphRequest, PublishFederatedSubgraphResponse, RemoveInvitationRequest, RemoveInvitationResponse, UpdateFederatedGraphRequest, UpdateFederatedGraphResponse, UpdateSubgraphRequest, UpdateSubgraphResponse } from "./platform_pb.js";
import { GetConfigRequest, GetConfigResponse } from "../../node/v1/node_pb.js";

export const typeName = "wg.cosmo.platform.v1.PlatformService";
Expand Down Expand Up @@ -523,6 +523,25 @@ export const getLatestValidRouterConfig = createQueryService({
},
}).getLatestValidRouterConfig;

/**
* MigrateFromApollo migrates the graphs from apollo to cosmo
*
* @generated from rpc wg.cosmo.platform.v1.PlatformService.MigrateFromApollo
*/
export const migrateFromApollo = createQueryService({
service: {
methods: {
migrateFromApollo: {
name: "MigrateFromApollo",
kind: MethodKind.Unary,
I: MigrateFromApolloRequest,
O: MigrateFromApolloResponse,
},
},
typeName: "wg.cosmo.platform.v1.PlatformService",
},
}).migrateFromApollo;

/**
* @generated from rpc wg.cosmo.platform.v1.PlatformService.GetAnalyticsView
*/
Expand Down
13 changes: 12 additions & 1 deletion connect/src/wg/cosmo/platform/v1/platform_connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/* eslint-disable */
// @ts-nocheck

import { CheckFederatedGraphRequest, CheckFederatedGraphResponse, CheckSubgraphSchemaRequest, CheckSubgraphSchemaResponse, CreateAPIKeyRequest, CreateAPIKeyResponse, CreateFederatedGraphRequest, CreateFederatedGraphResponse, CreateFederatedGraphTokenRequest, CreateFederatedGraphTokenResponse, CreateFederatedSubgraphRequest, CreateFederatedSubgraphResponse, DeleteAPIKeyRequest, DeleteAPIKeyResponse, DeleteFederatedGraphRequest, DeleteFederatedGraphResponse, DeleteFederatedSubgraphRequest, DeleteFederatedSubgraphResponse, FixSubgraphSchemaRequest, FixSubgraphSchemaResponse, GetAnalyticsViewRequest, GetAnalyticsViewResponse, GetAPIKeysRequest, GetAPIKeysResponse, GetCheckDetailsRequest, GetCheckDetailsResponse, GetChecksByFederatedGraphNameRequest, GetChecksByFederatedGraphNameResponse, GetDashboardAnalyticsViewRequest, GetDashboardAnalyticsViewResponse, GetFederatedGraphByNameRequest, GetFederatedGraphByNameResponse, GetFederatedGraphChangelogRequest, GetFederatedGraphChangelogResponse, GetFederatedGraphSDLByNameRequest, GetFederatedGraphSDLByNameResponse, GetFederatedGraphsRequest, GetFederatedGraphsResponse, GetFederatedSubgraphSDLByNameRequest, GetFederatedSubgraphSDLByNameResponse, GetOrganizationMembersRequest, GetOrganizationMembersResponse, GetSubgraphByNameRequest, GetSubgraphByNameResponse, GetSubgraphsRequest, GetSubgraphsResponse, GetTraceRequest, GetTraceResponse, InviteUserRequest, InviteUserResponse, PublishFederatedSubgraphRequest, PublishFederatedSubgraphResponse, RemoveInvitationRequest, RemoveInvitationResponse, UpdateFederatedGraphRequest, UpdateFederatedGraphResponse, UpdateSubgraphRequest, UpdateSubgraphResponse } from "./platform_pb.js";
import { CheckFederatedGraphRequest, CheckFederatedGraphResponse, CheckSubgraphSchemaRequest, CheckSubgraphSchemaResponse, CreateAPIKeyRequest, CreateAPIKeyResponse, CreateFederatedGraphRequest, CreateFederatedGraphResponse, CreateFederatedGraphTokenRequest, CreateFederatedGraphTokenResponse, CreateFederatedSubgraphRequest, CreateFederatedSubgraphResponse, DeleteAPIKeyRequest, DeleteAPIKeyResponse, DeleteFederatedGraphRequest, DeleteFederatedGraphResponse, DeleteFederatedSubgraphRequest, DeleteFederatedSubgraphResponse, FixSubgraphSchemaRequest, FixSubgraphSchemaResponse, GetAnalyticsViewRequest, GetAnalyticsViewResponse, GetAPIKeysRequest, GetAPIKeysResponse, GetCheckDetailsRequest, GetCheckDetailsResponse, GetChecksByFederatedGraphNameRequest, GetChecksByFederatedGraphNameResponse, GetDashboardAnalyticsViewRequest, GetDashboardAnalyticsViewResponse, GetFederatedGraphByNameRequest, GetFederatedGraphByNameResponse, GetFederatedGraphChangelogRequest, GetFederatedGraphChangelogResponse, GetFederatedGraphSDLByNameRequest, GetFederatedGraphSDLByNameResponse, GetFederatedGraphsRequest, GetFederatedGraphsResponse, GetFederatedSubgraphSDLByNameRequest, GetFederatedSubgraphSDLByNameResponse, GetOrganizationMembersRequest, GetOrganizationMembersResponse, GetSubgraphByNameRequest, GetSubgraphByNameResponse, GetSubgraphsRequest, GetSubgraphsResponse, GetTraceRequest, GetTraceResponse, InviteUserRequest, InviteUserResponse, MigrateFromApolloRequest, MigrateFromApolloResponse, PublishFederatedSubgraphRequest, PublishFederatedSubgraphResponse, RemoveInvitationRequest, RemoveInvitationResponse, UpdateFederatedGraphRequest, UpdateFederatedGraphResponse, UpdateSubgraphRequest, UpdateSubgraphResponse } from "./platform_pb.js";
import { MethodIdempotency, MethodKind } from "@bufbuild/protobuf";
import { GetConfigRequest, GetConfigResponse } from "../../node/v1/node_pb.js";

Expand Down Expand Up @@ -310,6 +310,17 @@ export const PlatformService = {
O: GetConfigResponse,
kind: MethodKind.Unary,
},
/**
* MigrateFromApollo migrates the graphs from apollo to cosmo
*
* @generated from rpc wg.cosmo.platform.v1.PlatformService.MigrateFromApollo
*/
migrateFromApollo: {
name: "MigrateFromApollo",
I: MigrateFromApolloRequest,
O: MigrateFromApolloResponse,
kind: MethodKind.Unary,
},
/**
* @generated from rpc wg.cosmo.platform.v1.PlatformService.GetAnalyticsView
*/
Expand Down
74 changes: 74 additions & 0 deletions connect/src/wg/cosmo/platform/v1/platform_pb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3940,6 +3940,80 @@ export class RemoveInvitationResponse extends Message<RemoveInvitationResponse>
}
}

/**
* @generated from message wg.cosmo.platform.v1.MigrateFromApolloRequest
*/
export class MigrateFromApolloRequest extends Message<MigrateFromApolloRequest> {
/**
* @generated from field: string apiKey = 1;
*/
apiKey = "";

constructor(data?: PartialMessage<MigrateFromApolloRequest>) {
super();
proto3.util.initPartial(data, this);
}

static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "wg.cosmo.platform.v1.MigrateFromApolloRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "apiKey", kind: "scalar", T: 9 /* ScalarType.STRING */ },
]);

static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): MigrateFromApolloRequest {
return new MigrateFromApolloRequest().fromBinary(bytes, options);
}

static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): MigrateFromApolloRequest {
return new MigrateFromApolloRequest().fromJson(jsonValue, options);
}

static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): MigrateFromApolloRequest {
return new MigrateFromApolloRequest().fromJsonString(jsonString, options);
}

static equals(a: MigrateFromApolloRequest | PlainMessage<MigrateFromApolloRequest> | undefined, b: MigrateFromApolloRequest | PlainMessage<MigrateFromApolloRequest> | undefined): boolean {
return proto3.util.equals(MigrateFromApolloRequest, a, b);
}
}

/**
* @generated from message wg.cosmo.platform.v1.MigrateFromApolloResponse
*/
export class MigrateFromApolloResponse extends Message<MigrateFromApolloResponse> {
/**
* @generated from field: wg.cosmo.platform.v1.Response response = 1;
*/
response?: Response;

constructor(data?: PartialMessage<MigrateFromApolloResponse>) {
super();
proto3.util.initPartial(data, this);
}

static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "wg.cosmo.platform.v1.MigrateFromApolloResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "response", kind: "message", T: Response },
]);

static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): MigrateFromApolloResponse {
return new MigrateFromApolloResponse().fromBinary(bytes, options);
}

static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): MigrateFromApolloResponse {
return new MigrateFromApolloResponse().fromJson(jsonValue, options);
}

static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): MigrateFromApolloResponse {
return new MigrateFromApolloResponse().fromJsonString(jsonString, options);
}

static equals(a: MigrateFromApolloResponse | PlainMessage<MigrateFromApolloResponse> | undefined, b: MigrateFromApolloResponse | PlainMessage<MigrateFromApolloResponse> | undefined): boolean {
return proto3.util.equals(MigrateFromApolloResponse, a, b);
}
}

/**
* @generated from message wg.cosmo.platform.v1.SpanAttributes
*/
Expand Down
80 changes: 80 additions & 0 deletions controlplane/src/core/bufservices/PlatformService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import { TraceRepository } from '../repositories/analytics/TraceRepository.js';
import type { RouterOptions } from '../routes.js';
import { ApiKeyGenerator } from '../services/ApiGenerator.js';
import { handleError, isValidLabelMatchers, isValidLabels } from '../util.js';
import ApolloMigrator from '../services/ApolloMigrator.js';

export default function (opts: RouterOptions): Partial<ServiceImpl<typeof PlatformService>> {
return {
Expand Down Expand Up @@ -1721,5 +1722,84 @@ export default function (opts: RouterOptions): Partial<ServiceImpl<typeof Platfo
};
});
},

migrateFromApollo: (req, ctx) => {
const logger = opts.logger.child({
service: ctx.service.typeName,
method: ctx.method.name,
});

return handleError<PlainMessage<DeleteAPIKeyResponse>>(logger, async () => {
const authContext = await opts.authenticator.authenticate(ctx.requestHeader);
const orgRepo = new OrganizationRepository(opts.db);
const fedGraphRepo = new FederatedGraphRepository(opts.db, authContext.organizationId);
const subgraphRepo = new SubgraphRepository(opts.db, authContext.organizationId);

const org = await orgRepo.byId(authContext.organizationId);
if (!org) {
return {
response: {
code: EnumStatusCode.ERR_NOT_FOUND,
details: `Organization not found`,
},
};
}

const apolloMigrator = new ApolloMigrator({ apiKey: req.apiKey, organizationSlug: org.slug });

const graph = await apolloMigrator.fetchGraphID();
const graphDetails = await apolloMigrator.fetchGraphDetails({ graphID: graph.id, variantName: 'main' });

if (await fedGraphRepo.exists(graph.name)) {
return {
response: {
code: EnumStatusCode.ERR_ALREADY_EXISTS,
details: `Federated graph '${graph.name}' already exists.`,
},
};
}

for (const subgraph of graphDetails.subgraphs) {
if (await subgraphRepo.exists(subgraph.name)) {
return {
response: {
code: EnumStatusCode.ERR_ALREADY_EXISTS,
details: `Subgraph '${subgraph.name}' already exists`,
},
};
}
}

const federatedGraph = await apolloMigrator.migrateGraphFromApollo({
fedGraph: {
name: graph.name,
routingURL: graphDetails.fedGraphRoutingURL,
},
subgraphs: graphDetails.subgraphs,
organizationID: authContext.organizationId,
db: opts.db,
});

const compositionErrors = await updateComposedSchema({
federatedGraph,
fedGraphRepo,
subgraphRepo,
});

if (compositionErrors.length > 0) {
return {
response: {
code: EnumStatusCode.ERR_SUBGRAPH_COMPOSITION_FAILED,
},
};
}

return {
response: {
code: EnumStatusCode.OK,
},
};
});
},
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
GraphApiKeyDTO,
Label,
ListFilterOptions,
MigrationSubgraph,
SchemaChangeType,
} from '../../types/index.js';
import { updateComposedSchema } from '../composition/updateComposedSchema.js';
Expand Down
Loading