Skip to content

Commit 0ca670b

Browse files
authored
Merge pull request #493 from msailes/mark
Object representations of the CloudWatch alarms
2 parents c0b4f60 + aa9686f commit 0ca670b

File tree

8 files changed

+389
-2
lines changed

8 files changed

+389
-2
lines changed

Diff for: aws-lambda-java-events/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
* `AppSyncLambdaAuthorizerResponse`
1717
* `CloudFormationCustomResourceEvent`
1818
* `CloudFrontEvent`
19+
* `CloudWatchCompositeAlarmEvent`
1920
* `CloudWatchLogsEvent`
21+
* `CloudWatchMetricAlarmEvent`
2022
* `CodeCommitEvent`
2123
* `CognitoEvent`
2224
* `CognitoUserPoolCreateAuthChallengeEvent`

Diff for: aws-lambda-java-events/pom.xml

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
<maven.compiler.source>1.8</maven.compiler.source>
3636
<maven.compiler.target>1.8</maven.compiler.target>
3737
<lombok.version>1.18.22</lombok.version>
38+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
39+
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
3840
</properties>
3941

4042
<distributionManagement>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.amazonaws.services.lambda.runtime.events;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Data;
6+
import lombok.NoArgsConstructor;
7+
8+
/**
9+
* Represents an CloudWatch Composite Alarm event. This event occurs when a composite alarm is triggered.
10+
*
11+
* @see <a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-actions">Using Amazon CloudWatch alarms</a>
12+
*/
13+
@Data
14+
@Builder(setterPrefix = "with")
15+
@NoArgsConstructor
16+
@AllArgsConstructor
17+
public class CloudWatchCompositeAlarmEvent {
18+
private String source;
19+
private String alarmArn;
20+
private String accountId;
21+
private String time;
22+
private String region;
23+
private AlarmData alarmData;
24+
25+
@Data
26+
@Builder(setterPrefix = "with")
27+
@NoArgsConstructor
28+
@AllArgsConstructor
29+
public static class AlarmData {
30+
private String alarmName;
31+
private State state;
32+
private PreviousState previousState;
33+
private Configuration configuration;
34+
}
35+
36+
@Data
37+
@Builder(setterPrefix = "with")
38+
@NoArgsConstructor
39+
@AllArgsConstructor
40+
public static class State {
41+
private String value;
42+
private String reason;
43+
private String reasonData;
44+
private String timestamp;
45+
}
46+
47+
@Data
48+
@Builder(setterPrefix = "with")
49+
@NoArgsConstructor
50+
@AllArgsConstructor
51+
public static class PreviousState {
52+
private String value;
53+
private String reason;
54+
private String reasonData;
55+
private String timestamp;
56+
private String actionsSuppressedBy;
57+
private String actionsSuppressedReason;
58+
}
59+
60+
@Data
61+
@Builder(setterPrefix = "with")
62+
@NoArgsConstructor
63+
@AllArgsConstructor
64+
public static class Configuration {
65+
private String alarmRule;
66+
private String actionsSuppressor;
67+
private Integer actionsSuppressorWaitPeriod;
68+
private Integer actionsSuppressorExtensionPeriod;
69+
}
70+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package com.amazonaws.services.lambda.runtime.events;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Data;
6+
import lombok.NoArgsConstructor;
7+
8+
import java.util.List;
9+
import java.util.Map;
10+
11+
/**
12+
* Represents an CloudWatch Metric Alarm event. This event occurs when a metric alarm is triggered.
13+
*
14+
* @see <a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-actions">Using Amazon CloudWatch alarms</a>
15+
*/
16+
@Data
17+
@Builder(setterPrefix = "with")
18+
@NoArgsConstructor
19+
@AllArgsConstructor
20+
public class CloudWatchMetricAlarmEvent {
21+
private String source;
22+
private String alarmArn;
23+
private String accountId;
24+
private String time;
25+
private String region;
26+
private AlarmData alarmData;
27+
28+
@Data
29+
@Builder(setterPrefix = "with")
30+
@NoArgsConstructor
31+
@AllArgsConstructor
32+
public static class AlarmData {
33+
private String alarmName;
34+
private State state;
35+
private PreviousState previousState;
36+
private Configuration configuration;
37+
}
38+
39+
@Data
40+
@Builder(setterPrefix = "with")
41+
@NoArgsConstructor
42+
@AllArgsConstructor
43+
public static class State {
44+
private String value;
45+
private String reason;
46+
private String timestamp;
47+
}
48+
49+
@Data
50+
@Builder(setterPrefix = "with")
51+
@NoArgsConstructor
52+
@AllArgsConstructor
53+
public static class PreviousState {
54+
private String value;
55+
private String reason;
56+
private String reasonData;
57+
private String timestamp;
58+
}
59+
60+
@Data
61+
@Builder(setterPrefix = "with")
62+
@NoArgsConstructor
63+
@AllArgsConstructor
64+
public static class Configuration {
65+
private String description;
66+
private List<Metric> metrics;
67+
}
68+
69+
@Data
70+
@Builder(setterPrefix = "with")
71+
@NoArgsConstructor
72+
@AllArgsConstructor
73+
public static class Metric {
74+
private String id;
75+
private MetricStat metricStat;
76+
private Boolean returnData;
77+
}
78+
79+
@Data
80+
@Builder(setterPrefix = "with")
81+
@NoArgsConstructor
82+
@AllArgsConstructor
83+
public static class MetricStat {
84+
private MetricDetail metric;
85+
private Integer period;
86+
private String stat;
87+
private String unit;
88+
}
89+
90+
@Data
91+
@Builder(setterPrefix = "with")
92+
@NoArgsConstructor
93+
@AllArgsConstructor
94+
public static class MetricDetail {
95+
private String namespace;
96+
private String name;
97+
private Map<String, String> dimensions;
98+
}
99+
}

Diff for: aws-lambda-java-tests/src/main/java/com/amazonaws/services/lambda/runtime/tests/EventLoader.java

+8
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,18 @@ public static CloudFrontEvent loadCloudFrontEvent(String filename) {
4545
return loadEvent(filename, CloudFrontEvent.class);
4646
}
4747

48+
public static CloudWatchCompositeAlarmEvent loadCloudWatchCompositeAlarmEvent(String filename) {
49+
return loadEvent(filename, CloudWatchCompositeAlarmEvent.class);
50+
}
51+
4852
public static CloudWatchLogsEvent loadCloudWatchLogsEvent(String filename) {
4953
return loadEvent(filename, CloudWatchLogsEvent.class);
5054
}
5155

56+
public static CloudWatchMetricAlarmEvent loadCloudWatchMetricAlarmEvent(String filename) {
57+
return loadEvent(filename, CloudWatchMetricAlarmEvent.class);
58+
}
59+
5260
public static CodeCommitEvent loadCodeCommitEvent(String filename) {
5361
return loadEvent(filename, CodeCommitEvent.class);
5462
}

Diff for: aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/EventLoaderTest.java

+136-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,38 @@
11
/* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. */
22
package com.amazonaws.services.lambda.runtime.tests;
33

4+
import com.amazonaws.services.lambda.runtime.events.APIGatewayCustomAuthorizerEvent;
5+
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
6+
import com.amazonaws.services.lambda.runtime.events.APIGatewayV2CustomAuthorizerEvent;
7+
import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPEvent;
8+
import com.amazonaws.services.lambda.runtime.events.ActiveMQEvent;
9+
import com.amazonaws.services.lambda.runtime.events.ApplicationLoadBalancerRequestEvent;
10+
import com.amazonaws.services.lambda.runtime.events.CloudFormationCustomResourceEvent;
11+
import com.amazonaws.services.lambda.runtime.events.CloudFrontEvent;
12+
import com.amazonaws.services.lambda.runtime.events.CloudWatchCompositeAlarmEvent;
13+
import com.amazonaws.services.lambda.runtime.events.CloudWatchCompositeAlarmEvent.AlarmData;
14+
import com.amazonaws.services.lambda.runtime.events.CloudWatchCompositeAlarmEvent.Configuration;
15+
import com.amazonaws.services.lambda.runtime.events.CloudWatchCompositeAlarmEvent.PreviousState;
16+
import com.amazonaws.services.lambda.runtime.events.CloudWatchCompositeAlarmEvent.State;
17+
import com.amazonaws.services.lambda.runtime.events.CloudWatchLogsEvent;
18+
import com.amazonaws.services.lambda.runtime.events.CloudWatchMetricAlarmEvent;
19+
import com.amazonaws.services.lambda.runtime.events.CodeCommitEvent;
20+
import com.amazonaws.services.lambda.runtime.events.CognitoUserPoolPreTokenGenerationEventV2;
21+
import com.amazonaws.services.lambda.runtime.events.ConfigEvent;
22+
import com.amazonaws.services.lambda.runtime.events.ConnectEvent;
23+
import com.amazonaws.services.lambda.runtime.events.DynamodbEvent;
24+
import com.amazonaws.services.lambda.runtime.events.KafkaEvent;
25+
import com.amazonaws.services.lambda.runtime.events.KinesisEvent;
26+
import com.amazonaws.services.lambda.runtime.events.KinesisFirehoseEvent;
27+
import com.amazonaws.services.lambda.runtime.events.LambdaDestinationEvent;
28+
import com.amazonaws.services.lambda.runtime.events.LexEvent;
29+
import com.amazonaws.services.lambda.runtime.events.MSKFirehoseEvent;
30+
import com.amazonaws.services.lambda.runtime.events.RabbitMQEvent;
31+
import com.amazonaws.services.lambda.runtime.events.S3Event;
32+
import com.amazonaws.services.lambda.runtime.events.SNSEvent;
33+
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
34+
import com.amazonaws.services.lambda.runtime.events.ScheduledEvent;
35+
import com.amazonaws.services.lambda.runtime.events.SecretsManagerRotationEvent;
436
import com.amazonaws.services.lambda.runtime.events.models.dynamodb.AttributeValue;
537
import com.amazonaws.services.lambda.runtime.events.models.dynamodb.Record;
638
import com.amazonaws.services.lambda.runtime.events.models.dynamodb.StreamRecord;
@@ -15,8 +47,6 @@
1547
import static java.time.Instant.ofEpochSecond;
1648
import static org.assertj.core.api.Assertions.*;
1749

18-
import com.amazonaws.services.lambda.runtime.events.*;
19-
2050
public class EventLoaderTest {
2151

2252
@Test
@@ -389,4 +419,108 @@ public void testLoadCognitoUserPoolPreTokenGenerationEventV2() {
389419
String[] requestScopes = request.getScopes();
390420
assertThat("aws.cognito.signin.user.admin").isEqualTo(requestScopes[0]);
391421
}
422+
423+
@Test
424+
public void testCloudWatchCompositeAlarmEvent() {
425+
CloudWatchCompositeAlarmEvent event = EventLoader.loadCloudWatchCompositeAlarmEvent("cloudwatch_composite_alarm.json");
426+
assertThat(event).isNotNull();
427+
assertThat(event)
428+
.returns("aws.cloudwatch", from(CloudWatchCompositeAlarmEvent::getSource))
429+
.returns("arn:aws:cloudwatch:us-east-1:111122223333:alarm:SuppressionDemo.Main", from(CloudWatchCompositeAlarmEvent::getAlarmArn))
430+
.returns("111122223333", from(CloudWatchCompositeAlarmEvent::getAccountId))
431+
.returns("2023-08-04T12:56:46.138+0000", from(CloudWatchCompositeAlarmEvent::getTime))
432+
.returns("us-east-1", from(CloudWatchCompositeAlarmEvent::getRegion));
433+
434+
AlarmData alarmData = event.getAlarmData();
435+
assertThat(alarmData).isNotNull();
436+
assertThat(alarmData)
437+
.returns("CompositeDemo.Main", from(AlarmData::getAlarmName));
438+
439+
State state = alarmData.getState();
440+
assertThat(state).isNotNull();
441+
assertThat(state)
442+
.returns("ALARM", from(State::getValue))
443+
.returns("arn:aws:cloudwatch:us-east-1:111122223333:alarm:CompositeDemo.FirstChild transitioned to ALARM at Friday 04 August, 2023 12:54:46 UTC", from(State::getReason))
444+
.returns("{\"triggeringAlarms\":[{\"arn\":\"arn:aws:cloudwatch:us-east-1:111122223333:alarm:CompositeDemo.FirstChild\",\"state\":{\"value\":\"ALARM\",\"timestamp\":\"2023-08-04T12:54:46.138+0000\"}}]}", from(State::getReasonData))
445+
.returns("2023-08-04T12:56:46.138+0000", from(State::getTimestamp));
446+
447+
PreviousState previousState = alarmData.getPreviousState();
448+
assertThat(previousState).isNotNull();
449+
assertThat(previousState)
450+
.returns("ALARM", from(PreviousState::getValue))
451+
.returns("arn:aws:cloudwatch:us-east-1:111122223333:alarm:CompositeDemo.FirstChild transitioned to ALARM at Friday 04 August, 2023 12:54:46 UTC", from(PreviousState::getReason))
452+
.returns("{\"triggeringAlarms\":[{\"arn\":\"arn:aws:cloudwatch:us-east-1:111122223333:alarm:CompositeDemo.FirstChild\",\"state\":{\"value\":\"ALARM\",\"timestamp\":\"2023-08-04T12:54:46.138+0000\"}}]}", from(PreviousState::getReasonData))
453+
.returns("2023-08-04T12:54:46.138+0000", from(PreviousState::getTimestamp))
454+
.returns("WaitPeriod", from(PreviousState::getActionsSuppressedBy))
455+
.returns("Actions suppressed by WaitPeriod", from(PreviousState::getActionsSuppressedReason));
456+
457+
Configuration configuration = alarmData.getConfiguration();
458+
assertThat(configuration).isNotNull();
459+
assertThat(configuration)
460+
.returns("ALARM(CompositeDemo.FirstChild) OR ALARM(CompositeDemo.SecondChild)", from(Configuration::getAlarmRule))
461+
.returns("CompositeDemo.ActionsSuppressor", from(Configuration::getActionsSuppressor))
462+
.returns(120, from(Configuration::getActionsSuppressorWaitPeriod))
463+
.returns(180, from(Configuration::getActionsSuppressorExtensionPeriod));
464+
}
465+
466+
@Test
467+
public void testCloudWatchMetricAlarmEvent() {
468+
CloudWatchMetricAlarmEvent event = EventLoader.loadCloudWatchMetricAlarmEvent("cloudwatch_metric_alarm.json");
469+
assertThat(event).isNotNull();
470+
assertThat(event)
471+
.returns("aws.cloudwatch", from(CloudWatchMetricAlarmEvent::getSource))
472+
.returns("arn:aws:cloudwatch:us-east-1:444455556666:alarm:lambda-demo-metric-alarm", from(CloudWatchMetricAlarmEvent::getAlarmArn))
473+
.returns("444455556666", from(CloudWatchMetricAlarmEvent::getAccountId))
474+
.returns("2023-08-04T12:36:15.490+0000", from(CloudWatchMetricAlarmEvent::getTime))
475+
.returns("us-east-1", from(CloudWatchMetricAlarmEvent::getRegion));
476+
477+
CloudWatchMetricAlarmEvent.AlarmData alarmData = event.getAlarmData();
478+
assertThat(alarmData).isNotNull();
479+
assertThat(alarmData)
480+
.returns("lambda-demo-metric-alarm", from(CloudWatchMetricAlarmEvent.AlarmData::getAlarmName));
481+
482+
CloudWatchMetricAlarmEvent.State state = alarmData.getState();
483+
assertThat(state).isNotNull();
484+
assertThat(state)
485+
.returns("ALARM", from(CloudWatchMetricAlarmEvent.State::getValue))
486+
.returns("test", from(CloudWatchMetricAlarmEvent.State::getReason))
487+
.returns("2023-08-04T12:36:15.490+0000", from(CloudWatchMetricAlarmEvent.State::getTimestamp));
488+
489+
CloudWatchMetricAlarmEvent.PreviousState previousState = alarmData.getPreviousState();
490+
assertThat(previousState).isNotNull();
491+
assertThat(previousState)
492+
.returns("INSUFFICIENT_DATA", from(CloudWatchMetricAlarmEvent.PreviousState::getValue))
493+
.returns("Insufficient Data: 5 datapoints were unknown.", from(CloudWatchMetricAlarmEvent.PreviousState::getReason))
494+
.returns("{\"version\":\"1.0\",\"queryDate\":\"2023-08-04T12:31:29.591+0000\",\"statistic\":\"Average\",\"period\":60,\"recentDatapoints\":[],\"threshold\":5.0,\"evaluatedDatapoints\":[{\"timestamp\":\"2023-08-04T12:30:00.000+0000\"},{\"timestamp\":\"2023-08-04T12:29:00.000+0000\"},{\"timestamp\":\"2023-08-04T12:28:00.000+0000\"},{\"timestamp\":\"2023-08-04T12:27:00.000+0000\"},{\"timestamp\":\"2023-08-04T12:26:00.000+0000\"}]}", from(CloudWatchMetricAlarmEvent.PreviousState::getReasonData))
495+
.returns("2023-08-04T12:31:29.595+0000", from(CloudWatchMetricAlarmEvent.PreviousState::getTimestamp));
496+
497+
CloudWatchMetricAlarmEvent.Configuration configuration = alarmData.getConfiguration();
498+
assertThat(configuration).isNotNull();
499+
assertThat(configuration)
500+
.returns("Metric Alarm to test Lambda actions", from(CloudWatchMetricAlarmEvent.Configuration::getDescription));
501+
502+
List<CloudWatchMetricAlarmEvent.Metric> metrics = configuration.getMetrics();
503+
assertThat(metrics).hasSize(1);
504+
CloudWatchMetricAlarmEvent.Metric metric = metrics.get(0);
505+
assertThat(metric)
506+
.returns("1234e046-06f0-a3da-9534-EXAMPLEe4c", from(CloudWatchMetricAlarmEvent.Metric::getId));
507+
508+
CloudWatchMetricAlarmEvent.MetricStat metricStat = metric.getMetricStat();
509+
assertThat(metricStat).isNotNull();
510+
assertThat(metricStat)
511+
.returns(60, from(CloudWatchMetricAlarmEvent.MetricStat::getPeriod))
512+
.returns("Average", from(CloudWatchMetricAlarmEvent.MetricStat::getStat))
513+
.returns("Percent", from(CloudWatchMetricAlarmEvent.MetricStat::getUnit));
514+
515+
CloudWatchMetricAlarmEvent.MetricDetail metricDetail = metricStat.getMetric();
516+
assertThat(metricDetail).isNotNull();
517+
assertThat(metricDetail)
518+
.returns("AWS/Logs", from(CloudWatchMetricAlarmEvent.MetricDetail::getNamespace))
519+
.returns("CallCount", from(CloudWatchMetricAlarmEvent.MetricDetail::getName));
520+
521+
Map<String, String> dimensions = metricDetail.getDimensions();
522+
assertThat(dimensions).isNotEmpty().hasSize(1);
523+
assertThat(dimensions)
524+
.contains(entry("InstanceId", "i-12345678"));
525+
}
392526
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"source": "aws.cloudwatch",
3+
"alarmArn": "arn:aws:cloudwatch:us-east-1:111122223333:alarm:SuppressionDemo.Main",
4+
"accountId": "111122223333",
5+
"time": "2023-08-04T12:56:46.138+0000",
6+
"region": "us-east-1",
7+
"alarmData": {
8+
"alarmName": "CompositeDemo.Main",
9+
"state": {
10+
"value": "ALARM",
11+
"reason": "arn:aws:cloudwatch:us-east-1:111122223333:alarm:CompositeDemo.FirstChild transitioned to ALARM at Friday 04 August, 2023 12:54:46 UTC",
12+
"reasonData": "{\"triggeringAlarms\":[{\"arn\":\"arn:aws:cloudwatch:us-east-1:111122223333:alarm:CompositeDemo.FirstChild\",\"state\":{\"value\":\"ALARM\",\"timestamp\":\"2023-08-04T12:54:46.138+0000\"}}]}",
13+
"timestamp": "2023-08-04T12:56:46.138+0000"
14+
},
15+
"previousState": {
16+
"value": "ALARM",
17+
"reason": "arn:aws:cloudwatch:us-east-1:111122223333:alarm:CompositeDemo.FirstChild transitioned to ALARM at Friday 04 August, 2023 12:54:46 UTC",
18+
"reasonData": "{\"triggeringAlarms\":[{\"arn\":\"arn:aws:cloudwatch:us-east-1:111122223333:alarm:CompositeDemo.FirstChild\",\"state\":{\"value\":\"ALARM\",\"timestamp\":\"2023-08-04T12:54:46.138+0000\"}}]}",
19+
"timestamp": "2023-08-04T12:54:46.138+0000",
20+
"actionsSuppressedBy": "WaitPeriod",
21+
"actionsSuppressedReason": "Actions suppressed by WaitPeriod"
22+
},
23+
"configuration": {
24+
"alarmRule": "ALARM(CompositeDemo.FirstChild) OR ALARM(CompositeDemo.SecondChild)",
25+
"actionsSuppressor": "CompositeDemo.ActionsSuppressor",
26+
"actionsSuppressorWaitPeriod": 120,
27+
"actionsSuppressorExtensionPeriod": 180
28+
}
29+
}
30+
}

0 commit comments

Comments
 (0)