Skip to content

Commit 06e0f9d

Browse files
scottschreckengaustgithub-actionskrokoko
authored
feat: add destroy and create options for generate physical name (#758)
* feat: add destroy and create options for generate physical name FIXES: 734 --------- Signed-off-by: Scott Schreckengaust <[email protected]> Signed-off-by: github-actions <[email protected]> Co-authored-by: github-actions <[email protected]> Co-authored-by: Alain Krok <[email protected]>
1 parent 52fd030 commit 06e0f9d

File tree

3 files changed

+44
-4
lines changed

3 files changed

+44
-4
lines changed

src/cdk-lib/bedrock/data-sources/s3-data-source.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,12 @@ export class S3DataSource extends DataSourceNew {
9999
// Assign attributes
100100
this.knowledgeBase = props.knowledgeBase;
101101
this.dataSourceType = DataSourceType.S3;
102-
this.dataSourceName = props.dataSourceName ?? generatePhysicalNameV2(this, 's3-ds', { maxLength: 40, lower: true, separator: '-' });;
102+
103+
// Turns out chunking and parsing are not replace so pass
104+
const chunkingStrategy = props.chunkingStrategy;
105+
const parsingStrategy = props.parsingStrategy;
106+
const theseAreNotReplacable = { chunkingStrategy, parsingStrategy };
107+
this.dataSourceName = props.dataSourceName ?? generatePhysicalNameV2(this, 's3-ds', { maxLength: 40, lower: true, separator: '-', destroyCreate: theseAreNotReplacable });;
103108
this.bucket = props.bucket;
104109
this.kmsKey = props.kmsKey;
105110

src/common/helpers/utils.ts

+26-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
1111
* and limitations under the License.
1212
*/
13+
import { createHash } from 'crypto';
1314
import * as cdk from 'aws-cdk-lib';
1415
import { IConstruct } from 'constructs';
1516
import { CfnNagSuppressRule } from '../../patterns/gen-ai/aws-rag-appsync-stepfn-kendra/types';
@@ -76,6 +77,12 @@ export interface GeneratePhysicalNameV2Options extends cdk.UniqueResourceNameOpt
7677
* @default false
7778
*/
7879
lower?: boolean;
80+
81+
/**
82+
* This object is hashed for uniqueness and can force a destroy instead of a replace.
83+
* @default: undefined
84+
*/
85+
destroyCreate?: any;
7986
}
8087
/**
8188
* @internal This is an internal core function and should not be called directly by Solutions Constructs clients.
@@ -102,20 +109,36 @@ export function generatePhysicalNameV2(
102109
*/
103110
options?: GeneratePhysicalNameV2Options,
104111
): string {
112+
function objectToHash(obj: any): string {
113+
// Nothing to hash if undefined
114+
if (obj === undefined) { return ''; }
115+
116+
// Convert the object to a JSON string
117+
const jsonString = JSON.stringify(obj);
118+
119+
// Create a SHA-256 hash
120+
const hash = createHash('sha256');
121+
122+
// Update the hash with the JSON string and get the digest in hexadecimal format
123+
// Shorten it (modeled after seven characters like git commit hash shortening)
124+
return hash.update(jsonString).digest('hex').slice(0, 7);
125+
}
105126
const {
106127
maxLength = 256,
107128
lower = false,
108129
separator = '',
109130
allowedSpecialCharacters = undefined,
131+
destroyCreate = undefined,
110132
} = options ?? {};
111-
if (maxLength < (prefix + separator).length) {
133+
const hash = objectToHash(destroyCreate);
134+
if (maxLength < (prefix + hash + separator).length) {
112135
throw new Error('The prefix is longer than the maximum length.');
113136
}
114137
const uniqueName = cdk.Names.uniqueResourceName(
115138
scope,
116-
{ maxLength: maxLength - (prefix + separator).length, separator, allowedSpecialCharacters },
139+
{ maxLength: maxLength - (prefix + hash + separator).length, separator, allowedSpecialCharacters },
117140
);
118-
const name = `${prefix}${separator}${uniqueName}`;
141+
const name = `${prefix}${hash}${separator}${uniqueName}`;
119142
if (name.length > maxLength) {
120143
throw new Error(`The generated name is longer than the maximum length of ${maxLength}`);
121144
}

test/common/helpers/utils.test.ts

+12
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,18 @@ describe('generatePhysicalNameV2', () => {
281281
}).toThrow(new RegExp('^The generated name is longer than the maximum length of'));
282282
});
283283

284+
test('hash for a more unique name', () => {
285+
const hashedName = generatePhysicalNameV2(
286+
testResourceB,
287+
'test',
288+
{
289+
destroyCreate: { one: 'XXX', two: true, three: undefined },
290+
});
291+
292+
expect(hashedName).not.toMatch(new RegExp('^test' + testResourceB.stack.stackName));
293+
expect(hashedName).toMatch(new RegExp('^test' + '[0-9a-f]{7}' + testResourceB.stack.stackName));
294+
expect(hashedName).toEqual('test0221ffeTestStackAB27595CD3');
295+
});
284296

285297
describe('kendra general utils', () => {
286298
describe('addCfnSuppressRules', () => {

0 commit comments

Comments
 (0)