Skip to content

Commit

Permalink
finish initial refactor of classes
Browse files Browse the repository at this point in the history
  • Loading branch information
ddelgrosso1 committed Jul 9, 2024
1 parent 2a9c6fc commit 4770b05
Show file tree
Hide file tree
Showing 11 changed files with 409 additions and 470 deletions.
5 changes: 2 additions & 3 deletions conformance-test/conformanceCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import * as libraryMethods from './libraryMethods';
import {Bucket, File, HmacKey, Notification, Storage} from '../src/';
import * as uuid from 'uuid';
import * as assert from 'assert';
import {DecorateRequestOptions} from '../src/nodejs-common';
import fetch from 'node-fetch';

interface RetryCase {
Expand Down Expand Up @@ -127,12 +126,12 @@ export function executeScenario(testCase: RetryTestCase) {
);

storage.interceptors.push({
request: requestConfig => {
resolved: requestConfig => {
requestConfig.headers = requestConfig.headers || {};
Object.assign(requestConfig.headers, {
'x-retry-test-id': creationResult.id,
});
return requestConfig as DecorateRequestOptions;
return Promise.resolve(requestConfig);
},
});
});
Expand Down
15 changes: 11 additions & 4 deletions conformance-test/libraryMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {Bucket, File, Notification, Storage, HmacKey, Policy} from '../src';
import {
Bucket,
File,
Notification,
Storage,
HmacKey,
Policy,
GaxiosError,
} from '../src';
import * as path from 'path';
import {ApiError} from '../src/nodejs-common';
import {
createTestBuffer,
createTestFileFromBuffer,
Expand Down Expand Up @@ -227,7 +234,7 @@ export async function getFilesStream(options: ConformanceTestOptions) {
.bucket!.getFilesStream()
.on('data', () => {})
.on('end', () => resolve(undefined))
.on('error', (err: ApiError) => reject(err));
.on('error', (err: GaxiosError) => reject(err));
});
}

Expand Down Expand Up @@ -496,7 +503,7 @@ export async function createReadStream(options: ConformanceTestOptions) {
.file!.createReadStream()
.on('data', () => {})
.on('end', () => resolve(undefined))
.on('error', (err: ApiError) => reject(err));
.on('error', (err: GaxiosError) => reject(err));
});
}

Expand Down
7 changes: 5 additions & 2 deletions src/acl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,10 @@ interface AclQuery {
export interface AccessControlObject {
entity: string;
role: string;
projectTeam: string;
projectTeam?: {
projectNumber?: string;
team?: 'editors' | 'owners' | 'viewers' | string;
};
}

export interface AclMetadata extends BaseMetadata {
Expand All @@ -103,7 +106,7 @@ export interface AclMetadata extends BaseMetadata {
object?: string;
projectTeam?: {
projectNumber?: string;
team?: 'editors' | 'owners' | 'viewers';
team?: 'editors' | 'owners' | 'viewers' | string;
};
role?: 'OWNER' | 'READER' | 'WRITER' | 'FULL_CONTROL';
[key: string]: unknown;
Expand Down
76 changes: 30 additions & 46 deletions src/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1505,8 +1505,6 @@ class File extends ServiceObject<File, FileMetadata> {
const tailRequest = options.end! < 0;

let validateStream: HashStreamValidator | undefined = undefined;
let request: r.Request | undefined = undefined;

const throughStream = new PassThroughShim();

let crc32c = true;
Expand Down Expand Up @@ -1539,9 +1537,9 @@ class File extends ServiceObject<File, FileMetadata> {
if (err) {
// There is an issue with node-fetch 2.x that if the stream errors the underlying socket connection is not closed.
// This causes a memory leak, so cleanup the sockets manually here by destroying the agent.
if (request?.agent) {
request.agent.destroy();
}
//if (request?.agent) {
// request.agent.destroy();
//}
throughStream.destroy(err);
}
};
Expand Down Expand Up @@ -1570,7 +1568,6 @@ class File extends ServiceObject<File, FileMetadata> {
return;
}

request = (rawResponseStream as r.Response).request;
const headers = (rawResponseStream as ResponseBody).toJSON().headers;
const isCompressed = headers['content-encoding'] === 'gzip';
const hashes: {crc32c?: string; md5?: string} = {};
Expand Down Expand Up @@ -1682,7 +1679,7 @@ class File extends ServiceObject<File, FileMetadata> {
})
.on('response', res => {
throughStream.emit('response', res);
util.handleResp(null, res, null, onResponse);
onResponse(res.err, res.body, res.resp);
})
.resume();
};
Expand Down Expand Up @@ -1811,11 +1808,6 @@ class File extends ServiceObject<File, FileMetadata> {
authClient: this.storage.storageTransport.authClient,
apiEndpoint: this.storage.apiEndpoint,
bucket: this.bucket.name,
//TODO: Fill in with gaxios interceptors
/* customRequestOptions: this.getRequestInterceptors().reduce(
(reqOpts, interceptorFn) => interceptorFn(reqOpts),
{}
), */
file: this.name,
generation: this.generation,
key: this.encryptionKey,
Expand Down Expand Up @@ -2398,13 +2390,13 @@ class File extends ServiceObject<File, FileMetadata> {
.digest('base64');

this.encryptionKeyInterceptor = {
request: reqOpts => {
resolved: reqOpts => {
reqOpts.headers = reqOpts.headers || {};
reqOpts.headers['x-goog-encryption-algorithm'] = 'AES256';
reqOpts.headers['x-goog-encryption-key'] = this.encryptionKeyBase64;
reqOpts.headers['x-goog-encryption-key-sha256'] =
this.encryptionKeyHash;
return reqOpts as DecorateRequestOptions;
return Promise.resolve(reqOpts);
},
};

Expand Down Expand Up @@ -2499,7 +2491,11 @@ class File extends ServiceObject<File, FileMetadata> {
callback?: GetExpirationDateCallback
): void | Promise<GetExpirationDateResponse> {
this.getMetadata(
(err: ApiError | null, metadata: FileMetadata, apiResponse: unknown) => {
(
err: GaxiosError | null,
metadata: FileMetadata,
apiResponse: unknown
) => {
if (err) {
callback!(err, null, apiResponse);
return;
Expand Down Expand Up @@ -3223,29 +3219,24 @@ class File extends ServiceObject<File, FileMetadata> {
const storageInterceptors = this.storage?.interceptors || [];
const fileInterceptors = this.interceptors || [];
const allInterceptors = storageInterceptors.concat(fileInterceptors);
const headers = allInterceptors.reduce((acc, curInterceptor) => {
const currentHeaders = curInterceptor.request({
uri: `${this.storage.apiEndpoint}/${
this.bucket.name
}/${encodeURIComponent(this.name)}`,
});

Object.assign(acc, currentHeaders.headers);
return acc;
}, {});
for (const curInter of allInterceptors) {
gaxios.instance.interceptors.request.add(curInter);
}

gaxios
.request({
method: 'GET',
url: `${this.storage.apiEndpoint}/${
this.bucket.name
}/${encodeURIComponent(this.name)}`,
headers,
retryConfig: {
retry: this.storage.retryOptions.maxRetries,
noResponseRetries: this.storage.retryOptions.maxRetries,
maxRetryDelay: this.storage.retryOptions.maxRetryDelay,
retryDelayMultiplier: this.storage.retryOptions.retryDelayMultiplier,
shouldRetry: this.storage.retryOptions.retryableErrorFn,
//TODO: Finish rest of retry options
totalTimeout: this.storage.retryOptions.totalTimeout,
},
})
.then(() => callback!(null, true))
Expand Down Expand Up @@ -4141,10 +4132,6 @@ class File extends ServiceObject<File, FileMetadata> {
authClient: this.storage.storageTransport.authClient,
apiEndpoint: this.storage.apiEndpoint,
bucket: this.bucket.name,
customRequestOptions: this.getRequestInterceptors().reduce(
(reqOpts, interceptorFn) => interceptorFn(reqOpts),
{}
),
file: this.name,
generation: this.generation,
isPartialUpload: options.isPartialUpload,
Expand Down Expand Up @@ -4254,23 +4241,20 @@ class File extends ServiceObject<File, FileMetadata> {
options.preconditionOpts
);

util.makeWritableStream(dup, {
makeAuthenticatedRequest: (reqOpts: object) => {
this.request(reqOpts as DecorateRequestOptions, (err, body, resp) => {
if (err) {
dup.destroy(err);
return;
}
this.storageTransport.makeRequest(
reqOpts as StorageRequestOptions,
(err, body, resp) => {
if (err) {
dup.destroy(err);
return;
}

this.metadata = body;
dup.emit('metadata', body);
dup.emit('response', resp);
dup.emit('complete');
});
},
metadata: options.metadata,
request: reqOpts,
});
this.metadata = body as FileMetadata;
dup.emit('metadata', body);
dup.emit('response', resp);
dup.emit('complete');
}
);
}

disableAutoRetryConditionallyIdempotent_(
Expand Down
57 changes: 31 additions & 26 deletions src/iam.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -12,14 +13,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {
BodyResponseCallback,
DecorateRequestOptions,
} from './nodejs-common/index.js';
import {promisifyAll} from '@google-cloud/promisify';

import {Bucket} from './bucket.js';
import {normalize} from './util.js';
import {StorageQueryParameters, StorageTransport} from './storage-transport.js';

export interface GetPolicyOptions {
userProject?: string;
Expand Down Expand Up @@ -141,15 +138,12 @@ export enum IAMExceptionMessages {
* ```
*/
class Iam {
private request_: (
reqOpts: DecorateRequestOptions,
callback: BodyResponseCallback
) => void;
private resourceId_: string;
private storageTransport: StorageTransport;

constructor(bucket: Bucket) {
this.request_ = bucket.request.bind(bucket);
this.resourceId_ = 'buckets/' + bucket.getId();
this.storageTransport = bucket.storageTransport;
}

getPolicy(options?: GetPolicyOptions): Promise<GetPolicyResponse>;
Expand Down Expand Up @@ -261,12 +255,18 @@ class Iam {
qs.optionsRequestedPolicyVersion = options.requestedPolicyVersion;
}

this.request_(
this.storageTransport.makeRequest(
{
uri: '/iam',
qs,
url: '/iam',
queryParameters: qs as unknown as StorageQueryParameters,
},
cb!
(err, data, resp) => {
if (err) {
cb(err);
return;
}
callback!(null, data as Policy, resp);
}
);
}

Expand Down Expand Up @@ -347,20 +347,26 @@ class Iam {
maxRetries = 0;
}

this.request_(
this.storageTransport.makeRequest(
{
method: 'PUT',
uri: '/iam',
url: '/iam',
maxRetries,
json: Object.assign(
body: Object.assign(
{
resourceId: this.resourceId_,
},
policy
),
qs: options,
queryParameters: options as unknown as StorageQueryParameters,
},
cb
(err, data, resp) => {
if (err) {
cb!(err);
return;
}
cb!(null, data as Policy, resp);
}
);
}

Expand Down Expand Up @@ -457,20 +463,19 @@ class Iam {
options
);

this.request_(
this.storageTransport.makeRequest(
{
uri: '/iam/testPermissions',
qs: req,
useQuerystring: true,
url: '/iam/testPermissions',
queryParameters: req as unknown as StorageQueryParameters,
},
(err, resp) => {
(err, data, resp) => {
if (err) {
cb!(err, null, resp);
return;
}

const availablePermissions = Array.isArray(resp.permissions)
? resp.permissions
const availablePermissions = Array.isArray((data as any).permissions)
? (data as any).permissions
: [];

const permissionsHash = permissionsArray.reduce(
Expand Down
12 changes: 8 additions & 4 deletions src/nodejs-common/service-object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ import {EventEmitter} from 'events';
import {util} from './util.js';
import {Bucket} from '../bucket.js';
import {StorageRequestOptions, StorageTransport} from '../storage-transport.js';
import {GaxiosError, GaxiosResponse} from 'gaxios';
import {
GaxiosError,
GaxiosInterceptor,
GaxiosOptions,
GaxiosResponse,
} from 'gaxios';

export type GetMetadataOptions = object;

Expand Down Expand Up @@ -155,8 +160,7 @@ class ServiceObject<T, K extends BaseMetadata> extends EventEmitter {
name?: string;
private createMethod?: Function;
protected methods: Methods;
//TODO: Fill in with GaxiosInterceptors
//interceptors: Interceptor[];
interceptors: GaxiosInterceptor<GaxiosOptions>[];
projectId?: string;

/*
Expand Down Expand Up @@ -185,7 +189,7 @@ class ServiceObject<T, K extends BaseMetadata> extends EventEmitter {
this.id = config.id; // Name or ID (e.g. dataset ID, bucket name, etc).
this.createMethod = config.createMethod;
this.methods = config.methods || {};
//this.interceptors = [];
this.interceptors = [];
this.projectId = config.projectId;
this.storageTransport = config.storageTransport;

Expand Down
Loading

0 comments on commit 4770b05

Please sign in to comment.