Skip to content

Commit

Permalink
Revert "fix(servicecatalogappregistry): Remove deprecated resource in…
Browse files Browse the repository at this point in the history
… Application Construct (aws#25095)"

This reverts commit 9222f21.
  • Loading branch information
yingdon-amazon committed Apr 17, 2023
1 parent 3bf6adb commit 0082db6
Show file tree
Hide file tree
Showing 7 changed files with 338 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,29 @@ export interface IApplication extends cdk.IResource {
*/
readonly applicationName?: string;

/**
* Associate this application with an attribute group.
*
* @param attributeGroup AppRegistry attribute group
*/
associateAttributeGroup(attributeGroup: IAttributeGroup): void;

/**
* Create an attribute group and associate this application with the created attribute group.
*
* @param id name of the AttributeGroup construct to be created.
* @param attributeGroupProps AppRegistry attribute group props
*/
addAttributeGroup(id: string, attributeGroupProps: AttributeGroupAssociationProps): IAttributeGroup;

/**
* Associate this application with a CloudFormation stack.
*
* @deprecated Use `associateApplicationWithStack` instead.
* @param stack a CFN stack
*/
associateStack(stack: cdk.Stack): void;

/**
* Associate a Cloudformation statck with the application in the given stack.
*
Expand Down Expand Up @@ -112,6 +128,23 @@ abstract class ApplicationBase extends cdk.Resource implements IApplication {
private readonly associatedAttributeGroups: Set<string> = new Set();
private readonly associatedResources: Set<string> = new Set();

/**
* Associate an attribute group with application
* If the attribute group is already associated, it will ignore duplicate request.
*
* @deprecated Use `AttributeGroup.associateWith` instead.
*/
public associateAttributeGroup(attributeGroup: IAttributeGroup): void {
if (!this.associatedAttributeGroups.has(attributeGroup.node.addr)) {
const hashId = this.generateUniqueHash(attributeGroup.node.addr);
new CfnAttributeGroupAssociation(this, `AttributeGroupAssociation${hashId}`, {
application: this.applicationId,
attributeGroup: attributeGroup.attributeGroupId,
});
this.associatedAttributeGroups.add(attributeGroup.node.addr);
}
}

/**
* Create an attribute group and associate this application with the created attribute group.
*/
Expand All @@ -129,6 +162,25 @@ abstract class ApplicationBase extends cdk.Resource implements IApplication {
return attributeGroup;
}

/**
* Associate a stack with the application
* If the resource is already associated, it will ignore duplicate request.
* A stack can only be associated with one application.
*
* @deprecated Use `associateApplicationWithStack` instead.
*/
public associateStack(stack: cdk.Stack): void {
if (!this.associatedResources.has(stack.node.addr)) {
const hashId = this.generateUniqueHash(stack.node.addr);
new CfnResourceAssociation(this, `ResourceAssociation${hashId}`, {
application: this.applicationId,
resource: stack.stackId,
resourceType: 'CFN_STACK',
});
this.associatedResources.add(stack.node.addr);
}
}

/**
* Associate stack with the application in the stack passed as parameter.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,20 @@ describe('Application', () => {
});
});

test('associate attribute group', () => {
const attributeGroup = new appreg.AttributeGroup(stack, 'AttributeGroup', {
attributeGroupName: 'AttributeGroupName',
attributes: {},
});

application.associateAttributeGroup(attributeGroup);

Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalogAppRegistry::AttributeGroupAssociation', {
Application: { 'Fn::GetAtt': ['MyApplication5C63EC1D', 'Id'] },
AttributeGroup: { 'Fn::GetAtt': ['AttributeGroup409C6335', 'Id'] },
});
}),

test('associate new attribute group', () => {
application.addAttributeGroup('AttributeGroup', {
attributeGroupName: 'AttributeGroupName',
Expand All @@ -169,6 +183,78 @@ describe('Application', () => {
},
},
});
}),

test('duplicate attribute group association are idempotent', () => {
const attributeGroup = new appreg.AttributeGroup(stack, 'AttributeGroup', {
attributeGroupName: 'attributeGroupName',
attributes: { key: 'value' },
});

// If these were not idempotent, the second call would produce an error for duplicate construct ID.
application.associateAttributeGroup(attributeGroup);
application.associateAttributeGroup(attributeGroup);

Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalogAppRegistry::AttributeGroupAssociation', 1);
}),

test('multiple applications and attribute groups can associate', () => {
const application2 = new appreg.Application(stack, 'MyApplication2', {
applicationName: 'MyApplication2',
});

const attributeGroup1 = new appreg.AttributeGroup(stack, 'AttributeGroup', {
attributeGroupName: 'attributeGroupName',
attributes: { key: 'value' },
});

const attributeGroup2 = new appreg.AttributeGroup(stack, 'AttributeGroup2', {
attributeGroupName: 'attributeGroupName2',
attributes: { key: 'value' },
});

application.associateAttributeGroup(attributeGroup1);
application.associateAttributeGroup(attributeGroup2);

application2.associateAttributeGroup(attributeGroup1);
application2.associateAttributeGroup(attributeGroup2);

Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalogAppRegistry::AttributeGroupAssociation', 4);
}),

test('associate resource', () => {
const resource = new cdk.Stack(stack, 'MyStack');

application.associateStack(resource);

Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalogAppRegistry::ResourceAssociation', {
Application: { 'Fn::GetAtt': ['MyApplication5C63EC1D', 'Id'] },
Resource: { 'Fn::ImportValue': 'MyStack:ExportsOutputRefAWSStackIdB2DD5BAA' },
});
}),

test('associate resource on imported application', () => {
const resource = new cdk.Stack(stack, 'MyStack');

const importedApplication = appreg.Application.fromApplicationArn(stack, 'ImportedApplication',
'arn:aws:servicecatalog:us-east-1:123456789012:/applications/0bqmvxvgmry0ecc4mjhwypun6i');

importedApplication.associateStack(resource);

Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalogAppRegistry::ResourceAssociation', {
Application: '0bqmvxvgmry0ecc4mjhwypun6i',
Resource: { 'Fn::ImportValue': 'MyStack:ExportsOutputRefAWSStackIdB2DD5BAA' },
});
}),

test('duplicate resource assocations are idempotent', () => {
const resource = new cdk.Stack(stack, 'MyStack');

// If these were not idempotent, the second call would produce an error for duplicate construct ID.
application.associateStack(resource);
application.associateStack(resource);

Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalogAppRegistry::ResourceAssociation', 1);
});
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"version": "31.0.0",
"files": {
"f33c45795986ec36a911c738213b5076f0382d4e57e6ed43ea411e2014880ae2": {
"461d235e9497deb16b9209be4a927c7d0dc7aa06d668e38bfb19a90db8e4a4b2": {
"source": {
"path": "integ-servicecatalogappregistry-application.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "f33c45795986ec36a911c738213b5076f0382d4e57e6ed43ea411e2014880ae2.json",
"objectKey": "461d235e9497deb16b9209be4a927c7d0dc7aa06d668e38bfb19a90db8e4a4b2.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,38 @@
"Description": "My application description"
}
},
"TestApplicationResourceAssociationd232b63e52a8414E905D": {
"Type": "AWS::ServiceCatalogAppRegistry::ResourceAssociation",
"Properties": {
"Application": {
"Fn::GetAtt": [
"TestApplication2FBC585F",
"Id"
]
},
"Resource": {
"Ref": "AWS::StackId"
},
"ResourceType": "CFN_STACK"
}
},
"TestApplicationAttributeGroupAssociation4ba7f5842818B8EE1C6F": {
"Type": "AWS::ServiceCatalogAppRegistry::AttributeGroupAssociation",
"Properties": {
"Application": {
"Fn::GetAtt": [
"TestApplication2FBC585F",
"Id"
]
},
"AttributeGroup": {
"Fn::GetAtt": [
"TestAttributeGroupB1CB284F",
"Id"
]
}
}
},
"TestApplicationmyAnotherAttributeGroup375F79DB": {
"Type": "AWS::ServiceCatalogAppRegistry::AttributeGroup",
"Properties": {
Expand Down Expand Up @@ -73,6 +105,29 @@
]
}
},
"TestAttributeGroupB1CB284F": {
"Type": "AWS::ServiceCatalogAppRegistry::AttributeGroup",
"Properties": {
"Attributes": {
"stage": "alpha",
"teamMembers": [
"markI",
"markII",
"markIII"
],
"public": false,
"publishYear": 2021,
"plannedRoadMap": {
"alpha": "some time",
"beta": "another time",
"gamma": "penultimate time",
"release": "go time"
}
},
"Name": "myAttributeGroup",
"Description": "my attribute group description"
}
},
"MyRoleF48FFE04": {
"Type": "AWS::IAM::Role",
"Properties": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"validateOnSynth": false,
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/f33c45795986ec36a911c738213b5076f0382d4e57e6ed43ea411e2014880ae2.json",
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/461d235e9497deb16b9209be4a927c7d0dc7aa06d668e38bfb19a90db8e4a4b2.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
"additionalDependencies": [
Expand All @@ -39,67 +39,58 @@
"data": "TestApplication2FBC585F"
}
],
"/integ-servicecatalogappregistry-application/TestApplication/myAnotherAttributeGroup/Resource": [
"/integ-servicecatalogappregistry-application/TestApplication/ResourceAssociationd232b63e52a8": [
{
"type": "aws:cdk:logicalId",
"data": "TestApplicationmyAnotherAttributeGroup375F79DB"
"data": "TestApplicationResourceAssociationd232b63e52a8414E905D"
}
],
"/integ-servicecatalogappregistry-application/TestApplication/AttributeGroupAssociationb6f47e836a8c": [
"/integ-servicecatalogappregistry-application/TestApplication/AttributeGroupAssociation4ba7f5842818": [
{
"type": "aws:cdk:logicalId",
"data": "TestApplicationAttributeGroupAssociationb6f47e836a8c4FCAC29E"
"data": "TestApplicationAttributeGroupAssociation4ba7f5842818B8EE1C6F"
}
],
"/integ-servicecatalogappregistry-application/TestApplication/MyShareId": [
"/integ-servicecatalogappregistry-application/TestApplication/myAnotherAttributeGroup/Resource": [
{
"type": "aws:cdk:logicalId",
"data": "TestApplicationMyShareIdE1044482"
"data": "TestApplicationmyAnotherAttributeGroup375F79DB"
}
],
"/integ-servicecatalogappregistry-application/MyRole/Resource": [
"/integ-servicecatalogappregistry-application/TestApplication/AttributeGroupAssociationb6f47e836a8c": [
{
"type": "aws:cdk:logicalId",
"data": "MyRoleF48FFE04"
"data": "TestApplicationAttributeGroupAssociationb6f47e836a8c4FCAC29E"
}
],
"/integ-servicecatalogappregistry-application/BootstrapVersion": [
"/integ-servicecatalogappregistry-application/TestApplication/MyShareId": [
{
"type": "aws:cdk:logicalId",
"data": "BootstrapVersion"
"data": "TestApplicationMyShareIdE1044482"
}
],
"/integ-servicecatalogappregistry-application/CheckBootstrapVersion": [
"/integ-servicecatalogappregistry-application/TestAttributeGroup/Resource": [
{
"type": "aws:cdk:logicalId",
"data": "CheckBootstrapVersion"
"data": "TestAttributeGroupB1CB284F"
}
],
"TestApplicationResourceAssociationd232b63e52a8414E905D": [
"/integ-servicecatalogappregistry-application/MyRole/Resource": [
{
"type": "aws:cdk:logicalId",
"data": "TestApplicationResourceAssociationd232b63e52a8414E905D",
"trace": [
"!!DESTRUCTIVE_CHANGES: WILL_DESTROY"
]
"data": "MyRoleF48FFE04"
}
],
"TestApplicationAttributeGroupAssociation4ba7f5842818B8EE1C6F": [
"/integ-servicecatalogappregistry-application/BootstrapVersion": [
{
"type": "aws:cdk:logicalId",
"data": "TestApplicationAttributeGroupAssociation4ba7f5842818B8EE1C6F",
"trace": [
"!!DESTRUCTIVE_CHANGES: WILL_DESTROY"
]
"data": "BootstrapVersion"
}
],
"TestAttributeGroupB1CB284F": [
"/integ-servicecatalogappregistry-application/CheckBootstrapVersion": [
{
"type": "aws:cdk:logicalId",
"data": "TestAttributeGroupB1CB284F",
"trace": [
"!!DESTRUCTIVE_CHANGES: WILL_DESTROY"
]
"data": "CheckBootstrapVersion"
}
]
},
Expand Down
Loading

0 comments on commit 0082db6

Please sign in to comment.