mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-05-03 06:53:49 +01:00
Added logic
This commit is contained in:
parent
07c4ca9c50
commit
152c995ec0
@ -39,7 +39,10 @@ import {
|
|||||||
migrateTableToManualThroughput,
|
migrateTableToManualThroughput,
|
||||||
updateTableThroughput,
|
updateTableThroughput,
|
||||||
} from "../../Utils/arm/generatedClients/cosmos/tableResources";
|
} from "../../Utils/arm/generatedClients/cosmos/tableResources";
|
||||||
import { ThroughputSettingsUpdateParameters } from "../../Utils/arm/generatedClients/cosmos/types";
|
import {
|
||||||
|
ThroughputSettingsGetResults,
|
||||||
|
ThroughputSettingsUpdateParameters,
|
||||||
|
} from "../../Utils/arm/generatedClients/cosmos/types";
|
||||||
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
|
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
|
||||||
import { HttpHeaders } from "../Constants";
|
import { HttpHeaders } from "../Constants";
|
||||||
import { client } from "../CosmosClient";
|
import { client } from "../CosmosClient";
|
||||||
@ -146,23 +149,28 @@ const updateSqlContainerOffer = async (params: UpdateOfferParams): Promise<void>
|
|||||||
const { subscriptionId, resourceGroup, databaseAccount } = userContext;
|
const { subscriptionId, resourceGroup, databaseAccount } = userContext;
|
||||||
const accountName = databaseAccount.name;
|
const accountName = databaseAccount.name;
|
||||||
|
|
||||||
|
let updatedOffer: ThroughputSettingsGetResults;
|
||||||
|
|
||||||
if (params.migrateToAutoPilot) {
|
if (params.migrateToAutoPilot) {
|
||||||
await migrateSqlContainerToAutoscale(
|
updatedOffer = (await migrateSqlContainerToAutoscale(
|
||||||
subscriptionId,
|
subscriptionId,
|
||||||
resourceGroup,
|
resourceGroup,
|
||||||
accountName,
|
accountName,
|
||||||
params.databaseId,
|
params.databaseId,
|
||||||
params.collectionId,
|
params.collectionId,
|
||||||
);
|
)) as ThroughputSettingsGetResults;
|
||||||
|
params.autopilotThroughput = updatedOffer.properties?.resource?.autoscaleSettings?.maxThroughput;
|
||||||
} else if (params.migrateToManual) {
|
} else if (params.migrateToManual) {
|
||||||
await migrateSqlContainerToManualThroughput(
|
updatedOffer = (await migrateSqlContainerToManualThroughput(
|
||||||
subscriptionId,
|
subscriptionId,
|
||||||
resourceGroup,
|
resourceGroup,
|
||||||
accountName,
|
accountName,
|
||||||
params.databaseId,
|
params.databaseId,
|
||||||
params.collectionId,
|
params.collectionId,
|
||||||
);
|
)) as ThroughputSettingsGetResults;
|
||||||
} else {
|
params.manualThroughput = updatedOffer.properties?.resource?.throughput;
|
||||||
|
}
|
||||||
|
if (params.throughputBuckets || !(params.migrateToAutoPilot || params.migrateToManual)) {
|
||||||
const body: ThroughputSettingsUpdateParameters = createUpdateOfferBody(params);
|
const body: ThroughputSettingsUpdateParameters = createUpdateOfferBody(params);
|
||||||
await updateSqlContainerThroughput(
|
await updateSqlContainerThroughput(
|
||||||
subscriptionId,
|
subscriptionId,
|
||||||
|
@ -106,6 +106,7 @@ export interface SettingsComponentState {
|
|||||||
changeFeedPolicyBaseline: ChangeFeedPolicyState;
|
changeFeedPolicyBaseline: ChangeFeedPolicyState;
|
||||||
isSubSettingsSaveable: boolean;
|
isSubSettingsSaveable: boolean;
|
||||||
isSubSettingsDiscardable: boolean;
|
isSubSettingsDiscardable: boolean;
|
||||||
|
isThroughputBucketsSaveable: boolean;
|
||||||
|
|
||||||
vectorEmbeddingPolicy: DataModels.VectorEmbeddingPolicy;
|
vectorEmbeddingPolicy: DataModels.VectorEmbeddingPolicy;
|
||||||
vectorEmbeddingPolicyBaseline: DataModels.VectorEmbeddingPolicy;
|
vectorEmbeddingPolicyBaseline: DataModels.VectorEmbeddingPolicy;
|
||||||
@ -179,7 +180,9 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
|
|
||||||
this.changeFeedPolicyVisible = userContext.features.enableChangeFeedPolicy;
|
this.changeFeedPolicyVisible = userContext.features.enableChangeFeedPolicy;
|
||||||
this.throughputBucketsEnabled =
|
this.throughputBucketsEnabled =
|
||||||
userContext.features.enableThroughputBuckets && userContext.authType === AuthType.AAD;
|
userContext.apiType === "SQL" &&
|
||||||
|
userContext.features.enableThroughputBuckets &&
|
||||||
|
userContext.authType === AuthType.AAD;
|
||||||
|
|
||||||
// Mongo container with system partition key still treat as "Fixed"
|
// Mongo container with system partition key still treat as "Fixed"
|
||||||
this.isFixedContainer =
|
this.isFixedContainer =
|
||||||
@ -218,6 +221,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
changeFeedPolicyBaseline: undefined,
|
changeFeedPolicyBaseline: undefined,
|
||||||
isSubSettingsSaveable: false,
|
isSubSettingsSaveable: false,
|
||||||
isSubSettingsDiscardable: false,
|
isSubSettingsDiscardable: false,
|
||||||
|
isThroughputBucketsSaveable: false,
|
||||||
|
|
||||||
vectorEmbeddingPolicy: undefined,
|
vectorEmbeddingPolicy: undefined,
|
||||||
vectorEmbeddingPolicyBaseline: undefined,
|
vectorEmbeddingPolicyBaseline: undefined,
|
||||||
@ -450,6 +454,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
isScaleSaveable: false,
|
isScaleSaveable: false,
|
||||||
isScaleDiscardable: false,
|
isScaleDiscardable: false,
|
||||||
isSubSettingsSaveable: false,
|
isSubSettingsSaveable: false,
|
||||||
|
isThroughputBucketsSaveable: false,
|
||||||
isSubSettingsDiscardable: false,
|
isSubSettingsDiscardable: false,
|
||||||
isContainerPolicyDirty: false,
|
isContainerPolicyDirty: false,
|
||||||
isIndexingPolicyDirty: false,
|
isIndexingPolicyDirty: false,
|
||||||
@ -488,6 +493,10 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
private onIndexingPolicyContentChange = (newIndexingPolicy: DataModels.IndexingPolicy): void =>
|
private onIndexingPolicyContentChange = (newIndexingPolicy: DataModels.IndexingPolicy): void =>
|
||||||
this.setState({ indexingPolicyContent: newIndexingPolicy });
|
this.setState({ indexingPolicyContent: newIndexingPolicy });
|
||||||
|
|
||||||
|
private onThroughputBucketsSaveableChange = (isSaveable: boolean): void => {
|
||||||
|
this.setState({ isThroughputBucketsSaveable: isSaveable });
|
||||||
|
};
|
||||||
|
|
||||||
private resetShouldDiscardContainerPolicies = (): void => this.setState({ shouldDiscardContainerPolicies: false });
|
private resetShouldDiscardContainerPolicies = (): void => this.setState({ shouldDiscardContainerPolicies: false });
|
||||||
|
|
||||||
private resetShouldDiscardIndexingPolicy = (): void => this.setState({ shouldDiscardIndexingPolicy: false });
|
private resetShouldDiscardIndexingPolicy = (): void => this.setState({ shouldDiscardIndexingPolicy: false });
|
||||||
@ -1053,7 +1062,8 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
currentOffer: this.collection.offer(),
|
currentOffer: this.collection.offer(),
|
||||||
autopilotThroughput: this.state.isAutoPilotSelected ? this.state.autoPilotThroughput : undefined,
|
autopilotThroughput: this.state.isAutoPilotSelected ? this.state.autoPilotThroughput : undefined,
|
||||||
manualThroughput: this.state.isAutoPilotSelected ? undefined : this.state.throughput,
|
manualThroughput: this.state.isAutoPilotSelected ? undefined : this.state.throughput,
|
||||||
...(this.state.throughputBuckets && { throughputBuckets: this.state.throughputBuckets }),
|
...(this.throughputBucketsEnabled &&
|
||||||
|
this.state.isThroughputBucketsSaveable && { throughputBuckets: this.state.throughputBuckets }),
|
||||||
};
|
};
|
||||||
if (this.hasProvisioningTypeChanged()) {
|
if (this.hasProvisioningTypeChanged()) {
|
||||||
if (this.state.isAutoPilotSelected) {
|
if (this.state.isAutoPilotSelected) {
|
||||||
@ -1124,6 +1134,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
throughputBuckets: this.state.throughputBuckets,
|
throughputBuckets: this.state.throughputBuckets,
|
||||||
enableThroughputBuckets: this.isCollectionSettingsTab && this.throughputBucketsEnabled,
|
enableThroughputBuckets: this.isCollectionSettingsTab && this.throughputBucketsEnabled,
|
||||||
onThroughputBucketChange: this.onThroughputBucketChange,
|
onThroughputBucketChange: this.onThroughputBucketChange,
|
||||||
|
onThroughputBucketsSaveableChange: this.onThroughputBucketsSaveableChange,
|
||||||
throughputError: this.state.throughputError,
|
throughputError: this.state.throughputError,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -38,14 +38,15 @@ export interface ScaleComponentProps {
|
|||||||
throughputBucketsBaseline: DataModels.ThroughputBucket[];
|
throughputBucketsBaseline: DataModels.ThroughputBucket[];
|
||||||
enableThroughputBuckets: boolean;
|
enableThroughputBuckets: boolean;
|
||||||
onThroughputBucketChange: (throughputBuckets: DataModels.ThroughputBucket[]) => void;
|
onThroughputBucketChange: (throughputBuckets: DataModels.ThroughputBucket[]) => void;
|
||||||
|
onThroughputBucketsSaveableChange: (isSaveable: boolean) => void;
|
||||||
throughputError?: string;
|
throughputError?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ScaleComponentState {
|
interface ScaleComponentState {
|
||||||
isThroughputSaveable: boolean;
|
isThroughputSaveable: boolean;
|
||||||
isBucketsSaveable: boolean;
|
isThroughputBucketsSaveable: boolean;
|
||||||
isThroughputDiscardable: boolean;
|
isThroughputDiscardable: boolean;
|
||||||
isBucketsDiscardable: boolean;
|
isThroughputBucketsDiscardable: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ScaleComponent extends React.Component<ScaleComponentProps, ScaleComponentState> {
|
export class ScaleComponent extends React.Component<ScaleComponentProps, ScaleComponentState> {
|
||||||
@ -62,9 +63,9 @@ export class ScaleComponent extends React.Component<ScaleComponentProps, ScaleCo
|
|||||||
this.collectionId = this.props.collection?.id();
|
this.collectionId = this.props.collection?.id();
|
||||||
this.state = {
|
this.state = {
|
||||||
isThroughputSaveable: false,
|
isThroughputSaveable: false,
|
||||||
isBucketsSaveable: false,
|
isThroughputBucketsSaveable: false,
|
||||||
isThroughputDiscardable: false,
|
isThroughputDiscardable: false,
|
||||||
isBucketsDiscardable: false,
|
isThroughputBucketsDiscardable: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +99,6 @@ export class ScaleComponent extends React.Component<ScaleComponentProps, ScaleCo
|
|||||||
if (userContext.isTryCosmosDBSubscription) {
|
if (userContext.isTryCosmosDBSubscription) {
|
||||||
return SharedConstants.CollectionCreation.DefaultCollectionRUs400;
|
return SharedConstants.CollectionCreation.DefaultCollectionRUs400;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.offer?.minimumThroughput || SharedConstants.CollectionCreation.DefaultCollectionRUs400;
|
return this.offer?.minimumThroughput || SharedConstants.CollectionCreation.DefaultCollectionRUs400;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -193,9 +193,12 @@ export class ScaleComponent extends React.Component<ScaleComponentProps, ScaleCo
|
|||||||
return hasChanges ? { ...prevState, ...updates } : null;
|
return hasChanges ? { ...prevState, ...updates } : null;
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
const isSaveable = this.state.isThroughputSaveable || this.state.isBucketsSaveable;
|
const isSaveable = this.state.isThroughputSaveable
|
||||||
const isDiscardable = this.state.isThroughputDiscardable || this.state.isBucketsDiscardable;
|
? this.state.isThroughputDiscardable || this.state.isThroughputBucketsSaveable
|
||||||
|
: this.state.isThroughputBucketsSaveable;
|
||||||
|
const isDiscardable = this.state.isThroughputDiscardable || this.state.isThroughputBucketsDiscardable;
|
||||||
this.props.onScaleSaveableChange(isSaveable);
|
this.props.onScaleSaveableChange(isSaveable);
|
||||||
|
this.props.onThroughputBucketsSaveableChange(this.state.isThroughputBucketsSaveable);
|
||||||
this.props.onScaleDiscardableChange(isDiscardable);
|
this.props.onScaleDiscardableChange(isDiscardable);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -209,12 +212,12 @@ export class ScaleComponent extends React.Component<ScaleComponentProps, ScaleCo
|
|||||||
this.updateScaleSettingsState({ isThroughputDiscardable: isDiscardable });
|
this.updateScaleSettingsState({ isThroughputDiscardable: isDiscardable });
|
||||||
};
|
};
|
||||||
|
|
||||||
private handleBucketsSaveableChange = (isSaveable: boolean) => {
|
private handleThroughputBucketsSaveableChange = (isSaveable: boolean) => {
|
||||||
this.updateScaleSettingsState({ isBucketsSaveable: isSaveable });
|
this.updateScaleSettingsState({ isThroughputBucketsSaveable: isSaveable });
|
||||||
};
|
};
|
||||||
|
|
||||||
private handleBucketsDiscardableChange = (isDiscardable: boolean) => {
|
private handleThroughputBucketsDiscardableChange = (isDiscardable: boolean) => {
|
||||||
this.updateScaleSettingsState({ isBucketsDiscardable: isDiscardable });
|
this.updateScaleSettingsState({ isThroughputBucketsDiscardable: isDiscardable });
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): JSX.Element {
|
||||||
@ -232,13 +235,13 @@ export class ScaleComponent extends React.Component<ScaleComponentProps, ScaleCo
|
|||||||
<MessageBar messageBarType={MessageBarType.warning}>{this.getInitialNotificationElement()}</MessageBar>
|
<MessageBar messageBarType={MessageBarType.warning}>{this.getInitialNotificationElement()}</MessageBar>
|
||||||
)}
|
)}
|
||||||
{!this.isAutoScaleEnabled() && <Stack {...subComponentStackProps}>{this.getThroughputInputComponent()}</Stack>}
|
{!this.isAutoScaleEnabled() && <Stack {...subComponentStackProps}>{this.getThroughputInputComponent()}</Stack>}
|
||||||
{this.props.enableThroughputBuckets && !this.props.isAutoPilotSelected && (
|
{this.props.enableThroughputBuckets && (
|
||||||
<ThroughputBucketsComponent
|
<ThroughputBucketsComponent
|
||||||
currentBuckets={this.props.throughputBuckets}
|
currentBuckets={this.props.throughputBuckets}
|
||||||
throughputBucketsBaseline={this.props.throughputBucketsBaseline}
|
throughputBucketsBaseline={this.props.throughputBucketsBaseline}
|
||||||
onBucketsChange={this.props.onThroughputBucketChange}
|
onBucketsChange={this.props.onThroughputBucketChange}
|
||||||
onSaveableChange={this.handleBucketsSaveableChange}
|
onSaveableChange={this.handleThroughputBucketsSaveableChange}
|
||||||
onDiscardableChange={this.handleBucketsDiscardableChange}
|
onDiscardableChange={this.handleThroughputBucketsDiscardableChange}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Icon, Label, Slider, Stack, TextField } from "@fluentui/react";
|
import { Label, Slider, Stack, TextField, Toggle } from "@fluentui/react";
|
||||||
import { ThroughputBucket } from "Contracts/DataModels";
|
import { ThroughputBucket } from "Contracts/DataModels";
|
||||||
import React, { FC, useEffect, useState } from "react";
|
import React, { FC, useEffect, useState } from "react";
|
||||||
import { isDirty } from "../../SettingsUtils";
|
import { isDirty } from "../../SettingsUtils";
|
||||||
@ -26,7 +26,16 @@ export const ThroughputBucketsComponent: FC<ThroughputBucketsComponentProps> = (
|
|||||||
onDiscardableChange,
|
onDiscardableChange,
|
||||||
}) => {
|
}) => {
|
||||||
const getThroughputBuckets = (buckets: ThroughputBucket[]): ThroughputBucket[] => {
|
const getThroughputBuckets = (buckets: ThroughputBucket[]): ThroughputBucket[] => {
|
||||||
return DEFAULT_BUCKETS.map(
|
if (!buckets || buckets.length === 0) {
|
||||||
|
return DEFAULT_BUCKETS;
|
||||||
|
}
|
||||||
|
const maxBuckets = Math.max(DEFAULT_BUCKETS.length, buckets.length);
|
||||||
|
const adjustedDefaultBuckets = Array.from({ length: maxBuckets }, (_, i) => ({
|
||||||
|
id: i + 1,
|
||||||
|
maxThroughputPercentage: 100,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return adjustedDefaultBuckets.map(
|
||||||
(defaultBucket) => buckets?.find((bucket) => bucket.id === defaultBucket.id) || defaultBucket,
|
(defaultBucket) => buckets?.find((bucket) => bucket.id === defaultBucket.id) || defaultBucket,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -54,9 +63,13 @@ export const ThroughputBucketsComponent: FC<ThroughputBucketsComponentProps> = (
|
|||||||
settingsChanged && onBucketsChange(updatedBuckets);
|
settingsChanged && onBucketsChange(updatedBuckets);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onToggle = (id: number, checked: boolean) => {
|
||||||
|
handleBucketChange(id, checked ? 50 : 100);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack tokens={{ childrenGap: "m" }} styles={{ root: { width: "70%", maxWidth: 700 } }}>
|
<Stack tokens={{ childrenGap: "m" }} styles={{ root: { width: "70%", maxWidth: 700 } }}>
|
||||||
<Label>Throughput buckets</Label>
|
<Label>Throughput groups</Label>
|
||||||
<Stack>
|
<Stack>
|
||||||
{throughputBuckets?.map((bucket) => (
|
{throughputBuckets?.map((bucket) => (
|
||||||
<Stack key={bucket.id} horizontal tokens={{ childrenGap: 8 }} verticalAlign="center">
|
<Stack key={bucket.id} horizontal tokens={{ childrenGap: 8 }} verticalAlign="center">
|
||||||
@ -67,8 +80,9 @@ export const ThroughputBucketsComponent: FC<ThroughputBucketsComponentProps> = (
|
|||||||
value={bucket.maxThroughputPercentage}
|
value={bucket.maxThroughputPercentage}
|
||||||
onChange={(newValue) => handleBucketChange(bucket.id, newValue)}
|
onChange={(newValue) => handleBucketChange(bucket.id, newValue)}
|
||||||
showValue={false}
|
showValue={false}
|
||||||
label={`Bucket ${bucket.id}`}
|
label={`Group ${bucket.id}${bucket.id === 1 ? " (Data Explorer Query Bucket)" : ""}`}
|
||||||
styles={{ root: { flex: 2, maxWidth: 400 } }}
|
styles={{ root: { flex: 2, maxWidth: 400 } }}
|
||||||
|
disabled={bucket.maxThroughputPercentage === 100}
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
value={bucket.maxThroughputPercentage.toString()}
|
value={bucket.maxThroughputPercentage.toString()}
|
||||||
@ -78,13 +92,21 @@ export const ThroughputBucketsComponent: FC<ThroughputBucketsComponentProps> = (
|
|||||||
styles={{
|
styles={{
|
||||||
fieldGroup: { width: 80 },
|
fieldGroup: { width: 80 },
|
||||||
}}
|
}}
|
||||||
|
disabled={bucket.maxThroughputPercentage === 100}
|
||||||
/>
|
/>
|
||||||
{bucket.id === 1 && (
|
<Toggle
|
||||||
|
onText="Enabled"
|
||||||
|
offText="Disabled"
|
||||||
|
checked={bucket.maxThroughputPercentage !== 100}
|
||||||
|
onChange={(event, checked) => onToggle(bucket.id, checked)}
|
||||||
|
styles={{ root: { marginBottom: 0 }, text: { fontSize: 12 } }}
|
||||||
|
></Toggle>
|
||||||
|
{/* {bucket.id === 1 && (
|
||||||
<Stack horizontal tokens={{ childrenGap: 4 }} verticalAlign="center">
|
<Stack horizontal tokens={{ childrenGap: 4 }} verticalAlign="center">
|
||||||
<Icon iconName="TagSolid" />
|
<Icon iconName="TagSolid" />
|
||||||
<span>Data Explorer Query Bucket</span>
|
<span>Data Explorer Query Bucket</span>
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)} */}
|
||||||
</Stack>
|
</Stack>
|
||||||
))}
|
))}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user