Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GM-833] Update Apollo Graph Manager API Key environment variable #3923

Merged
merged 19 commits into from
Apr 23, 2020
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ The version headers in this history reflect the versions of Apollo Server itself
- [__CHANGELOG for `@apollo/federation`__](https://github.com/apollographql/apollo-server/blob/master/packages/apollo-federation/CHANGELOG.md)

### vNEXT

> The changes noted within this `vNEXT` section have not been released yet. New PRs and commits which introduce changes should include an entry in this `vNEXT` section as part of their development. When a release is being prepared, a new header will be (manually) created below and the the appropriate changes within that release will be moved into the new section.

- `apollo-engine-reporting`: Deprecate the `ENGINE_API_KEY` environment variable in favor of its new name, `APOLLO_KEY`. Continued use of `ENGINE_API_KEY` will result in deprecation warnings and support for it will be removed in a future major version. [#3923](https://github.com/apollographql/apollo-server/pull/3923)
- `apollo-engine-reporting`: Deprecated the `APOLLO_SCHEMA_TAG` environment variable in favor of its new name, `APOLLO_GRAPH_VARIANT`. Similarly, within the `engine` configuration object, the `schemaTag` property has been renamed `graphVariant`. The functionality remains otherwise unchanged, but their new names mirror the name used within Apollo Graph Manager. Continued use of the now-deprecated names will result in deprecation warnings and support will be dropped completely in the next "major" update. To avoid misconfiguration, a runtime error will be thrown if _both_ new and deprecated names are set. [PR #3855](https://github.com/apollographql/apollo-server/pull/3855)
- Allow passing a `WebSocket.Server` to `ApolloServer.installSubscriptionHandlers`. [PR #2314](https://github.com/apollographql/apollo-server/pull/2314)

Expand Down
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 30 additions & 5 deletions packages/apollo-engine-reporting/src/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { GraphQLRequestContext, Logger } from 'apollo-server-types';
import { InMemoryLRUCache } from 'apollo-server-caching';
import { defaultEngineReportingSignature } from 'apollo-graphql';

let warnedOnDeprecatedApiKey = false;

export interface ClientInfo {
clientName?: string;
clientVersion?: string;
Expand Down Expand Up @@ -45,7 +47,30 @@ export type GenerateClientInfo<TContext> = (
requestContext: GraphQLRequestContext<TContext>,
) => ClientInfo;

// AS3: Drop support for deprecated bits.
// AS3: Drop support for deprecated `ENGINE_API_KEY`.
export function getEngineApiKey(
{engine, skipWarn = false, logger= console }:
{engine: EngineReportingOptions<any> | boolean | undefined, skipWarn?: boolean, logger?: Logger }
) {
if (typeof engine === 'object') {
if (engine.apiKey) {
return engine.apiKey;
}
}
const legacyApiKeyFromEnv = process.env.ENGINE_API_KEY;
const apiKeyFromEnv = process.env.APOLLO_KEY;

if(legacyApiKeyFromEnv && apiKeyFromEnv && !skipWarn) {
logger.warn(`Both ENGINE_API_KEY (deprecated) and APOLLO_KEY are set; defaulting to APOLLO_KEY.`);
}
if(legacyApiKeyFromEnv && !warnedOnDeprecatedApiKey && !skipWarn) {
logger.warn(`[deprecated] Setting the key via ENGINE_API_KEY is deprecated and will not be supported in future versions.`);
warnedOnDeprecatedApiKey = true;
}
return apiKeyFromEnv || legacyApiKeyFromEnv || ''
}

// AS3: Drop support for deprecated `ENGINE_SCHEMA_TAG`.
export function getEngineGraphVariant(engine: EngineReportingOptions<any> | boolean | undefined, logger: Logger = console): string | undefined {
if (engine === false) {
return;
Expand Down Expand Up @@ -242,9 +267,9 @@ const serviceHeaderDefaults = {
// EngineReportingExtensions for each request and sends batches of trace reports
// to the Engine server.
export class EngineReportingAgent<TContext = any> {
private options: EngineReportingOptions<TContext>;
private readonly options: EngineReportingOptions<TContext>;
private readonly apiKey: string;
private logger: Logger = console;
private apiKey: string;
private graphVariant: string;
private reports: { [schemaHash: string]: FullTracesReport } = Object.create(
null,
Expand All @@ -262,12 +287,12 @@ export class EngineReportingAgent<TContext = any> {

public constructor(options: EngineReportingOptions<TContext> = {}) {
this.options = options;
this.apiKey = getEngineApiKey({engine: this.options, skipWarn: false, logger: this.logger});
if (options.logger) this.logger = options.logger;
this.apiKey = options.apiKey || process.env.ENGINE_API_KEY || '';
this.graphVariant = getEngineGraphVariant(options, this.logger) || '';
if (!this.apiKey) {
throw new Error(
'To use EngineReportingAgent, you must specify an API key via the apiKey option or the ENGINE_API_KEY environment variable.',
`To use EngineReportingAgent, you must specify an API key via the apiKey option or the APOLLO_KEY environment variable.`,
);
}

Expand Down
4 changes: 3 additions & 1 deletion packages/apollo-gateway/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

> The changes noted within this `vNEXT` section have not been released yet. New PRs and commits which introduce changes should include an entry in this `vNEXT` section as part of their development. When a release is being prepared, a new header will be (manually) created below and the the appropriate changes within that release will be moved into the new section.

- Deprecated the `APOLLO_SCHEMA_TAG` environment variable in favor of its new name, `APOLLO_GRAPH_VARIANT`. The functionality remains otherwise identical, but the new name mirrors the name used within Apollo Graph Manager. Use of the now-deprecated name will result in a deprecation warning and support will be dropped completely in a future "major" update. To avoid misconfiguration, runtime errors will be thrown if the new and deprecated name are _both_ set. [#3855](https://github.com/apollographql/apollo-server/pull/3855)
- Deprecated the `ENGINE_API_KEY` environment variable in favor of its new name, `APOLLO_KEY`. Continued use of `ENGINE_API_KEY` will result in deprecation warnings being printed to the server console. Support for `ENGINE_API_KEY` will be removed in a future, major update. [#3923](https://github.com/apollographql/apollo-server/pull/3923)
- Deprecated the `APOLLO_SCHEMA_TAG` environment variable in favor of its new name, `APOLLO_GRAPH_VARIANT`. The functionality remains otherwise identical, but the new name mirrors the name used within Apollo Graph Manager. Use of the now-deprecated name will result in a deprecation warning being printed to the server console. Support will be removed entirely in a future, major update. To avoid misconfiguration, runtime errors will be thrown if the new and deprecated name are _both_ set. [#3855](https://github.com/apollographql/apollo-server/pull/3855)
- Cache stringified representations of downstream query bodies within the query plan to address performance implications incurred by repeatedly `print`ing the same`DocumentNode`s with the `graphql` printer. This improvement is more pronounced on larger documents. [PR #4018](https://github.com/apollographql/apollo-server/pull/4018)
- Add inadvertently excluded `apollo-server-errors` runtime dependency. [#3927](https://github.com/apollographql/apollo-server/pull/3927)

Expand All @@ -29,6 +30,7 @@
- Implement retry logic for requests to GCS [PR #3836](https://github.com/apollographql/apollo-server/pull/3836) Note: coupled with this change is a small alteration in how the gateway polls GCS for updates in managed mode. Previously, the tick was on a specific interval. Now, every tick starts after the round of fetches to GCS completes. For more details, see the linked PR.
- Gateway issues health checks to downstream services via `serviceHealthCheck` configuration option. Note: expected behavior differs between managed and unmanaged federation. See PR for new test cases and documentation. [#3930](https://github.com/apollographql/apollo-server/pull/3930)


## 0.13.2

- __BREAKING__: The behavior and signature of `RemoteGraphQLDataSource`'s `didReceiveResponse` method has been changed. No changes are necessary _unless_ your implementation has overridden the default behavior of this method by either extending the class and overriding the method or by providing `didReceiveResponse` as a parameter to the `RemoteGraphQLDataSource`'s constructor options. Implementations which have provided their own `didReceiveResponse` using either of these methods should view the PR linked here for details on what has changed. [PR #3743](https://github.com/apollographql/apollo-server/pull/3743)
Expand Down
22 changes: 5 additions & 17 deletions packages/apollo-server-core/src/ApolloServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ import {

import { Headers } from 'apollo-server-env';
import { buildServiceDefinition } from '@apollographql/apollo-tools';
import {getEngineGraphVariant} from "apollo-engine-reporting/dist/agent";
import { getEngineApiKey, getEngineGraphVariant } from "apollo-engine-reporting/dist/agent";
import { Logger } from "apollo-server-types";

const NoIntrospection = (context: ValidationContext) => ({
Expand All @@ -87,20 +87,8 @@ const NoIntrospection = (context: ValidationContext) => ({
},
});

function getEngineApiKey(engine: Config['engine']): string | undefined {
const keyFromEnv = process.env.ENGINE_API_KEY || '';
if (engine === false) {
return;
} else if (typeof engine === 'object' && engine.apiKey) {
return engine.apiKey;
} else if (keyFromEnv) {
return keyFromEnv;
}
return;
}

function getEngineServiceId(engine: Config['engine']): string | undefined {
const engineApiKey = getEngineApiKey(engine);
function getEngineServiceId(engine: Config['engine'], logger: Logger): string | undefined {
const engineApiKey = getEngineApiKey({engine, skipWarn: true, logger} );
if (engineApiKey) {
return engineApiKey.split(':', 2)[1];
}
Expand Down Expand Up @@ -330,8 +318,8 @@ export class ApolloServerBase {
// service ID from the API key for plugins which only needs service ID.
// The truthiness of this value can also be used in other forks of logic
// related to Engine, as is the case with EngineReportingAgent just below.
this.engineServiceId = getEngineServiceId(engine);
const apiKey = getEngineApiKey(engine);
this.engineServiceId = getEngineServiceId(engine, this.logger);
const apiKey = getEngineApiKey({engine, skipWarn: true, logger: this.logger});
if (apiKey) {
this.engineApiKeyHash = createSHA('sha512')
.update(apiKey)
Expand Down
47 changes: 47 additions & 0 deletions packages/apollo-server-core/src/__tests__/ApolloServerBase.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,50 @@ describe('ApolloServerBase construction', () => {
);
});
});

describe('environment variables', () => {
const OLD_ENV = process.env;

beforeEach(() => {
jest.resetModules();
process.env = { ...OLD_ENV };
delete process.env.ENGINE_API_KEY;
delete process.env.APOLLO_KEY;
});

afterEach(() => {
process.env = OLD_ENV;
});

it('constructs a reporting agent with the ENGINE_API_KEY (deprecated) environment variable and warns', async () => {
// set the variables
process.env.ENGINE_API_KEY = 'just:fake:stuff';
const spyConsoleWarn = jest.spyOn(console, 'warn').mockImplementation();

const server = new ApolloServerBase({
typeDefs,
resolvers
});

await server.stop();
expect(spyConsoleWarn).toHaveBeenCalledTimes(1);
spyConsoleWarn.mockReset();
});

it('warns with both the legacy env var and new env var set', async () => {
// set the variables
process.env.ENGINE_API_KEY = 'just:fake:stuff';
process.env.APOLLO_KEY = 'also:fake:stuff';
const spyConsoleWarn = jest.spyOn(console, 'warn').mockImplementation();

const server = new ApolloServerBase({
typeDefs,
resolvers
});

await server.stop();
// Once for deprecation, once for double-set
expect(spyConsoleWarn).toHaveBeenCalledTimes(2);
spyConsoleWarn.mockReset();
});
});