Skip to content

Commit e32403c

Browse files
author
Lambros Petrou
authored
Merge pull request #3 from aws-cloudformation/feature-implement-handlers
Implement the handlers for the `ProfilingGroup` resource type
2 parents b994c86 + 03077fb commit e32403c

File tree

18 files changed

+574
-177
lines changed

18 files changed

+574
-177
lines changed

aws-codeguruprofiler-profilinggroup/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,6 @@ target/
1818

1919
# our logs
2020
rpdk.log
21+
22+
# used by SAM local
23+
.hypothesis/

aws-codeguruprofiler-profilinggroup/README.md

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,45 @@
22

33
Congratulations on starting development! Next steps:
44

5-
1. Write the JSON schema describing your resource, `aws-codeguruprofiler-profilinggroup.json`
5+
1. Write the JSON schema describing your resource, `aws-codeguruprofiler-profilinggroup.json`.
66
2. The RPDK will automatically generate the correct resource model from the
77
schema whenever the project is built via Maven. You can also do this manually
8-
with the following command: `cfn generate`
9-
3. Implement your resource handlers
10-
8+
with the following command: `cfn generate`.
9+
3. Implement/Modify your resource handlers.
1110

1211
Please don't modify files under `target/generated-sources/rpdk`, as they will be
1312
automatically overwritten.
1413

15-
The code use [Lombok](https://projectlombok.org/), and [you may have to install
16-
IDE integrations](https://projectlombok.org/) to enable auto-complete for
17-
Lombok-annotated classes.
14+
After modifying the JSON schema or changing the handlers implementation make sure you do the following before sending a pull-request:
15+
16+
```
17+
pre-commit run --all-files && AWS_REGION=us-east-1 mvn clean package
18+
```
19+
20+
**References**
21+
22+
- https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/resource-type-walkthrough.html
23+
- https://docs.amazonaws.cn/en_us/cloudformation-cli/latest/userguide/resource-type-schema.html
24+
- https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-kms/blob/master/alias
25+
- https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-athena/tree/master/namedquery
26+
- https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-s3/tree/master/aws-s3-bucket
27+
- The code use [Lombok](https://projectlombok.org/), and [you may have to install IDE integrations](https://projectlombok.org/) to enable auto-complete for Lombok-annotated classes.
28+
29+
30+
## How do I test this in my account?
31+
32+
1. Get credentials with ADA (if you are Amazonian) or with any other way.
33+
2. Run the following to register the resource type to your account (only needed after changes) and create the required CloudFormation stacks:
34+
```
35+
cfn submit -v --region us-east-1
36+
```
37+
2. Create a sample CloudFormation stack that defines a profiling group:
38+
```
39+
aws cloudformation create-stack --region us-east-1 --template-body "file://sample-template.json" --stack-name "sample-profiling-group-resource-creation"
40+
```
41+
3. Validate the creation of the profiling group!
42+
4. Delete the sample stack:
43+
```
44+
aws cloudformation delete-stack --region us-east-1 --stack-name "sample-profiling-group-resource-creation"
45+
```
46+
5. Validate the profiling group has been deleted!

aws-codeguruprofiler-profilinggroup/aws-codeguruprofiler-profilinggroup.json

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,26 @@
22
"typeName": "AWS::CodeGuruProfiler::ProfilingGroup",
33
"description": "This resource schema represents the Profiling Group resource in the Amazon CodeGuru Profiler service.",
44
"sourceUrl": "https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-codeguru-profiler",
5-
"definitions": {},
5+
"definitions": {
6+
"Arn": {
7+
"type": "string",
8+
"pattern": "^arn:aws(-(cn|gov))?:[a-z-]+:(([a-z]+-)+[0-9]+):([0-9]{12}):[^.]+$"
9+
}
10+
},
611
"properties": {
712
"ProfilingGroupName": {
813
"description": "The name of the profiling group.",
914
"type": "string",
1015
"minLength": 1,
1116
"maxLength": 255,
1217
"pattern": "^[\\w-]+$"
18+
},
19+
"Arn": {
20+
"description": "The Amazon Resource Name (ARN) of the specified profiling group.",
21+
"$ref": "#/definitions/Arn",
22+
"examples": [
23+
"arn:aws:codeguru-profiler:us-east-1:000000000000:profilingGroup/My-example-profiling-group"
24+
]
1325
}
1426
},
1527
"additionalProperties": false,
@@ -19,6 +31,9 @@
1931
"primaryIdentifier": [
2032
"/properties/ProfilingGroupName"
2133
],
34+
"readOnlyProperties": [
35+
"/properties/Arn"
36+
],
2237
"createOnlyProperties": [
2338
"/properties/ProfilingGroupName"
2439
],

aws-codeguruprofiler-profilinggroup/pom.xml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,12 @@
7070
<scope>test</scope>
7171
</dependency>
7272

73-
<!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-codeguruprofiler -->
73+
<!-- https://mvnrepository.com/artifact/software.amazon.awssdk/codeguruprofiler -->
7474
<dependency>
75-
<groupId>com.amazonaws</groupId>
76-
<artifactId>aws-java-sdk-codeguruprofiler</artifactId>
77-
<version>1.11.720</version>
75+
<groupId>software.amazon.awssdk</groupId>
76+
<artifactId>codeguruprofiler</artifactId>
77+
<version>2.10.63</version>
7878
</dependency>
79-
80-
8179
</dependencies>
8280

8381
<build>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"credentials": {
3+
"accessKeyId": "",
4+
"secretAccessKey": "",
5+
"sessionToken": ""
6+
},
7+
"action": "CREATE",
8+
"request": {
9+
"clientRequestToken": "4b90a7e4-b790-456b-a937-0cfdfa211dfe",
10+
"desiredResourceState": {
11+
"ProfilingGroupName": "Lambros-Testing-REPLACE-THIS"
12+
},
13+
"logicalResourceIdentifier": "LambrosTestProfilingGroupResource"
14+
},
15+
"callbackContext": null
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"credentials": {
3+
"accessKeyId": "",
4+
"secretAccessKey": "",
5+
"sessionToken": ""
6+
},
7+
"action": "DELETE",
8+
"request": {
9+
"clientRequestToken": "4b90a7e4-b790-456b-a937-0cfdfa211dfe",
10+
"desiredResourceState": {
11+
"ProfilingGroupName": "Lambros-Testing-REPLACE-THIS"
12+
},
13+
"logicalResourceIdentifier": "LambrosTestProfilingGroupResource"
14+
},
15+
"callbackContext": null
16+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"AWSTemplateFormatVersion": "2010-09-09",
3+
"Description": "Sample template for the AWS::CodeGuruProfiler::ProfilingGroup resource.",
4+
"Resources": {
5+
"MyProfilingGroup": {
6+
"Type": "AWS::CodeGuruProfiler::ProfilingGroup",
7+
"Properties": {
8+
"ProfilingGroupName": "MySampleProfilingGroup"
9+
}
10+
}
11+
},
12+
"Outputs": {
13+
"Ref": {
14+
"Description": "The Ref",
15+
"Value": {
16+
"Ref": "MyProfilingGroup"
17+
}
18+
},
19+
"GetAttArn": {
20+
"Description": "The GetAtt",
21+
"Value": {
22+
"Fn::GetAtt": [
23+
"MyProfilingGroup",
24+
"Arn"
25+
]
26+
}
27+
}
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
package software.amazon.codeguruprofiler.profilinggroup;
22

3+
import software.amazon.awssdk.services.codeguruprofiler.CodeGuruProfilerClient;
4+
import software.amazon.awssdk.services.codeguruprofiler.model.ConflictException;
5+
import software.amazon.awssdk.services.codeguruprofiler.model.CreateProfilingGroupRequest;
6+
import software.amazon.awssdk.services.codeguruprofiler.model.InternalServerException;
7+
import software.amazon.awssdk.services.codeguruprofiler.model.ServiceQuotaExceededException;
8+
import software.amazon.awssdk.services.codeguruprofiler.model.ThrottlingException;
9+
import software.amazon.awssdk.services.codeguruprofiler.model.ValidationException;
10+
import software.amazon.cloudformation.exceptions.CfnAlreadyExistsException;
11+
import software.amazon.cloudformation.exceptions.CfnInvalidRequestException;
12+
import software.amazon.cloudformation.exceptions.CfnServiceInternalErrorException;
13+
import software.amazon.cloudformation.exceptions.CfnServiceLimitExceededException;
14+
import software.amazon.cloudformation.exceptions.CfnThrottlingException;
315
import software.amazon.cloudformation.proxy.AmazonWebServicesClientProxy;
416
import software.amazon.cloudformation.proxy.Logger;
517
import software.amazon.cloudformation.proxy.ProgressEvent;
6-
import software.amazon.cloudformation.proxy.OperationStatus;
718
import software.amazon.cloudformation.proxy.ResourceHandlerRequest;
819

920
public class CreateHandler extends BaseHandler<CallbackContext> {
@@ -17,11 +28,28 @@ public ProgressEvent<ResourceModel, CallbackContext> handleRequest(
1728

1829
final ResourceModel model = request.getDesiredResourceState();
1930

20-
// System.out.println(model.toString());
31+
try {
32+
CodeGuruProfilerClient profilerClient = CodeGuruProfilerClient.create();
2133

22-
return ProgressEvent.<ResourceModel, CallbackContext>builder()
23-
.resourceModel(model)
24-
.status(OperationStatus.SUCCESS)
25-
.build();
34+
CreateProfilingGroupRequest createProfilingGroupRequest = CreateProfilingGroupRequest.builder()
35+
.profilingGroupName(model.getProfilingGroupName())
36+
.build();
37+
38+
proxy.injectCredentialsAndInvokeV2(createProfilingGroupRequest, profilerClient::createProfilingGroup);
39+
40+
logger.log(String.format("%s [%s] has been successfully created!", ResourceModel.TYPE_NAME, model.getProfilingGroupName()));
41+
42+
return ProgressEvent.defaultSuccessHandler(model);
43+
} catch (ConflictException e) {
44+
throw new CfnAlreadyExistsException(e);
45+
} catch (InternalServerException e) {
46+
throw new CfnServiceInternalErrorException(e);
47+
} catch (ServiceQuotaExceededException e) {
48+
throw new CfnServiceLimitExceededException(e);
49+
} catch (ThrottlingException e) {
50+
throw new CfnThrottlingException(e);
51+
} catch (ValidationException e) {
52+
throw new CfnInvalidRequestException(ResourceModel.TYPE_NAME + e.getMessage(), e);
53+
}
2654
}
2755
}
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
package software.amazon.codeguruprofiler.profilinggroup;
22

3+
import software.amazon.awssdk.services.codeguruprofiler.CodeGuruProfilerClient;
4+
import software.amazon.awssdk.services.codeguruprofiler.model.DeleteProfilingGroupRequest;
5+
import software.amazon.awssdk.services.codeguruprofiler.model.InternalServerException;
6+
import software.amazon.awssdk.services.codeguruprofiler.model.ResourceNotFoundException;
7+
import software.amazon.awssdk.services.codeguruprofiler.model.ThrottlingException;
8+
import software.amazon.awssdk.services.codeguruprofiler.model.ValidationException;
9+
import software.amazon.cloudformation.exceptions.CfnInvalidRequestException;
10+
import software.amazon.cloudformation.exceptions.CfnNotFoundException;
11+
import software.amazon.cloudformation.exceptions.CfnServiceInternalErrorException;
12+
import software.amazon.cloudformation.exceptions.CfnThrottlingException;
313
import software.amazon.cloudformation.proxy.AmazonWebServicesClientProxy;
414
import software.amazon.cloudformation.proxy.Logger;
515
import software.amazon.cloudformation.proxy.ProgressEvent;
6-
import software.amazon.cloudformation.proxy.OperationStatus;
716
import software.amazon.cloudformation.proxy.ResourceHandlerRequest;
817

918
public class DeleteHandler extends BaseHandler<CallbackContext> {
@@ -17,11 +26,27 @@ public ProgressEvent<ResourceModel, CallbackContext> handleRequest(
1726

1827
final ResourceModel model = request.getDesiredResourceState();
1928

20-
// TODO : put your code here
29+
try {
30+
CodeGuruProfilerClient profilerClient = CodeGuruProfilerClient.create();
2131

22-
return ProgressEvent.<ResourceModel, CallbackContext>builder()
23-
.resourceModel(model)
24-
.status(OperationStatus.SUCCESS)
25-
.build();
32+
DeleteProfilingGroupRequest deleteProfilingGroupRequest = DeleteProfilingGroupRequest.builder()
33+
.profilingGroupName(model.getProfilingGroupName())
34+
.build();
35+
36+
proxy.injectCredentialsAndInvokeV2(deleteProfilingGroupRequest, profilerClient::deleteProfilingGroup);
37+
38+
logger.log(String.format("%s [%s] has been successfully deleted!", ResourceModel.TYPE_NAME, model.getProfilingGroupName()));
39+
40+
return ProgressEvent.defaultSuccessHandler(model);
41+
42+
} catch (ResourceNotFoundException e) {
43+
throw new CfnNotFoundException(e);
44+
} catch (InternalServerException e) {
45+
throw new CfnServiceInternalErrorException(e);
46+
} catch (ThrottlingException e) {
47+
throw new CfnThrottlingException(e);
48+
} catch (ValidationException e) {
49+
throw new CfnInvalidRequestException(ResourceModel.TYPE_NAME + e.getMessage(), e);
50+
}
2651
}
2752
}

aws-codeguruprofiler-profilinggroup/src/main/java/software/amazon/codeguruprofiler/profilinggroup/ListHandler.java

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
package software.amazon.codeguruprofiler.profilinggroup;
22

3+
import software.amazon.awssdk.services.codeguruprofiler.CodeGuruProfilerClient;
4+
import software.amazon.awssdk.services.codeguruprofiler.model.InternalServerException;
5+
import software.amazon.awssdk.services.codeguruprofiler.model.ListProfilingGroupsRequest;
6+
import software.amazon.awssdk.services.codeguruprofiler.model.ListProfilingGroupsResponse;
7+
import software.amazon.awssdk.services.codeguruprofiler.model.ThrottlingException;
8+
import software.amazon.cloudformation.exceptions.CfnServiceInternalErrorException;
9+
import software.amazon.cloudformation.exceptions.CfnThrottlingException;
310
import software.amazon.cloudformation.proxy.AmazonWebServicesClientProxy;
411
import software.amazon.cloudformation.proxy.Logger;
5-
import software.amazon.cloudformation.proxy.ProgressEvent;
612
import software.amazon.cloudformation.proxy.OperationStatus;
13+
import software.amazon.cloudformation.proxy.ProgressEvent;
714
import software.amazon.cloudformation.proxy.ResourceHandlerRequest;
815

916
import java.util.ArrayList;
@@ -20,11 +27,35 @@ public ProgressEvent<ResourceModel, CallbackContext> handleRequest(
2027

2128
final List<ResourceModel> models = new ArrayList<>();
2229

23-
// TODO : put your code here
30+
try {
31+
CodeGuruProfilerClient profilerClient = CodeGuruProfilerClient.create();
32+
33+
ListProfilingGroupsRequest listProfilingGroupsRequest = ListProfilingGroupsRequest.builder()
34+
.includeDescription(true)
35+
.maxResults(100)
36+
.nextToken(request.getNextToken())
37+
.build();
38+
39+
ListProfilingGroupsResponse response = proxy.injectCredentialsAndInvokeV2(listProfilingGroupsRequest, profilerClient::listProfilingGroups);
40+
41+
response.profilingGroups().forEach(pg ->
42+
models.add(ResourceModel.builder()
43+
.profilingGroupName(pg.name())
44+
.arn(pg.arn()).build())
45+
);
46+
47+
logger.log(String.format("%d \"%s\" has been successfully listed for token %s!", models.size(), ResourceModel.TYPE_NAME, request.getNextToken()));
48+
49+
return ProgressEvent.<ResourceModel, CallbackContext>builder()
50+
.resourceModels(models)
51+
.nextToken(response.nextToken())
52+
.status(OperationStatus.SUCCESS)
53+
.build();
2454

25-
return ProgressEvent.<ResourceModel, CallbackContext>builder()
26-
.resourceModels(models)
27-
.status(OperationStatus.SUCCESS)
28-
.build();
55+
} catch (InternalServerException e) {
56+
throw new CfnServiceInternalErrorException(e);
57+
} catch (ThrottlingException e) {
58+
throw new CfnThrottlingException(e);
59+
}
2960
}
3061
}

0 commit comments

Comments
 (0)