diff --git a/package.json b/package.json index 524a093e..f53d8dc4 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ }, "license": "Apache-2.0", "dependencies": { - "@google-cloud/common": "^1.0.0", + "@google-cloud/common": "^2.0.0", "@types/console-log-level": "^1.4.0", "@types/semver": "^6.0.0", "console-log-level": "^1.4.0", diff --git a/ts/src/config.ts b/ts/src/config.ts index e4482423..c9574abb 100644 --- a/ts/src/config.ts +++ b/ts/src/config.ts @@ -20,6 +20,12 @@ const parseDuration: (str: string) => number = require('parse-duration'); // Configuration for Profiler. export interface Config extends GoogleAuthOptions { + /** + * The API endpoint of the service used to make requests. + * Defaults to `cloudprofiler.googleapis.com`. + */ + apiEndpoint?: string; + // Cloud Console projectId to associate profiles with instead of one read // from VM metadata server. projectId?: string; @@ -107,10 +113,6 @@ export interface Config extends GoogleAuthOptions { // https://nodejs.org/dist/latest-v9.x/docs/api/timers.html#timers_settimeout_callback_delay_args. serverBackoffCapMillis?: number; - // Allows user to specify API URL other than - // https://cloudprofiler.googleapis.com/v2. - baseApiUrl?: string; - // Time between profile collection. // For testing with startLocal() only. localProfilingPeriodMillis?: number; @@ -148,6 +150,7 @@ export interface Config extends GoogleAuthOptions { // Interface for an initialized config. export interface ProfilerConfig extends GoogleAuthOptions { + apiEndpoint: string; projectId?: string; logLevel: number; serviceContext: {service: string; version?: string}; @@ -163,7 +166,6 @@ export interface ProfilerConfig extends GoogleAuthOptions { backoffCapMillis: number; backoffMultiplier: number; serverBackoffCapMillis: number; - baseApiUrl: string; localProfilingPeriodMillis: number; localLogPeriodMillis: number; localTimeDurationMillis: number; @@ -184,7 +186,7 @@ export const defaultConfig = { initialBackoffMillis: 60 * 1000, // 1 minute backoffCapMillis: parseDuration('1h'), backoffMultiplier: 1.3, - baseApiUrl: 'https://cloudprofiler.googleapis.com/v2', + apiEndpoint: 'cloudprofiler.googleapis.com', // This is the largest duration for setTimeout which does not cause it to // run immediately. diff --git a/ts/src/index.ts b/ts/src/index.ts index c72a2a6d..7bcd0b50 100644 --- a/ts/src/index.ts +++ b/ts/src/index.ts @@ -154,17 +154,17 @@ export function nodeVersionOkay(version: string | SemVer): boolean { * needed. Returns a profiler if creation is successful. Otherwise, returns * rejected promise. */ -export async function createProfiler(config: Config): Promise { +export async function createProfiler(config: Config = {}): Promise { if (!nodeVersionOkay(process.version)) { throw new Error( `Could not start profiler: node version ${process.version}` + ` does not satisfies "${pjson.engines.node}"` + - '\nSee https://github.com/GoogleCloudPlatform/cloud-profiler-nodejs#prerequisites' + + '\nSee https://github.com/googleapis/cloud-profiler-nodejs#prerequisites' + ' for details.' ); } - let profilerConfig: ProfilerConfig = initConfigLocal(config); + let profilerConfig = initConfigLocal(config); // Start the heap profiler if profiler config does not indicate heap profiling // is disabled. This must be done before any asynchronous calls are made so diff --git a/ts/src/profiler.ts b/ts/src/profiler.ts index eedfee50..a9ce9d39 100644 --- a/ts/src/profiler.ts +++ b/ts/src/profiler.ts @@ -280,14 +280,17 @@ export class Profiler extends ServiceObject { private profileTypes: string[]; private retryer: Retryer; private sourceMapper: SourceMapper | undefined; + private baseApiUrl: string; // Public for testing. config: ProfilerConfig; constructor(config: ProfilerConfig) { config = config || ({} as ProfilerConfig); + const baseApiUrl = `https://${config.apiEndpoint}/v2`; const serviceConfig: ServiceConfig = { - baseUrl: config.baseApiUrl, + apiEndpoint: config.apiEndpoint, + baseUrl: baseApiUrl, scopes: [SCOPE], packageJson: pjson, }; @@ -296,6 +299,7 @@ export class Profiler extends ServiceObject { baseUrl: '/', }); this.config = config; + this.baseApiUrl = baseApiUrl; this.logger = createLogger(this.config.logLevel); @@ -471,7 +475,7 @@ export class Profiler extends ServiceObject { } const options = { method: 'PATCH', - uri: this.config.baseApiUrl + '/' + prof.name, + uri: this.baseApiUrl + '/' + prof.name, body: prof, json: true, }; diff --git a/ts/test/test-init-config.ts b/ts/test/test-init-config.ts index fbe33770..ed2a943c 100644 --- a/ts/test/test-init-config.ts +++ b/ts/test/test-init-config.ts @@ -79,9 +79,9 @@ describe('createProfiler', () => { localProfilingPeriodMillis: 1000, localTimeDurationMillis: 1000, localLogPeriodMillis: 10000, - baseApiUrl: 'https://cloudprofiler.googleapis.com/v2', + apiEndpoint: 'cloudprofiler.googleapis.com', }; - const sourceMapSearchPath: string[] = []; + const disableSourceMapParams = { sourceMapSearchPath: ['path'], disableSourceMaps: true, @@ -342,14 +342,14 @@ describe('createProfiler', () => { } }); - it('should set baseApiUrl to non-default value', async () => { + it('should set apiEndpoint to non-default value', async () => { metadataStub = sinon.stub(gcpMetadata, 'instance'); metadataStub.throwsException('cannot access metadata'); const config = Object.assign( { + apiEndpoint: 'test-cloudprofiler.sandbox.googleapis.com', serviceContext: {version: '', service: 'fake-service'}, - baseApiUrl: 'https://test-cloudprofiler.sandbox.googleapis.com/v2', }, disableSourceMapParams ); @@ -358,7 +358,7 @@ describe('createProfiler', () => { disableHeap: false, disableTime: false, logLevel: 2, - baseApiUrl: 'https://test-cloudprofiler.sandbox.googleapis.com/v2', + apiEndpoint: 'test-cloudprofiler.sandbox.googleapis.com', }; const expConfig = Object.assign( {}, diff --git a/ts/test/test-profiler.ts b/ts/test/test-profiler.ts index 159d29d3..8a290caf 100644 --- a/ts/test/test-profiler.ts +++ b/ts/test/test-profiler.ts @@ -42,8 +42,11 @@ const parseDuration: (str: string) => number = require('parse-duration'); const fakeCredentials = require('../../ts/test/fixtures/gcloud-credentials.json'); -const API = 'https://cloudprofiler.googleapis.com/v2'; -const TEST_API = 'https://test-cloudprofiler.sandbox.googleapis.com/v2'; +const API = 'cloudprofiler.googleapis.com'; +const TEST_API = 'test-cloudprofiler.sandbox.googleapis.com'; + +const FULL_API = `https://${API}/v2`; +const FULL_TEST_API = `https://${TEST_API}/v2`; const testConfig: ProfilerConfig = { projectId: 'test-projectId', @@ -62,12 +65,12 @@ const testConfig: ProfilerConfig = { backoffCapMillis: parseDuration('1h'), backoffMultiplier: 1.3, serverBackoffCapMillis: parseDuration('7d'), - baseApiUrl: API, localProfilingPeriodMillis: 1000, localTimeDurationMillis: 1000, localLogPeriodMillis: 1000, sourceMapSearchPath: [], disableSourceMaps: true, + apiEndpoint: API, }; nock.disableNetConnect(); @@ -391,7 +394,7 @@ describe('Profiler', () => { labels: {instance: 'test-instance'}, }; nockOauth2(); - const apiMock = nock(API) + const apiMock = nock(FULL_API) .patch('/' + requestProf.name) .once() .reply(200); @@ -407,12 +410,12 @@ describe('Profiler', () => { labels: {instance: 'test-instance'}, }; nockOauth2(); - const apiMock = nock(TEST_API) + const apiMock = nock(FULL_TEST_API) .patch('/' + requestProf.name) .once() .reply(200); const config = extend(true, {}, testConfig); - config.baseApiUrl = TEST_API; + config.apiEndpoint = TEST_API; const profiler = new Profiler(config); await profiler.profileAndUpload(requestProf); assert.strictEqual(apiMock.isDone(), true, 'completed call to test API'); @@ -442,7 +445,7 @@ describe('Profiler', () => { labels: {version: config.serviceContext.version}, }; nockOauth2(); - const requestProfileMock = nock(API) + const requestProfileMock = nock(FULL_API) .post('/projects/' + testConfig.projectId + '/profiles') .once() .reply(200, response); @@ -454,7 +457,7 @@ describe('Profiler', () => { it('should successfully create profile using non-default api', async () => { const config = extend(true, {}, testConfig); config.disableHeap = true; - config.baseApiUrl = TEST_API; + config.apiEndpoint = TEST_API; const response = { name: 'projects/12345678901/test-projectId', profileType: 'WALL', @@ -467,7 +470,7 @@ describe('Profiler', () => { labels: {version: config.serviceContext.version}, }; nockOauth2(); - const requestProfileMock = nock(TEST_API) + const requestProfileMock = nock(FULL_TEST_API) .post('/projects/' + config.projectId + '/profiles') .once() .reply(200, response); @@ -490,7 +493,7 @@ describe('Profiler', () => { labels: {version: config.serviceContext.version}, }; nockOauth2(); - const requestProfileMock = nock(API) + const requestProfileMock = nock(FULL_API) .post('/projects/' + testConfig.projectId + '/profiles') .once() .reply(200, response); @@ -504,7 +507,7 @@ describe('Profiler', () => { config.disableHeap = true; const response = {name: 'projects/12345678901/test-projectId'}; nockOauth2(); - const requestProfileMock = nock(API) + const requestProfileMock = nock(FULL_API) .post('/projects/' + testConfig.projectId + '/profiles') .once() .reply(200, response); @@ -597,7 +600,7 @@ describe('Profiler', () => { additionalField: 'additionalField', }; nockOauth2(); - const requestProfileMock = nock(API) + const requestProfileMock = nock(FULL_API) .post('/projects/' + testConfig.projectId + '/profiles') .once() .reply(200, response);