From 2334da02b0fe3a6d844d057e043fe1bb7623303d Mon Sep 17 00:00:00 2001 From: Slushnas Date: Thu, 20 Sep 2018 13:57:26 -0700 Subject: [PATCH 1/4] KAL-45 Add CloudWatchEvent project and base class. --- Libraries/Libraries.sln | 7 ++ .../Amazon.Lambda.CloudWatchEvents.csproj | 20 +++++ .../CloudWatchEvent.cs | 77 +++++++++++++++++++ 3 files changed, 104 insertions(+) create mode 100644 Libraries/src/Amazon.Lambda.CloudWatchEvents/Amazon.Lambda.CloudWatchEvents.csproj create mode 100644 Libraries/src/Amazon.Lambda.CloudWatchEvents/CloudWatchEvent.cs diff --git a/Libraries/Libraries.sln b/Libraries/Libraries.sln index b2a87e830..c0e00084d 100644 --- a/Libraries/Libraries.sln +++ b/Libraries/Libraries.sln @@ -77,6 +77,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerShellTests", "test\Pow EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerShellScriptsAsFunctions", "test\TestPowerShellFunctions\PowerShellScriptsAsFunctions\PowerShellScriptsAsFunctions.csproj", "{0AD1E5D6-AC23-47C1-97BF-227007021B6F}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Amazon.Lambda.CloudWatchEvents", "src\Amazon.Lambda.CloudWatchEvents\Amazon.Lambda.CloudWatchEvents.csproj", "{AD96AA48-2E1A-4BBB-9329-E1E484172FE3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -203,6 +205,10 @@ Global {0AD1E5D6-AC23-47C1-97BF-227007021B6F}.Debug|Any CPU.Build.0 = Debug|Any CPU {0AD1E5D6-AC23-47C1-97BF-227007021B6F}.Release|Any CPU.ActiveCfg = Release|Any CPU {0AD1E5D6-AC23-47C1-97BF-227007021B6F}.Release|Any CPU.Build.0 = Release|Any CPU + {AD96AA48-2E1A-4BBB-9329-E1E484172FE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD96AA48-2E1A-4BBB-9329-E1E484172FE3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AD96AA48-2E1A-4BBB-9329-E1E484172FE3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AD96AA48-2E1A-4BBB-9329-E1E484172FE3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -240,6 +246,7 @@ Global {ADEC039D-0C34-4DA7-802B-6204FFE3F1F5} = {1DE4EE60-45BA-4EF7-BE00-B9EB861E4C69} {997B1047-4361-4E6D-9850-F130EC188141} = {1DE4EE60-45BA-4EF7-BE00-B9EB861E4C69} {0AD1E5D6-AC23-47C1-97BF-227007021B6F} = {ADEC039D-0C34-4DA7-802B-6204FFE3F1F5} + {AD96AA48-2E1A-4BBB-9329-E1E484172FE3} = {AAB54E74-20B1-42ED-BC3D-CE9F7BC7FD12} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {503678A4-B8D1-4486-8915-405A3E9CF0EB} diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/Amazon.Lambda.CloudWatchEvents.csproj b/Libraries/src/Amazon.Lambda.CloudWatchEvents/Amazon.Lambda.CloudWatchEvents.csproj new file mode 100644 index 000000000..d60a4a60f --- /dev/null +++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/Amazon.Lambda.CloudWatchEvents.csproj @@ -0,0 +1,20 @@ + + + + + + netstandard1.3 + 1.6.0 + Amazon Lambda .NET Core support - CloudWatchEvents package. + Amazon.Lambda.CloudWatchEvents + 1.0.0 + Amazon.Lambda.CloudWatchEvents + Amazon.Lambda.CloudWatchEvents + AWS;Amazon;Lambda + + + + + + + diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/CloudWatchEvent.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/CloudWatchEvent.cs new file mode 100644 index 000000000..d531b5d17 --- /dev/null +++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/CloudWatchEvent.cs @@ -0,0 +1,77 @@ +namespace CloudWatchEvents +{ + using System; + using System.Collections.Generic; + + /// + /// AWS CloudWatch event + /// The contents of the detail top-level field are different depending on which service generated the event and what the event is. + /// The combination of the source and detail-type fields serves to identify the fields and values found in the detail field. + /// Complete list of events that inherit this interface: https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/EventTypes.html + /// https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/CloudWatchEventsandEventPatterns.html + /// https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/EventTypes.html + /// + public class CloudWatchEvent + { + /// + /// By default, this is set to 0 (zero) in all events. + /// + public string Version { get; set; } + + /// + /// The 12-digit number identifying an AWS account. + /// + public string Account { get; set; } + + /// + /// Identifies the AWS region where the event originated. + /// + public string Region { get; set; } + + /// + /// A JSON object, whose content is at the discretion of the service originating the event. + /// The detail content in the example above is very simple, just two fields. + /// AWS API call events have detail objects with around 50 fields nested several levels deep. + /// + public T Detail { get; set; } + + /// + /// Identifies, in combination with the source field, the fields and values that appear in the detail field. + /// For example, ScheduledEvent will be null + /// For example, ECSEvent could be "ECS Container Instance State Change" or "ECS Task State Change" + /// + public string DetailType { get; set; } + + /// + /// Identifies the service that sourced the event. + /// All events sourced from within AWS begin with "aws." + /// Customer-generated events can have any value here, as long as it doesn't begin with "aws." + /// We recommend the use of Java package-name style reverse domain-name strings. + /// For example, ScheduledEvent will be "aws.events" + /// For example, ECSEvent will be "aws.ecs" + /// + public string Source { get; set; } + + /// + /// The event timestamp, which can be specified by the service originating the event. + /// If the event spans a time interval, the service might choose to report the start time, + /// so this value can be noticeably before the time the event is actually received. + /// + public DateTime Time { get; set; } + + /// + /// A unique value is generated for every event. + /// This can be helpful in tracing events as they move through rules to targets, and are processed. + /// + public string Id { get; set; } + + /// + /// This JSON array contains ARNs that identify resources that are involved in the event. + /// Inclusion of these ARNs is at the discretion of the service. + /// For example, Amazon EC2 instance state-changes include Amazon EC2 instance ARNs, Auto Scaling events + /// include ARNs for both instances and Auto Scaling groups, but API calls with AWS CloudTrail do not + /// include resource ARNs. + /// + public List Resources { get; set; } + } +} From 525d3c3357871e3fde12f7bddeb185149ad38f62 Mon Sep 17 00:00:00 2001 From: Slushnas Date: Fri, 21 Sep 2018 10:21:41 -0700 Subject: [PATCH 2/4] KAL-45 Add detail-type serialization for CloudWatchEvents. --- .../Amazon.Lambda.Serialization.Json/AwsResolver.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Libraries/src/Amazon.Lambda.Serialization.Json/AwsResolver.cs b/Libraries/src/Amazon.Lambda.Serialization.Json/AwsResolver.cs index e5bb32558..9b87f5395 100644 --- a/Libraries/src/Amazon.Lambda.Serialization.Json/AwsResolver.cs +++ b/Libraries/src/Amazon.Lambda.Serialization.Json/AwsResolver.cs @@ -2,6 +2,7 @@ using Newtonsoft.Json.Serialization; using System; using System.Collections.Generic; +using System.Reflection; namespace Amazon.Lambda.Serialization.Json { @@ -80,6 +81,17 @@ protected override IList CreateProperties(Type type, MemberSeriali } } } + else if (type.FullName.StartsWith("Amazon.Lambda.CloudWatchEvents.") + && (type.GetTypeInfo().BaseType?.FullName?.StartsWith("CloudWatchEvents.CloudWatchEvent`", StringComparison.Ordinal) ?? false)) + { + foreach (JsonProperty property in properties) + { + if (property.PropertyName.Equals("DetailType", StringComparison.Ordinal)) + { + property.PropertyName = "detail-type"; + } + } + } return properties; } From d8d77be484b680a3916cc02cfdfe2315f46cc5b7 Mon Sep 17 00:00:00 2001 From: Slushnas Date: Sat, 22 Sep 2018 01:43:21 -0700 Subject: [PATCH 3/4] Fix CloudWatchEvents namespace. --- .../src/Amazon.Lambda.CloudWatchEvents/CloudWatchEvent.cs | 2 +- Libraries/src/Amazon.Lambda.Serialization.Json/AwsResolver.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/CloudWatchEvent.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/CloudWatchEvent.cs index d531b5d17..55968369e 100644 --- a/Libraries/src/Amazon.Lambda.CloudWatchEvents/CloudWatchEvent.cs +++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/CloudWatchEvent.cs @@ -1,4 +1,4 @@ -namespace CloudWatchEvents +namespace Amazon.Lambda.CloudWatchEvents { using System; using System.Collections.Generic; diff --git a/Libraries/src/Amazon.Lambda.Serialization.Json/AwsResolver.cs b/Libraries/src/Amazon.Lambda.Serialization.Json/AwsResolver.cs index 9b87f5395..586f485a4 100644 --- a/Libraries/src/Amazon.Lambda.Serialization.Json/AwsResolver.cs +++ b/Libraries/src/Amazon.Lambda.Serialization.Json/AwsResolver.cs @@ -82,7 +82,8 @@ protected override IList CreateProperties(Type type, MemberSeriali } } else if (type.FullName.StartsWith("Amazon.Lambda.CloudWatchEvents.") - && (type.GetTypeInfo().BaseType?.FullName?.StartsWith("CloudWatchEvents.CloudWatchEvent`", StringComparison.Ordinal) ?? false)) + && (type.GetTypeInfo().BaseType?.FullName?.StartsWith("Amazon.Lambda.CloudWatchEvents.CloudWatchEvent`", + StringComparison.Ordinal) ?? false)) { foreach (JsonProperty property in properties) { From 2caecf019c84c0007633adbb66d61d50771ef684 Mon Sep 17 00:00:00 2001 From: Slushnas Date: Sat, 22 Sep 2018 03:39:01 -0700 Subject: [PATCH 4/4] KAL-9 Add support for job state change events. --- .../Amazon.Lambda.CloudWatchEvents.csproj | 6 + .../BatchEvents/ArrayPropertiesDetail.cs | 28 +++++ .../BatchEvents/AttemptContainerDetail.cs | 38 +++++++ .../BatchEvents/AttemptDetail.cs | 31 ++++++ .../BatchEvents/BatchJobStateChangeEvent.cs | 11 ++ .../BatchEvents/ContainerDetail.cs | 103 ++++++++++++++++++ .../BatchEvents/Host.cs | 21 ++++ .../BatchEvents/Job.cs | 99 +++++++++++++++++ .../BatchEvents/JobDependency.cs | 19 ++++ .../BatchEvents/JobTimeout.cs | 15 +++ .../BatchEvents/MountPoint.cs | 25 +++++ .../BatchEvents/RetryStrategy.cs | 16 +++ .../BatchEvents/Ulimit.cs | 24 ++++ .../BatchEvents/Volume.cs | 23 ++++ Libraries/test/EventsTests/EventTests.cs | 50 ++++++++- Libraries/test/EventsTests/EventsTests.csproj | 1 + .../batch-job-state-change-event.json | 39 +++++++ 17 files changed, 548 insertions(+), 1 deletion(-) create mode 100644 Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/ArrayPropertiesDetail.cs create mode 100644 Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/AttemptContainerDetail.cs create mode 100644 Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/AttemptDetail.cs create mode 100644 Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/BatchJobStateChangeEvent.cs create mode 100644 Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/ContainerDetail.cs create mode 100644 Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/Host.cs create mode 100644 Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/Job.cs create mode 100644 Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/JobDependency.cs create mode 100644 Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/JobTimeout.cs create mode 100644 Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/MountPoint.cs create mode 100644 Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/RetryStrategy.cs create mode 100644 Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/Ulimit.cs create mode 100644 Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/Volume.cs create mode 100644 Libraries/test/EventsTests/batch-job-state-change-event.json diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/Amazon.Lambda.CloudWatchEvents.csproj b/Libraries/src/Amazon.Lambda.CloudWatchEvents/Amazon.Lambda.CloudWatchEvents.csproj index d60a4a60f..cdb29dddc 100644 --- a/Libraries/src/Amazon.Lambda.CloudWatchEvents/Amazon.Lambda.CloudWatchEvents.csproj +++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/Amazon.Lambda.CloudWatchEvents.csproj @@ -17,4 +17,10 @@ + + + ..\..\..\..\..\Program Files\dotnet\sdk\NuGetFallbackFolder\newtonsoft.json\10.0.1\lib\netstandard1.3\Newtonsoft.Json.dll + + + diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/ArrayPropertiesDetail.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/ArrayPropertiesDetail.cs new file mode 100644 index 000000000..73b5bd4be --- /dev/null +++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/ArrayPropertiesDetail.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; + +namespace Amazon.Lambda.CloudWatchEvents.BatchEvents +{ + /// + /// An object representing the array properties of a job. + /// https://docs.aws.amazon.com/batch/latest/APIReference/API_ArrayPropertiesDetail.html + /// + public class ArrayPropertiesDetail + { + /// + /// The job index within the array that is associated with this job. + /// This parameter is returned for array job children. + /// + public int Index { get; set; } + + /// + /// The size of the array job. This parameter is returned for parent array jobs. + /// + public int Size { get; set; } + + /// + /// A summary of the number of array job children in each available job status. + /// This parameter is returned for parent array jobs. + /// + public Dictionary StatusSummary { get; set; } + } +} \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/AttemptContainerDetail.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/AttemptContainerDetail.cs new file mode 100644 index 000000000..577887a5f --- /dev/null +++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/AttemptContainerDetail.cs @@ -0,0 +1,38 @@ +namespace Amazon.Lambda.CloudWatchEvents.BatchEvents +{ + /// + /// An object representing the details of a container that is part of a job attempt. + /// https://docs.aws.amazon.com/batch/latest/APIReference/API_AttemptContainerDetail.html + /// + public class AttemptContainerDetail + { + /// + /// The Amazon Resource Name (ARN) of the Amazon ECS container instance that hosts the job attempt. + /// + public string ContainerInstanceArn { get; set; } + + /// + /// The exit code for the job attempt. A non-zero exit code is considered a failure. + /// + public int ExitCode { get; set; } + + /// + /// The name of the CloudWatch Logs log stream associated with the container. The log group for + /// AWS Batch jobs is /aws/batch/job. Each container attempt receives a log stream name when + /// they reach the RUNNING status. + /// + public string LogStreamName { get; set; } + + /// + /// A short (255 max characters) human-readable string to provide additional + /// details about a running or stopped container. + /// + public string Reason { get; set; } + + /// + /// The Amazon Resource Name (ARN) of the Amazon ECS task that is associated with the job attempt. + /// Each container attempt receives a task ARN when they reach the STARTING status. + /// + public string TaskArn { get; set; } + } +} \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/AttemptDetail.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/AttemptDetail.cs new file mode 100644 index 000000000..830ad0c1d --- /dev/null +++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/AttemptDetail.cs @@ -0,0 +1,31 @@ +namespace Amazon.Lambda.CloudWatchEvents.BatchEvents +{ + /// + /// An object representing a job attempt. + /// https://docs.aws.amazon.com/batch/latest/APIReference/API_AttemptDetail.html + /// + public class AttemptDetail + { + /// + /// Details about the container in this job attempt. + /// + public AttemptContainerDetail Container { get; set; } + + /// + /// The Unix time stamp (in seconds and milliseconds) for when the attempt was started + /// (when the attempt transitioned from the STARTING state to the RUNNING state). + /// + public long StartedAt { get; set; } + + /// + /// A short, human-readable string to provide additional details about the current status of the job attempt. + /// + public string StatusReason { get; set; } + + /// + /// The Unix time stamp (in seconds and milliseconds) for when the attempt was stopped + /// (when the attempt transitioned from the RUNNING state to a terminal state, such as SUCCEEDED or FAILED). + /// + public long StoppedAt { get; set; } + } +} \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/BatchJobStateChangeEvent.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/BatchJobStateChangeEvent.cs new file mode 100644 index 000000000..0f1f28f1a --- /dev/null +++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/BatchJobStateChangeEvent.cs @@ -0,0 +1,11 @@ +namespace Amazon.Lambda.CloudWatchEvents.BatchEvents +{ + /// + /// AWS Batch Event + /// https://docs.aws.amazon.com/batch/latest/userguide/batch_cwe_events.html + /// + public class BatchJobStateChangeEvent : CloudWatchEvent + { + + } +} \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/ContainerDetail.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/ContainerDetail.cs new file mode 100644 index 000000000..51b5266fb --- /dev/null +++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/ContainerDetail.cs @@ -0,0 +1,103 @@ +using System.Collections.Generic; + +namespace Amazon.Lambda.CloudWatchEvents.BatchEvents +{ + /// + /// An object representing the details of a container that is part of a job. + /// https://docs.aws.amazon.com/batch/latest/APIReference/API_ContainerDetail.html + /// + public class ContainerDetail + { + /// + /// The command that is passed to the container. + /// + public List Command { get; set; } + + /// + /// The Amazon Resource Name (ARN) of the container instance on which the container is running. + /// + public string ContainerInstanceArn { get; set; } + + /// + /// The environment variables to pass to a container. + /// Note: Environment variables must not start with AWS_BATCH; this naming convention is reserved + /// for variables that are set by the AWS Batch service. + /// + public List> Environment { get; set; } + + /// + /// The exit code to return upon completion. + /// + public int ExitCode { get; set; } + + /// + /// The image used to start the container. + /// + public string Image { get; set; } + + /// + /// The Amazon Resource Name (ARN) associated with the job upon execution. + /// + public string JobRoleArn { get; set; } + + /// + /// The name of the CloudWatch Logs log stream associated with the container. + /// The log group for AWS Batch jobs is /aws/batch/job. Each container attempt receives a + /// log stream name when they reach the RUNNING status. + /// + public string LogStreamName { get; set; } + + /// + /// The number of MiB of memory reserved for the job. + /// + public int Memory { get; set; } + + /// + /// The mount points for data volumes in your container. + /// + public List MountPoints { get; set; } + + /// + /// When this parameter is true, the container is given elevated privileges on the + /// host container instance (similar to the root user). + /// + public bool Privileged { get; set; } + + /// + /// When this parameter is true, the container is given read-only access to its root file system. + /// + public bool ReadonlyRootFilesystem { get; set; } + + /// + /// A short (255 max characters) human-readable string to provide additional + /// details about a running or stopped container. + /// + public string Reason { get; set; } + + /// + /// The Amazon Resource Name (ARN) of the Amazon ECS task that is associated with the container job. + /// Each container attempt receives a task ARN when they reach the STARTING status. + /// + public string TaskArn { get; set; } + + /// + /// A list of ulimit values to set in the container. + /// + public List Ulimits { get; set; } + + /// + /// The user name to use inside the container. + /// + public string User { get; set; } + + /// + /// The number of VCPUs allocated for the job. + /// + public int Vcpus { get; set; } + + /// + /// A list of volumes associated with the job. + /// + public List Volumes { get; set; } + } +} \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/Host.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/Host.cs new file mode 100644 index 000000000..e2f5cb8aa --- /dev/null +++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/Host.cs @@ -0,0 +1,21 @@ +namespace Amazon.Lambda.CloudWatchEvents.BatchEvents +{ + /// + /// The contents of the host parameter determine whether your data volume persists on the host container + /// instance and where it is stored. If the host parameter is empty, then the Docker daemon assigns a host + /// path for your data volume, but the data is not guaranteed to persist after the containers associated with + /// it stop running. + /// https://docs.aws.amazon.com/batch/latest/APIReference/API_Host.html + /// + public class Host + { + /// + /// The path on the host container instance that is presented to the container. If this parameter is empty, + /// then the Docker daemon has assigned a host path for you. If the host parameter contains a sourcePath file + /// location, then the data volume persists at the specified location on the host container instance until you + /// delete it manually. If the sourcePath value does not exist on the host container instance, the Docker + /// daemon creates it. If the location does exist, the contents of the source path folder are exported. + /// + public string SourcePath { get; set; } + } +} \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/Job.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/Job.cs new file mode 100644 index 000000000..58af443bc --- /dev/null +++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/Job.cs @@ -0,0 +1,99 @@ +using System.Collections.Generic; + +namespace Amazon.Lambda.CloudWatchEvents.BatchEvents +{ + /// + /// https://docs.aws.amazon.com/batch/latest/userguide/batch_cwe_events.html + /// https://docs.aws.amazon.com/batch/latest/APIReference/API_JobDetail.html + /// https://docs.aws.amazon.com/batch/latest/APIReference/API_DescribeJobs.html + /// + public class Job + { + /// + /// The array properties of the job, if it is an array job. + /// + public ArrayPropertiesDetail ArrayProperties { get; set; } + + /// + /// A list of job attempts associated with this job. + /// + public List Attempts { get; set; } + + /// + /// An object representing the details of the container that is associated with the job. + /// + public ContainerDetail Container { get; set; } + + /// + /// The Unix time stamp (in seconds and milliseconds) for when the job was created. For non-array + /// jobs and parent array jobs, this is when the job entered the SUBMITTED state + /// (at the time SubmitJob was called). For array child jobs, this is when the child job was + /// spawned by its parent and entered the PENDING state. + /// + public long CreatedAt { get; set; } + + /// + /// A list of job names or IDs on which this job depends. + /// + public List DependsOn { get; set; } + + /// + /// The job definition that is used by this job. + /// + public string JobDefinition { get; set; } + + /// + /// The ID for the job. + /// + public string JobId { get; set; } + + /// + /// The name of the job. + /// + public string JobName { get; set; } + + /// + /// The Amazon Resource Name (ARN) of the job queue with which the job is associated. + /// + public string JobQueue { get; set; } + + /// + /// Additional parameters passed to the job that replace parameter substitution placeholders or + /// override any corresponding parameter defaults from the job definition. + /// + public Dictionary Parameters { get; set; } + + /// + /// The retry strategy to use for this job if an attempt fails. + /// + public RetryStrategy RetryStrategy { get; set; } + + /// + /// The Unix time stamp (in seconds and milliseconds) for when the job was started (when the job + /// transitioned from the STARTING state to the RUNNING state). + /// + public long StartedAt { get; set; } + + /// + /// The current status for the job. Note: If your jobs do not progress to STARTING, see Jobs Stuck + /// in RUNNABLE Status in the troubleshooting section of the AWS Batch User Guide. + /// + public string Status { get; set; } + + /// + /// A short, human-readable string to provide additional details about the current status of the job. + /// + public string StatusReason { get; set; } + + /// + /// The Unix time stamp (in seconds and milliseconds) for when the job was stopped (when the + /// job transitioned from the RUNNING state to a terminal state, such as SUCCEEDED or FAILED). + /// + public long StoppedAt { get; set; } + + /// + /// The timeout configuration for the job. + /// + public JobTimeout Timeout { get; set; } + } +} \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/JobDependency.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/JobDependency.cs new file mode 100644 index 000000000..68ed49ff5 --- /dev/null +++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/JobDependency.cs @@ -0,0 +1,19 @@ +namespace Amazon.Lambda.CloudWatchEvents.BatchEvents +{ + /// + /// An object representing an AWS Batch job dependency. + /// https://docs.aws.amazon.com/batch/latest/APIReference/API_JobDependency.html + /// + public class JobDependency + { + /// + /// The job ID of the AWS Batch job associated with this dependency. + /// + public string JobId { get; set; } + + /// + /// The type of the job dependency. + /// + public string Type { get; set; } + } +} \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/JobTimeout.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/JobTimeout.cs new file mode 100644 index 000000000..98940e845 --- /dev/null +++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/JobTimeout.cs @@ -0,0 +1,15 @@ +namespace Amazon.Lambda.CloudWatchEvents.BatchEvents +{ + /// + /// An object representing a job timeout configuration. + /// https://docs.aws.amazon.com/batch/latest/APIReference/API_JobTimeout.html + /// + public class JobTimeout + { + /// + /// The time duration in seconds (measured from the job attempt's startedAt timestamp) after which + /// AWS Batch terminates your jobs if they have not finished. + /// + public int AttemptDurationSeconds { get; set; } + } +} \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/MountPoint.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/MountPoint.cs new file mode 100644 index 000000000..558734087 --- /dev/null +++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/MountPoint.cs @@ -0,0 +1,25 @@ +namespace Amazon.Lambda.CloudWatchEvents.BatchEvents +{ + /// + /// Details on a Docker volume mount point that is used in a job's container properties. + /// https://docs.aws.amazon.com/batch/latest/APIReference/API_MountPoint.html + /// + public class MountPoint + { + /// + /// The path on the container at which to mount the host volume. + /// + public string ContainerPath { get; set; } + + /// + /// If this value is true, the container has read-only access to the volume; otherwise, + /// the container can write to the volume. The default value is false. + /// + public bool ReadOnly { get; set; } + + /// + /// The name of the volume to mount. + /// + public string SourceVolume { get; set; } + } +} \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/RetryStrategy.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/RetryStrategy.cs new file mode 100644 index 000000000..4febf1fd6 --- /dev/null +++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/RetryStrategy.cs @@ -0,0 +1,16 @@ +namespace Amazon.Lambda.CloudWatchEvents.BatchEvents +{ + /// + /// The retry strategy associated with a job. + /// https://docs.aws.amazon.com/batch/latest/APIReference/API_RetryStrategy.html + /// + public class RetryStrategy + { + /// + /// The number of times to move a job to the RUNNABLE status. You may specify between 1 and 10 attempts. + /// If the value of attempts is greater than one, the job is retried if it fails until it has moved to + /// RUNNABLE that many times. + /// + public int Attempts { get; set; } + } +} \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/Ulimit.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/Ulimit.cs new file mode 100644 index 000000000..a6e54c148 --- /dev/null +++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/Ulimit.cs @@ -0,0 +1,24 @@ +namespace Amazon.Lambda.CloudWatchEvents.BatchEvents +{ + /// + /// The ulimit settings to pass to the container. + /// https://docs.aws.amazon.com/batch/latest/APIReference/API_Ulimit.html + /// + public class Ulimit + { + /// + /// The hard limit for the ulimit type. + /// + public int HardLimit { get; set; } + + /// + /// The type of the ulimit. + /// + public string Name { get; set; } + + /// + /// The soft limit for the ulimit type. + /// + public int SoftLimit { get; set; } + } +} \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/Volume.cs b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/Volume.cs new file mode 100644 index 000000000..686d41be0 --- /dev/null +++ b/Libraries/src/Amazon.Lambda.CloudWatchEvents/BatchEvents/Volume.cs @@ -0,0 +1,23 @@ +namespace Amazon.Lambda.CloudWatchEvents.BatchEvents +{ + /// + /// A data volume used in a job's container properties. + /// https://docs.aws.amazon.com/batch/latest/APIReference/API_Volume.html + /// + public class Volume + { + /// + /// The contents of the host parameter determine whether your data volume persists on the host container + /// instance and where it is stored. If the host parameter is empty, then the Docker daemon assigns a host + /// path for your data volume. However, the data is not guaranteed to persist after the containers associated + /// with it stop running. + /// + public Host Host { get; set; } + + /// + /// The name of the volume. Up to 255 letters (uppercase and lowercase), numbers, hyphens, and underscores are + /// allowed. This name is referenced in the sourceVolume parameter of container definition mountPoints. + /// + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/Libraries/test/EventsTests/EventTests.cs b/Libraries/test/EventsTests/EventTests.cs index 36b7a7ef8..966acfb9f 100644 --- a/Libraries/test/EventsTests/EventTests.cs +++ b/Libraries/test/EventsTests/EventTests.cs @@ -14,6 +14,7 @@ namespace Amazon.Lambda.Tests using Amazon.Lambda.LexEvents; using Amazon.Lambda.KinesisFirehoseEvents; using Amazon.Lambda.KinesisAnalyticsEvents; + using Amazon.Lambda.CloudWatchEvents.BatchEvents; using Newtonsoft.Json.Linq; @@ -27,7 +28,7 @@ namespace Amazon.Lambda.Tests using Newtonsoft.Json; using JsonSerializer = Amazon.Lambda.Serialization.Json.JsonSerializer; - + public class EventTest { [Fact] @@ -781,5 +782,52 @@ private string MemoryStreamToBase64String(MemoryStream ms) var data = ms.ToArray(); return Convert.ToBase64String(data); } + + [Fact] + public void BatchJobStateChangeEventTest() + { + using (var fileStream = File.OpenRead("batch-job-state-change-event.json")) + { + var serializer = new JsonSerializer(); + var jobStateChangeEvent = serializer.Deserialize(fileStream); + + Assert.Equal(jobStateChangeEvent.Version, "0"); + Assert.Equal(jobStateChangeEvent.Id, "c8f9c4b5-76e5-d76a-f980-7011e206042b"); + Assert.Equal(jobStateChangeEvent.DetailType, "Batch Job State Change"); + Assert.Equal(jobStateChangeEvent.Source, "aws.batch"); + Assert.Equal(jobStateChangeEvent.Account, "aws_account_id"); + Assert.Equal(jobStateChangeEvent.Time.ToUniversalTime(), DateTime.Parse("2017-10-23T17:56:03Z").ToUniversalTime()); + Assert.Equal(jobStateChangeEvent.Region, "us-east-1"); + Assert.Equal(jobStateChangeEvent.Resources.Count, 1); + Assert.Equal(jobStateChangeEvent.Resources[0], "arn:aws:batch:us-east-1:aws_account_id:job/4c7599ae-0a82-49aa-ba5a-4727fcce14a8"); + Assert.IsType(typeof(Job), jobStateChangeEvent.Detail); + Assert.Equal(jobStateChangeEvent.Detail.JobName, "event-test"); + Assert.Equal(jobStateChangeEvent.Detail.JobId, "4c7599ae-0a82-49aa-ba5a-4727fcce14a8"); + Assert.Equal(jobStateChangeEvent.Detail.JobQueue, "arn:aws:batch:us-east-1:aws_account_id:job-queue/HighPriority"); + Assert.Equal(jobStateChangeEvent.Detail.Status, "RUNNABLE"); + Assert.Equal(jobStateChangeEvent.Detail.Attempts.Count, 0); + Assert.Equal(jobStateChangeEvent.Detail.CreatedAt, 1508781340401); + Assert.Equal(jobStateChangeEvent.Detail.RetryStrategy.Attempts, 1); + Assert.Equal(jobStateChangeEvent.Detail.DependsOn.Count, 0); + Assert.Equal(jobStateChangeEvent.Detail.JobDefinition, "arn:aws:batch:us-east-1:aws_account_id:job-definition/first-run-job-definition:1"); + Assert.Equal(jobStateChangeEvent.Detail.Parameters.Count, 0); + Assert.Equal(jobStateChangeEvent.Detail.Container.Image, "busybox"); + Assert.Equal(jobStateChangeEvent.Detail.Container.Vcpus, 2); + Assert.Equal(jobStateChangeEvent.Detail.Container.Memory, 2000); + Assert.Equal(jobStateChangeEvent.Detail.Container.Command.Count, 2); + Assert.Equal(jobStateChangeEvent.Detail.Container.Command[0], "echo"); + Assert.Equal(jobStateChangeEvent.Detail.Container.Volumes.Count, 0); + Assert.Equal(jobStateChangeEvent.Detail.Container.Environment.Count, 0); + Assert.Equal(jobStateChangeEvent.Detail.Container.MountPoints.Count, 0); + Assert.Equal(jobStateChangeEvent.Detail.Container.Ulimits.Count, 0); + + Handle(jobStateChangeEvent); + } + } + + private void Handle(BatchJobStateChangeEvent jobStateChangeEvent) + { + Console.WriteLine($"[{jobStateChangeEvent.Source} {jobStateChangeEvent.Time}] {jobStateChangeEvent.DetailType}"); + } } } diff --git a/Libraries/test/EventsTests/EventsTests.csproj b/Libraries/test/EventsTests/EventsTests.csproj index 15fe53575..06c53d6a5 100644 --- a/Libraries/test/EventsTests/EventsTests.csproj +++ b/Libraries/test/EventsTests/EventsTests.csproj @@ -23,6 +23,7 @@ + diff --git a/Libraries/test/EventsTests/batch-job-state-change-event.json b/Libraries/test/EventsTests/batch-job-state-change-event.json new file mode 100644 index 000000000..a480d8c9a --- /dev/null +++ b/Libraries/test/EventsTests/batch-job-state-change-event.json @@ -0,0 +1,39 @@ +{ + "version": "0", + "id": "c8f9c4b5-76e5-d76a-f980-7011e206042b", + "detail-type": "Batch Job State Change", + "source": "aws.batch", + "account": "aws_account_id", + "time": "2017-10-23T17:56:03Z", + "region": "us-east-1", + "resources": [ + "arn:aws:batch:us-east-1:aws_account_id:job/4c7599ae-0a82-49aa-ba5a-4727fcce14a8" + ], + "detail": { + "jobName": "event-test", + "jobId": "4c7599ae-0a82-49aa-ba5a-4727fcce14a8", + "jobQueue": "arn:aws:batch:us-east-1:aws_account_id:job-queue/HighPriority", + "status": "RUNNABLE", + "attempts": [], + "createdAt": 1508781340401, + "retryStrategy": { + "attempts": 1 + }, + "dependsOn": [], + "jobDefinition": "arn:aws:batch:us-east-1:aws_account_id:job-definition/first-run-job-definition:1", + "parameters": {}, + "container": { + "image": "busybox", + "vcpus": 2, + "memory": 2000, + "command": [ + "echo", + "'hello world'" + ], + "volumes": [], + "environment": [], + "mountPoints": [], + "ulimits": [] + } + } +} \ No newline at end of file