-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create a shared internal interface for props validation. Implement th…
…is interface for SQS and RDS props validation.
- Loading branch information
Showing
9 changed files
with
158 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
packages/aws-cdk-lib/aws-rds/lib/validate-database-cluster-props.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { PerformanceInsightRetention } from './props'; | ||
import { validateProps, ValidationRule } from '../../core/lib/helpers-internal'; | ||
import { ClusterScailabilityType, DatabaseCluster, DatabaseClusterProps, DBClusterStorageType } from './cluster'; | ||
|
||
const standardDatabaseRules: ValidationRule<DatabaseClusterProps>[] = [ | ||
{ | ||
condition: (props) => props.enablePerformanceInsights === false && | ||
(props.performanceInsightRetention !== undefined || props.performanceInsightEncryptionKey !== undefined), | ||
message: () => '`enablePerformanceInsights` disabled, but `performanceInsightRetention` or `performanceInsightEncryptionKey` was set', | ||
|
||
}, | ||
]; | ||
|
||
const limitlessDatabaseRules: ValidationRule<DatabaseClusterProps>[] = [ | ||
{ | ||
condition: (props) => !props.enablePerformanceInsights, | ||
message: () => 'Performance Insights must be enabled for Aurora Limitless Database', | ||
}, | ||
{ | ||
condition: (props) => !props.performanceInsightRetention | ||
|| props.performanceInsightRetention < PerformanceInsightRetention.MONTHS_1, | ||
message: () => 'Performance Insights retention period must be set to at least 31 days for Aurora Limitless Database', | ||
}, | ||
{ | ||
condition: (props) => !props.monitoringInterval || !props.enableClusterLevelEnhancedMonitoring, | ||
message: () => 'Cluster level enhanced monitoring must be set for Aurora Limitless Database. Please set \'monitoringInterval\' and enable \'enableClusterLevelEnhancedMonitoring\'', | ||
}, | ||
{ | ||
condition: (props) => !!(props.writer || props.readers), | ||
message: () => 'Aurora Limitless Database does not support reader or writer instances', | ||
}, | ||
{ | ||
condition: (props) => !props.engine.engineVersion?.fullVersion?.endsWith('limitless'), | ||
message: (props) => `Aurora Limitless Database requires an engine version that supports it, got: ${props.engine.engineVersion?.fullVersion}`, | ||
}, | ||
{ | ||
condition: (props) => props.storageType !== DBClusterStorageType.AURORA_IOPT1, | ||
message: (props) => `Aurora Limitless Database requires I/O optimized storage type, got: ${props.storageType}`, | ||
}, | ||
{ | ||
condition: (props) => props.cloudwatchLogsExports === undefined || props.cloudwatchLogsExports.length === 0, | ||
message: () => 'Aurora Limitless Database requires CloudWatch Logs exports to be set', | ||
}, | ||
]; | ||
|
||
export function validateDatabaseClusterProps(props: DatabaseClusterProps): void { | ||
const isLimitlessCluster = props.clusterScailabilityType === ClusterScailabilityType.LIMITLESS; | ||
const applicableRules = isLimitlessCluster | ||
? [...standardDatabaseRules, ...limitlessDatabaseRules] | ||
: standardDatabaseRules; | ||
|
||
validateProps(DatabaseCluster.name, props, applicableRules); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { Queue, QueueProps } from './index'; | ||
import { Token } from '../../core'; | ||
import { validateProps, ValidationRule } from '../../core/lib/helpers-internal'; | ||
|
||
function validateRange(value: number | undefined, minValue: number, maxValue: number): boolean { | ||
return value !== undefined && !Token.isUnresolved(value) && (value < minValue || value > maxValue); | ||
} | ||
|
||
const queueValidationRules: ValidationRule<QueueProps>[] = [ | ||
{ | ||
condition: (props) => validateRange(props.deliveryDelay?.toSeconds(), 0, 900), | ||
message: (props) => `delivery delay must be between 0 and 900 seconds, but ${props.deliveryDelay?.toSeconds()} was provided`, | ||
}, | ||
{ | ||
condition: (props) => validateRange(props.maxMessageSizeBytes, 1_024, 262_144), | ||
message: (props) => `maximum message size must be between 1,024 and 262,144 bytes, but ${props.maxMessageSizeBytes} was provided`, | ||
}, | ||
{ | ||
condition: (props) => validateRange(props.retentionPeriod?.toSeconds(), 60, 1_209_600), | ||
message: (props) => `message retention period must be between 60 and 1,209,600 seconds, but ${props.retentionPeriod?.toSeconds()} was provided`, | ||
}, | ||
{ | ||
condition: (props) => validateRange(props.receiveMessageWaitTime?.toSeconds(), 0, 20), | ||
message: (props) => `receive wait time must be between 0 and 20 seconds, but ${props.receiveMessageWaitTime?.toSeconds()} was provided`, | ||
}, | ||
{ | ||
condition: (props) => validateRange(props.visibilityTimeout?.toSeconds(), 0, 43_200), | ||
message: (props) => `visibility timeout must be between 0 and 43,200 seconds, but ${props.visibilityTimeout?.toSeconds()} was provided`, | ||
}, | ||
{ | ||
condition: (props) => validateRange(props.deadLetterQueue?.maxReceiveCount, 1, Number.MAX_SAFE_INTEGER), | ||
message: (props) => `dead letter target maximum receive count must be 1 or more, but ${props.deadLetterQueue?.maxReceiveCount} was provided`, | ||
}, | ||
]; | ||
|
||
export function validateQueueProps(props: QueueProps) { | ||
validateProps(Queue.name, props, queueValidationRules); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
packages/aws-cdk-lib/core/lib/helpers-internal/validate-props.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/** | ||
* Represents a validation rule for props of type T. | ||
* @template T The type of the props being validated. | ||
*/ | ||
export type ValidationRule<T> = { | ||
/** | ||
* A function that checks if the validation rule condition is met. | ||
* @param {T} props - The props to validate. | ||
* @returns {boolean} True if the condition is met (i.e., validation fails), false otherwise. | ||
*/ | ||
condition: (props: T) => boolean; | ||
|
||
/** | ||
* A function that returns an error message if the validation fails. | ||
* @param {T} props - The props that failed validation. | ||
* @returns {string} The error message. | ||
*/ | ||
message: (props: T) => string; | ||
}; | ||
|
||
/** | ||
* Validates props against a set of rules and throws an error if any validations fail. | ||
* | ||
* @template T The type of the props being validated. | ||
* @param {string} className - The name of the class being validated, used in the error message. | ||
* @param {T} props - The props to validate. | ||
* @param {ValidationRule<T>[]} rules - An array of validation rules to apply. | ||
* @throws {Error} If any validation rules fail, with a message detailing all failures. | ||
*/ | ||
export function validateProps<T>(className: string, props: T, rules: ValidationRule<T>[]): void { | ||
const validationErrors = rules | ||
.filter(rule => rule.condition(props)) | ||
.map(rule => rule.message(props)); | ||
|
||
if (validationErrors.length > 0) { | ||
const errorMessage = `${className} initialization failed due to the following validation error(s):\n${validationErrors.map(error => `- ${error}`).join('\n')}`; | ||
throw new Error(errorMessage); | ||
} | ||
} |