Compare commits

..

1 Commits

Author SHA1 Message Date
artrejo
4664038df0 Add onChange event to throughput text field 2020-12-22 16:59:50 -08:00
4 changed files with 181 additions and 175 deletions

View File

@@ -267,6 +267,10 @@ export class ThroughputInputViewModel extends WaitsForTemplateViewModel {
return true;
};
public onThroughputChange = (source: any) => {
window.alert("onThroughputChange");
};
private _getSanitizedValue(): number {
let throughput = this.value();

View File

@@ -150,6 +150,9 @@
'aria-label': ariaLabel,
disabled: overrideWithAutoPilotSettings(),
required: isManualThroughputInputFieldRequired()
},
event:{
change: onThroughputChange
}"
/>
</div>

View File

@@ -265,11 +265,9 @@ export class CassandraAPIDataClient extends TableDataClient {
authType === AuthType.EncryptedToken
? Constants.CassandraBackend.guestQueryApi
: Constants.CassandraBackend.queryApi;
const authorizationHeader = getAuthorizationHeader();
const response = await fetch(`${configContext.BACKEND_ENDPOINT}/${apiEndpoint}`, {
method: "POST",
body: JSON.stringify({
const data: any = await $.ajax(`${configContext.BACKEND_ENDPOINT}/${apiEndpoint}`, {
type: "POST",
data: {
accountName:
collection && collection.container.databaseAccount && collection.container.databaseAccount().name,
cassandraEndpoint: this.trimCassandraEndpoint(
@@ -280,19 +278,11 @@ export class CassandraAPIDataClient extends TableDataClient {
tableId: collection.id(),
query,
paginationToken
}),
headers: {
[authorizationHeader.header]: authorizationHeader.token,
[Constants.HttpHeaders.contentType]: "application/json"
}
},
beforeSend: this.setAuthorizationHeader,
error: this.handleAjaxError,
cache: false
});
if (!response.ok) {
displayTokenRenewalPromptForStatus(response.status);
throw Error(`Failed to query rows for table ${collection.id()}`);
}
const data = await response.json();
shouldNotify &&
NotificationConsoleUtils.logConsoleInfo(
`Successfully fetched ${data.result.length} rows for table ${collection.id()}`
@@ -460,9 +450,9 @@ export class CassandraAPIDataClient extends TableDataClient {
return deferred.promise;
}
public async getTableKeys(collection: ViewModels.Collection): Promise<CassandraTableKeys> {
public getTableKeys(collection: ViewModels.Collection): Q.Promise<CassandraTableKeys> {
if (!!collection.cassandraKeys) {
return collection.cassandraKeys;
return Q.resolve(collection.cassandraKeys);
}
const notificationId = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
@@ -474,51 +464,45 @@ export class CassandraAPIDataClient extends TableDataClient {
? Constants.CassandraBackend.guestKeysApi
: Constants.CassandraBackend.keysApi;
let endpoint = `${configContext.BACKEND_ENDPOINT}/${apiEndpoint}`;
const authorizationHeader = getAuthorizationHeader();
try {
const response = await fetch(endpoint, {
method: "POST",
body: JSON.stringify({
accountName:
collection && collection.container.databaseAccount && collection.container.databaseAccount().name,
cassandraEndpoint: this.trimCassandraEndpoint(
collection.container.databaseAccount().properties.cassandraEndpoint
),
resourceId: collection.container.databaseAccount().id,
keyspaceId: collection.databaseId,
tableId: collection.id()
}),
headers: {
[authorizationHeader.header]: authorizationHeader.token,
[Constants.HttpHeaders.contentType]: "application/json"
const deferred = Q.defer<CassandraTableKeys>();
$.ajax(endpoint, {
type: "POST",
data: {
accountName: collection && collection.container.databaseAccount && collection.container.databaseAccount().name,
cassandraEndpoint: this.trimCassandraEndpoint(
collection.container.databaseAccount().properties.cassandraEndpoint
),
resourceId: collection.container.databaseAccount().id,
keyspaceId: collection.databaseId,
tableId: collection.id()
},
beforeSend: this.setAuthorizationHeader,
error: this.handleAjaxError,
cache: false
})
.then(
(data: CassandraTableKeys) => {
collection.cassandraKeys = data;
NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Info,
`Successfully fetched keys for table ${collection.id()}`
);
deferred.resolve(data);
},
(error: any) => {
handleError(error, "FetchKeysCassandra", `Error fetching keys for table ${collection.id()}`);
deferred.reject(error);
}
)
.done(() => {
NotificationConsoleUtils.clearInProgressMessageWithId(notificationId);
});
if (!response.ok) {
displayTokenRenewalPromptForStatus(response.status);
throw Error(`Fetching keys for table ${collection.id()} failed`);
}
const data: CassandraTableKeys = await response.json();
collection.cassandraKeys = data;
NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Info,
`Successfully fetched keys for table ${collection.id()}`
);
return data;
} catch (error) {
handleError(error, "FetchKeysCassandra", `Error fetching keys for table ${collection.id()}`);
throw error;
} finally {
NotificationConsoleUtils.clearInProgressMessageWithId(notificationId);
}
return deferred.promise;
}
public async getTableSchema(collection: ViewModels.Collection): Promise<CassandraTableKey[]> {
public getTableSchema(collection: ViewModels.Collection): Q.Promise<CassandraTableKey[]> {
if (!!collection.cassandraSchema) {
return collection.cassandraSchema;
return Q.resolve(collection.cassandraSchema);
}
const notificationId = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
@@ -530,79 +514,74 @@ export class CassandraAPIDataClient extends TableDataClient {
? Constants.CassandraBackend.guestSchemaApi
: Constants.CassandraBackend.schemaApi;
let endpoint = `${configContext.BACKEND_ENDPOINT}/${apiEndpoint}`;
const authorizationHeader = getAuthorizationHeader();
try {
const response = await fetch(endpoint, {
method: "POST",
body: JSON.stringify({
accountName:
collection && collection.container.databaseAccount && collection.container.databaseAccount().name,
cassandraEndpoint: this.trimCassandraEndpoint(
collection.container.databaseAccount().properties.cassandraEndpoint
),
resourceId: collection.container.databaseAccount().id,
keyspaceId: collection.databaseId,
tableId: collection.id()
}),
headers: {
[authorizationHeader.header]: authorizationHeader.token,
[Constants.HttpHeaders.contentType]: "application/json"
const deferred = Q.defer<CassandraTableKey[]>();
$.ajax(endpoint, {
type: "POST",
data: {
accountName: collection && collection.container.databaseAccount && collection.container.databaseAccount().name,
cassandraEndpoint: this.trimCassandraEndpoint(
collection.container.databaseAccount().properties.cassandraEndpoint
),
resourceId: collection.container.databaseAccount().id,
keyspaceId: collection.databaseId,
tableId: collection.id()
},
beforeSend: this.setAuthorizationHeader,
error: this.handleAjaxError,
cache: false
})
.then(
(data: any) => {
collection.cassandraSchema = data.columns;
NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Info,
`Successfully fetched schema for table ${collection.id()}`
);
deferred.resolve(data.columns);
},
(error: any) => {
handleError(error, "FetchSchemaCassandra", `Error fetching schema for table ${collection.id()}`);
deferred.reject(error);
}
)
.done(() => {
NotificationConsoleUtils.clearInProgressMessageWithId(notificationId);
});
if (!response.ok) {
displayTokenRenewalPromptForStatus(response.status);
throw Error(`Failed to fetch schema for table ${collection.id()}`);
}
const data = await response.json();
collection.cassandraSchema = data.columns;
NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Info,
`Successfully fetched schema for table ${collection.id()}`
);
return data.columns;
} catch (error) {
handleError(error, "FetchSchemaCassandra", `Error fetching schema for table ${collection.id()}`);
throw error;
} finally {
NotificationConsoleUtils.clearInProgressMessageWithId(notificationId);
}
return deferred.promise;
}
private async createOrDeleteQuery(
private createOrDeleteQuery(
cassandraEndpoint: string,
resourceId: string,
query: string,
explorer: Explorer
): Promise<void> {
): Q.Promise<any> {
const deferred = Q.defer();
const authType = window.authType;
const apiEndpoint: string =
authType === AuthType.EncryptedToken
? Constants.CassandraBackend.guestCreateOrDeleteApi
: Constants.CassandraBackend.createOrDeleteApi;
const authorizationHeader = getAuthorizationHeader();
const response = await fetch(`${configContext.BACKEND_ENDPOINT}/${apiEndpoint}`, {
method: "POST",
body: JSON.stringify({
$.ajax(`${configContext.BACKEND_ENDPOINT}/${apiEndpoint}`, {
type: "POST",
data: {
accountName: explorer.databaseAccount() && explorer.databaseAccount().name,
cassandraEndpoint: this.trimCassandraEndpoint(cassandraEndpoint),
resourceId,
query
}),
headers: {
[authorizationHeader.header]: authorizationHeader.token,
[Constants.HttpHeaders.contentType]: "application/json"
resourceId: resourceId,
query: query
},
beforeSend: this.setAuthorizationHeader,
error: this.handleAjaxError,
cache: false
}).then(
(data: any) => {
deferred.resolve();
},
reason => {
deferred.reject(reason);
}
});
if (!response.ok) {
displayTokenRenewalPromptForStatus(response.status);
throw Error(`Failed to create or delete keyspace/table`);
}
);
return deferred.promise;
}
private trimCassandraEndpoint(cassandraEndpoint: string): string {
@@ -621,6 +600,13 @@ export class CassandraAPIDataClient extends TableDataClient {
return cassandraEndpoint;
}
private setAuthorizationHeader: (xhr: XMLHttpRequest) => boolean = (xhr: XMLHttpRequest): boolean => {
const authorizationHeaderMetadata: ViewModels.AuthorizationTokenHeaderMetadata = getAuthorizationHeader();
xhr.setRequestHeader(authorizationHeaderMetadata.header, authorizationHeaderMetadata.token);
return true;
};
private isStringType(dataType: string): boolean {
// TODO figure out rest of types that are considered strings by Cassandra (if any have been missed)
return (
@@ -634,4 +620,12 @@ export class CassandraAPIDataClient extends TableDataClient {
private getCassandraPartitionKeyProperty(collection: ViewModels.Collection): string {
return collection.cassandraKeys.partitionKeys[0].property;
}
private handleAjaxError = (xhrObj: XMLHttpRequest, textStatus: string, errorThrown: string): void => {
if (!xhrObj) {
return;
}
displayTokenRenewalPromptForStatus(xhrObj.status);
};
}

View File

@@ -10,7 +10,6 @@ import { DefaultExperienceUtility } from "../../Shared/DefaultExperienceUtility"
import * as Logger from "../../Common/Logger";
import { configContext } from "../../ConfigContext";
import { userContext } from "../../UserContext";
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
export default class AuthHeadersUtil {
public static serverId: string = Constants.ServerIds.productionPortal;
@@ -38,7 +37,8 @@ export default class AuthHeadersUtil {
cacheLocation: window.navigator.userAgent.indexOf("Edge") > -1 ? "localStorage" : undefined
});
public static async getAccessInputMetadata(accessInput: string): Promise<DataModels.AccessInputMetadata> {
public static getAccessInputMetadata(accessInput: string): Q.Promise<DataModels.AccessInputMetadata> {
const deferred: Q.Deferred<DataModels.AccessInputMetadata> = Q.defer<DataModels.AccessInputMetadata>();
const url = `${configContext.BACKEND_ENDPOINT}${Constants.ApiEndpoints.guestRuntimeProxy}/accessinputmetadata`;
const authType: string = (<any>window).authType;
const headers: { [headerName: string]: string } = {};
@@ -49,55 +49,58 @@ export default class AuthHeadersUtil {
headers[Constants.HttpHeaders.connectionString] = accessInput;
}
let responseText: string;
try {
const timeout = setTimeout(() => {
throw Error("Request timed out while fetching access input metadata");
}, Constants.ClientDefaults.requestTimeoutMs);
$.ajax({
url: url,
type: "GET",
headers: headers,
cache: false,
dataType: "text"
}).then(
(data: string, textStatus: string, xhr: JQueryXHR<any>) => {
if (!data) {
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, `Failed to get access input metadata`);
deferred.reject(`Failed to get access input metadata`);
}
const response = await fetch(url, {
headers,
method: "GET"
});
clearTimeout(timeout);
responseText = await response.text();
if (!response.ok || !responseText) {
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, `Failed to get access input metadata`);
throw Error("Failed to get access input metadata");
try {
const metadata: DataModels.AccessInputMetadata = JSON.parse(JSON.parse(data));
deferred.resolve(metadata); // TODO: update to a single JSON parse once backend response is stringified exactly once
} catch (error) {
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, "Failed to parse access input metadata");
deferred.reject("Failed to parse access input metadata");
throw error;
}
},
(xhr: JQueryXHR<any>, textStatus: string, error: any) => {
NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Error,
`Error while fetching access input metadata: ${JSON.stringify(xhr.responseText)}`
);
deferred.reject(xhr.responseText);
}
} catch (error) {
const errorMessage: string = getErrorMessage(error);
NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Error,
`Error while fetching access input metadata: ${errorMessage}`
);
throw error;
}
);
try {
const metadata: DataModels.AccessInputMetadata = JSON.parse(JSON.parse(responseText));
return metadata; // TODO: update to a single JSON parse once backend response is stringified exactly once
} catch (error) {
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, "Failed to parse access input metadata");
throw error;
}
return deferred.promise.timeout(Constants.ClientDefaults.requestTimeoutMs);
}
public static async generateEncryptedToken(): Promise<DataModels.GenerateTokenResponse> {
public static generateEncryptedToken(): Q.Promise<DataModels.GenerateTokenResponse> {
const url = configContext.BACKEND_ENDPOINT + "/api/tokens/generateToken" + AuthHeadersUtil._generateResourceUrl();
const explorer = window.dataExplorer;
const headers: any = { authorization: userContext.authorizationToken };
headers[Constants.HttpHeaders.getReadOnlyKey] = !explorer.hasWriteAccess();
headers[Constants.HttpHeaders.contentType] = "application/json";
return await AuthHeadersUtil._initiateGenerateTokenRequest(url, "POST", headers);
return AuthHeadersUtil._initiateGenerateTokenRequest({
url: url,
type: "POST",
headers: headers,
contentType: "application/json",
cache: false
});
}
public static async generateUnauthenticatedEncryptedTokenForConnectionString(
public static generateUnauthenticatedEncryptedTokenForConnectionString(
connectionString: string
): Promise<DataModels.GenerateTokenResponse> {
): Q.Promise<DataModels.GenerateTokenResponse> {
if (!connectionString) {
return Q.reject("None or empty connection string specified");
}
@@ -105,9 +108,14 @@ export default class AuthHeadersUtil {
const url = configContext.BACKEND_ENDPOINT + "/api/guest/tokens/generateToken";
const headers: any = {};
headers[Constants.HttpHeaders.connectionString] = connectionString;
headers[Constants.HttpHeaders.contentType] = "application/json";
return await AuthHeadersUtil._initiateGenerateTokenRequest(url, "POST", headers);
return AuthHeadersUtil._initiateGenerateTokenRequest({
url: url,
type: "POST",
headers: headers,
contentType: "application/json",
cache: false
});
}
public static isUserSignedIn(): boolean {
@@ -274,27 +282,24 @@ export default class AuthHeadersUtil {
return `?resourceUrl=${resourceUrl}&rid=${rid}&rtype=${rtype}&sid=${sid}&rg=${rg}&dba=${dba}&api=${apiKind}`;
}
private static async _initiateGenerateTokenRequest(
url: string,
method: string,
headers: any
): Promise<DataModels.GenerateTokenResponse> {
const timeout = setTimeout(() => {
throw Error("Request timed out while generating token");
}, Constants.ClientDefaults.requestTimeoutMs);
private static _initiateGenerateTokenRequest(
requestSettings: JQueryAjaxSettings<any>
): Q.Promise<DataModels.GenerateTokenResponse> {
const deferred: Q.Deferred<DataModels.GenerateTokenResponse> = Q.defer<DataModels.GenerateTokenResponse>();
const response = await fetch(url, {
headers,
method
});
$.ajax(requestSettings).then(
(data: string, textStatus: string, xhr: JQueryXHR<any>) => {
if (!data) {
deferred.reject("No token generated");
}
clearTimeout(timeout);
deferred.resolve(JSON.parse(data));
},
(xhr: JQueryXHR<any>, textStatus: string, error: any) => {
deferred.reject(xhr.responseText);
}
);
const token: string = await response.json();
if (response.ok && token) {
return JSON.parse(token);
}
throw Error("No token generated");
return deferred.promise.timeout(Constants.ClientDefaults.requestTimeoutMs);
}
}