Fix update offer beyond throughput limit error (#135)
This commit is contained in:
parent
08ee86ecf1
commit
455a6ac81b
|
@ -26,7 +26,6 @@ import { OfferUtils } from "../Utils/OfferUtils";
|
||||||
import { RequestOptions } from "@azure/cosmos/dist-esm";
|
import { RequestOptions } from "@azure/cosmos/dist-esm";
|
||||||
import StoredProcedure from "../Explorer/Tree/StoredProcedure";
|
import StoredProcedure from "../Explorer/Tree/StoredProcedure";
|
||||||
import { Platform, configContext } from "../ConfigContext";
|
import { Platform, configContext } from "../ConfigContext";
|
||||||
import { getAuthorizationHeader } from "../Utils/AuthorizationUtils";
|
|
||||||
import DocumentId from "../Explorer/Tree/DocumentId";
|
import DocumentId from "../Explorer/Tree/DocumentId";
|
||||||
import ConflictId from "../Explorer/Tree/ConflictId";
|
import ConflictId from "../Explorer/Tree/ConflictId";
|
||||||
|
|
||||||
|
@ -640,29 +639,6 @@ export function queryConflicts(
|
||||||
return Q(documentsIterator);
|
return Q(documentsIterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateOfferThroughputBeyondLimit(
|
|
||||||
request: DataModels.UpdateOfferThroughputRequest
|
|
||||||
): Promise<void> {
|
|
||||||
if (configContext.platform !== Platform.Portal) {
|
|
||||||
throw new Error("Updating throughput beyond specified limit is not supported on this platform");
|
|
||||||
}
|
|
||||||
|
|
||||||
const explorer = window.dataExplorer;
|
|
||||||
const url = `${explorer.extensionEndpoint()}/api/offerthroughputrequest/updatebeyondspecifiedlimit`;
|
|
||||||
const authorizationHeader = getAuthorizationHeader();
|
|
||||||
|
|
||||||
const response = await fetch(url, {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify(request),
|
|
||||||
headers: { [authorizationHeader.header]: authorizationHeader.token }
|
|
||||||
});
|
|
||||||
|
|
||||||
if (response.ok) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
throw new Error(await response.text());
|
|
||||||
}
|
|
||||||
|
|
||||||
function _createDatabase(request: DataModels.CreateDatabaseRequest, options: any = {}): Q.Promise<DataModels.Database> {
|
function _createDatabase(request: DataModels.CreateDatabaseRequest, options: any = {}): Q.Promise<DataModels.Database> {
|
||||||
const { databaseId, databaseLevelThroughput, offerThroughput, autoPilot, hasAutoPilotV2FeatureFlag } = request;
|
const { databaseId, databaseLevelThroughput, offerThroughput, autoPilot, hasAutoPilotV2FeatureFlag } = request;
|
||||||
const createBody: DatabaseRequest = { id: databaseId };
|
const createBody: DatabaseRequest = { id: databaseId };
|
||||||
|
|
|
@ -383,40 +383,6 @@ export function updateOffer(
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateOfferThroughputBeyondLimit(
|
|
||||||
requestPayload: DataModels.UpdateOfferThroughputRequest
|
|
||||||
): Q.Promise<void> {
|
|
||||||
const deferred: Q.Deferred<void> = Q.defer<void>();
|
|
||||||
const resourceDescriptionInfo: string = requestPayload.collectionName
|
|
||||||
? `database ${requestPayload.databaseName} and container ${requestPayload.collectionName}`
|
|
||||||
: `database ${requestPayload.databaseName}`;
|
|
||||||
const id = NotificationConsoleUtils.logConsoleMessage(
|
|
||||||
ConsoleDataType.InProgress,
|
|
||||||
`Requesting increase in throughput to ${requestPayload.throughput} for ${resourceDescriptionInfo}`
|
|
||||||
);
|
|
||||||
DataAccessUtilityBase.updateOfferThroughputBeyondLimit(requestPayload)
|
|
||||||
.then(
|
|
||||||
() => {
|
|
||||||
NotificationConsoleUtils.logConsoleMessage(
|
|
||||||
ConsoleDataType.Info,
|
|
||||||
`Successfully requested an increase in throughput to ${requestPayload.throughput} for ${resourceDescriptionInfo}`
|
|
||||||
);
|
|
||||||
deferred.resolve();
|
|
||||||
},
|
|
||||||
(error: any) => {
|
|
||||||
NotificationConsoleUtils.logConsoleMessage(
|
|
||||||
ConsoleDataType.Error,
|
|
||||||
`Failed to request an increase in throughput for ${requestPayload.throughput}: ${JSON.stringify(error)}`
|
|
||||||
);
|
|
||||||
sendNotificationForError(error);
|
|
||||||
deferred.reject(error);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.finally(() => NotificationConsoleUtils.clearInProgressMessageWithId(id));
|
|
||||||
|
|
||||||
return deferred.promise.timeout(Constants.ClientDefaults.requestTimeoutMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateStoredProcedure(
|
export function updateStoredProcedure(
|
||||||
collection: ViewModels.Collection,
|
collection: ViewModels.Collection,
|
||||||
storedProcedure: DataModels.StoredProcedure,
|
storedProcedure: DataModels.StoredProcedure,
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { updateOfferThroughputBeyondLimit } from "./updateOfferThroughputBeyondLimit";
|
||||||
|
|
||||||
|
describe("updateOfferThroughputBeyondLimit", () => {
|
||||||
|
it("should call fetch", async () => {
|
||||||
|
window.fetch = jest.fn(() => {
|
||||||
|
return {
|
||||||
|
ok: true
|
||||||
|
};
|
||||||
|
});
|
||||||
|
window.dataExplorer = {
|
||||||
|
logConsoleData: jest.fn(),
|
||||||
|
deleteInProgressConsoleDataWithId: jest.fn(),
|
||||||
|
extensionEndpoint: jest.fn()
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
} as any;
|
||||||
|
await updateOfferThroughputBeyondLimit({
|
||||||
|
subscriptionId: "foo",
|
||||||
|
resourceGroup: "foo",
|
||||||
|
databaseAccountName: "foo",
|
||||||
|
databaseName: "foo",
|
||||||
|
throughput: 1000000000,
|
||||||
|
offerIsRUPerMinuteThroughputEnabled: false
|
||||||
|
});
|
||||||
|
expect(window.fetch).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,52 @@
|
||||||
|
import { Platform, configContext } from "../../ConfigContext";
|
||||||
|
import { getAuthorizationHeader } from "../../Utils/AuthorizationUtils";
|
||||||
|
import { AutoPilotOfferSettings } from "../../Contracts/DataModels";
|
||||||
|
import { logConsoleProgress, logConsoleInfo, logConsoleError } from "../../Utils/NotificationConsoleUtils";
|
||||||
|
import { HttpHeaders } from "../Constants";
|
||||||
|
|
||||||
|
interface UpdateOfferThroughputRequest {
|
||||||
|
subscriptionId: string;
|
||||||
|
resourceGroup: string;
|
||||||
|
databaseAccountName: string;
|
||||||
|
databaseName: string;
|
||||||
|
collectionName?: string;
|
||||||
|
throughput: number;
|
||||||
|
offerIsRUPerMinuteThroughputEnabled: boolean;
|
||||||
|
offerAutopilotSettings?: AutoPilotOfferSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updateOfferThroughputBeyondLimit(request: UpdateOfferThroughputRequest): Promise<void> {
|
||||||
|
if (configContext.platform !== Platform.Portal) {
|
||||||
|
throw new Error("Updating throughput beyond specified limit is not supported on this platform");
|
||||||
|
}
|
||||||
|
|
||||||
|
const resourceDescriptionInfo = request.collectionName
|
||||||
|
? `database ${request.databaseName} and container ${request.collectionName}`
|
||||||
|
: `database ${request.databaseName}`;
|
||||||
|
|
||||||
|
const clearMessage = logConsoleProgress(
|
||||||
|
`Requesting increase in throughput to ${request.throughput} for ${resourceDescriptionInfo}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const explorer = window.dataExplorer;
|
||||||
|
const url = `${explorer.extensionEndpoint()}/api/offerthroughputrequest/updatebeyondspecifiedlimit`;
|
||||||
|
const authorizationHeader = getAuthorizationHeader();
|
||||||
|
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(request),
|
||||||
|
headers: { [authorizationHeader.header]: authorizationHeader.token, [HttpHeaders.contentType]: "application/json" }
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
logConsoleInfo(
|
||||||
|
`Successfully requested an increase in throughput to ${request.throughput} for ${resourceDescriptionInfo}`
|
||||||
|
);
|
||||||
|
clearMessage();
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const error = await response.json();
|
||||||
|
logConsoleError(`Failed to request an increase in throughput for ${request.throughput}: ${error.message}`);
|
||||||
|
clearMessage();
|
||||||
|
throw new Error(error.message);
|
||||||
|
}
|
|
@ -312,17 +312,6 @@ export interface Query {
|
||||||
query: string;
|
query: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateOfferThroughputRequest {
|
|
||||||
subscriptionId: string;
|
|
||||||
resourceGroup: string;
|
|
||||||
databaseAccountName: string;
|
|
||||||
databaseName: string;
|
|
||||||
collectionName: string;
|
|
||||||
throughput: number;
|
|
||||||
offerIsRUPerMinuteThroughputEnabled: boolean;
|
|
||||||
offerAutopilotSettings?: AutoPilotOfferSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AutoPilotOfferSettings {
|
export interface AutoPilotOfferSettings {
|
||||||
tier?: AutopilotTier;
|
tier?: AutopilotTier;
|
||||||
maximumTierThroughput?: number;
|
maximumTierThroughput?: number;
|
||||||
|
|
|
@ -16,9 +16,10 @@ import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
||||||
import { PlatformType } from "../../PlatformType";
|
import { PlatformType } from "../../PlatformType";
|
||||||
import { RequestOptions } from "@azure/cosmos/dist-esm";
|
import { RequestOptions } from "@azure/cosmos/dist-esm";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
import { updateOfferThroughputBeyondLimit, updateOffer } from "../../Common/DocumentClientUtilityBase";
|
import { updateOffer } from "../../Common/DocumentClientUtilityBase";
|
||||||
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
import { userContext } from "../../UserContext";
|
import { userContext } from "../../UserContext";
|
||||||
|
import { updateOfferThroughputBeyondLimit } from "../../Common/dataAccess/updateOfferThroughputBeyondLimit";
|
||||||
|
|
||||||
const updateThroughputBeyondLimitWarningMessage: string = `
|
const updateThroughputBeyondLimitWarningMessage: string = `
|
||||||
You are about to request an increase in throughput beyond the pre-allocated capacity.
|
You are about to request an increase in throughput beyond the pre-allocated capacity.
|
||||||
|
@ -519,16 +520,15 @@ export default class DatabaseSettingsTab extends TabsBase implements ViewModels.
|
||||||
this.maxRUs() <= SharedConstants.CollectionCreation.DefaultCollectionRUs1Million &&
|
this.maxRUs() <= SharedConstants.CollectionCreation.DefaultCollectionRUs1Million &&
|
||||||
this.throughput() > SharedConstants.CollectionCreation.DefaultCollectionRUs1Million
|
this.throughput() > SharedConstants.CollectionCreation.DefaultCollectionRUs1Million
|
||||||
) {
|
) {
|
||||||
const requestPayload: DataModels.UpdateOfferThroughputRequest = {
|
const requestPayload = {
|
||||||
subscriptionId: userContext.subscriptionId,
|
subscriptionId: userContext.subscriptionId,
|
||||||
databaseAccountName: userContext.databaseAccount.name,
|
databaseAccountName: userContext.databaseAccount.name,
|
||||||
resourceGroup: userContext.resourceGroup,
|
resourceGroup: userContext.resourceGroup,
|
||||||
databaseName: this.database.id(),
|
databaseName: this.database.id(),
|
||||||
collectionName: undefined,
|
|
||||||
throughput: newThroughput,
|
throughput: newThroughput,
|
||||||
offerIsRUPerMinuteThroughputEnabled: false
|
offerIsRUPerMinuteThroughputEnabled: false
|
||||||
};
|
};
|
||||||
const updateOfferBeyondLimitPromise: Q.Promise<void> = updateOfferThroughputBeyondLimit(requestPayload).then(
|
const updateOfferBeyondLimitPromise = updateOfferThroughputBeyondLimit(requestPayload).then(
|
||||||
() => {
|
() => {
|
||||||
this.database.offer().content.offerThroughput = originalThroughputValue;
|
this.database.offer().content.offerThroughput = originalThroughputValue;
|
||||||
this.throughput(originalThroughputValue);
|
this.throughput(originalThroughputValue);
|
||||||
|
@ -552,7 +552,7 @@ export default class DatabaseSettingsTab extends TabsBase implements ViewModels.
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
promises.push(updateOfferBeyondLimitPromise);
|
promises.push(Q(updateOfferBeyondLimitPromise));
|
||||||
} else {
|
} else {
|
||||||
const newOffer: DataModels.Offer = {
|
const newOffer: DataModels.Offer = {
|
||||||
content: {
|
content: {
|
||||||
|
|
|
@ -17,13 +17,10 @@ import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
||||||
import { PlatformType } from "../../PlatformType";
|
import { PlatformType } from "../../PlatformType";
|
||||||
import { RequestOptions } from "@azure/cosmos/dist-esm";
|
import { RequestOptions } from "@azure/cosmos/dist-esm";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
import {
|
import { updateOffer, updateCollection } from "../../Common/DocumentClientUtilityBase";
|
||||||
updateOfferThroughputBeyondLimit,
|
|
||||||
updateOffer,
|
|
||||||
updateCollection
|
|
||||||
} from "../../Common/DocumentClientUtilityBase";
|
|
||||||
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
||||||
import { userContext } from "../../UserContext";
|
import { userContext } from "../../UserContext";
|
||||||
|
import { updateOfferThroughputBeyondLimit } from "../../Common/dataAccess/updateOfferThroughputBeyondLimit";
|
||||||
|
|
||||||
const ttlWarning: string = `
|
const ttlWarning: string = `
|
||||||
The system will automatically delete items based on the TTL value (in seconds) you provide, without needing a delete operation explicitly issued by a client application.
|
The system will automatically delete items based on the TTL value (in seconds) you provide, without needing a delete operation explicitly issued by a client application.
|
||||||
|
@ -1144,7 +1141,7 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
||||||
newThroughput > SharedConstants.CollectionCreation.DefaultCollectionRUs1Million &&
|
newThroughput > SharedConstants.CollectionCreation.DefaultCollectionRUs1Million &&
|
||||||
this.container != null
|
this.container != null
|
||||||
) {
|
) {
|
||||||
const requestPayload: DataModels.UpdateOfferThroughputRequest = {
|
const requestPayload = {
|
||||||
subscriptionId: userContext.subscriptionId,
|
subscriptionId: userContext.subscriptionId,
|
||||||
databaseAccountName: userContext.databaseAccount.name,
|
databaseAccountName: userContext.databaseAccount.name,
|
||||||
resourceGroup: userContext.resourceGroup,
|
resourceGroup: userContext.resourceGroup,
|
||||||
|
@ -1153,7 +1150,7 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
||||||
throughput: newThroughput,
|
throughput: newThroughput,
|
||||||
offerIsRUPerMinuteThroughputEnabled: isRUPerMinuteThroughputEnabled
|
offerIsRUPerMinuteThroughputEnabled: isRUPerMinuteThroughputEnabled
|
||||||
};
|
};
|
||||||
const updateOfferBeyondLimitPromise: Q.Promise<void> = updateOfferThroughputBeyondLimit(requestPayload).then(
|
const updateOfferBeyondLimitPromise = updateOfferThroughputBeyondLimit(requestPayload).then(
|
||||||
() => {
|
() => {
|
||||||
this.collection.offer().content.offerThroughput = originalThroughputValue;
|
this.collection.offer().content.offerThroughput = originalThroughputValue;
|
||||||
this.throughput(originalThroughputValue);
|
this.throughput(originalThroughputValue);
|
||||||
|
@ -1185,7 +1182,7 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
promises.push(updateOfferBeyondLimitPromise);
|
promises.push(Q(updateOfferBeyondLimitPromise));
|
||||||
} else {
|
} else {
|
||||||
const updateOfferPromise = updateOffer(this.collection.offer(), newOffer, headerOptions).then(
|
const updateOfferPromise = updateOffer(this.collection.offer(), newOffer, headerOptions).then(
|
||||||
(updatedOffer: DataModels.Offer) => {
|
(updatedOffer: DataModels.Offer) => {
|
||||||
|
|
Loading…
Reference in New Issue