using System; using System.Linq; using System.Collections.Generic; using System.Globalization; using Amazon.Runtime; using ThirdParty.Json.LitJson; namespace Amazon.S3.Util { /// /// A helper class that represents a strongly typed S3 EventNotification item sent to SQS /// public class S3EventNotification { /// /// Parse the JSON string into a S3EventNotification object. /// /// The function will try its best to parse input JSON string as best as it can. /// It will not fail even if the JSON string contains unknown properties. /// /// For any parsing errors /// public static S3EventNotification ParseJson(string json) { try { var data = JsonMapper.ToObject(json); var s3Event = new S3EventNotification { Records = new List() }; if (data["Records"] != null) { foreach (JsonData jsonRecord in data["Records"]) { var record = new S3EventNotificationRecord(); record.EventVersion = GetValueAsString(jsonRecord, "eventVersion"); record.EventSource = GetValueAsString(jsonRecord, "eventSource"); record.AwsRegion = GetValueAsString(jsonRecord, "awsRegion"); record.EventVersion = GetValueAsString(jsonRecord, "eventVersion"); if (jsonRecord["eventTime"] != null) record.EventTime = DateTime.Parse((string)jsonRecord["eventTime"], CultureInfo.InvariantCulture); if (jsonRecord["eventName"] != null) { var eventName = (string)jsonRecord["eventName"]; if (!eventName.StartsWith("s3:", StringComparison.OrdinalIgnoreCase)) eventName = "s3:" + eventName; record.EventName = EventType.FindValue(eventName); } if (jsonRecord["userIdentity"] != null) { var jsonUserIdentity = jsonRecord["userIdentity"]; record.UserIdentity = new UserIdentityEntity(); record.UserIdentity.PrincipalId = GetValueAsString(jsonUserIdentity, "principalId"); } if (jsonRecord["requestParameters"] != null) { var jsonRequestParameters = jsonRecord["requestParameters"]; record.RequestParameters = new RequestParametersEntity(); record.RequestParameters.SourceIPAddress = GetValueAsString(jsonRequestParameters, "sourceIPAddress"); } if (jsonRecord["responseElements"] != null) { var jsonResponseElements = jsonRecord["responseElements"]; record.ResponseElements = new ResponseElementsEntity(); record.ResponseElements.XAmzRequestId = GetValueAsString(jsonResponseElements, "x-amz-request-id"); record.ResponseElements.XAmzId2 = GetValueAsString(jsonResponseElements, "x-amz-id-2"); } if (jsonRecord["s3"] != null) { var jsonS3 = jsonRecord["s3"]; record.S3 = new S3Entity(); record.S3.S3SchemaVersion = GetValueAsString(jsonS3, "s3SchemaVersion"); record.S3.ConfigurationId = GetValueAsString(jsonS3, "configurationId"); if (jsonS3["bucket"] != null) { var jsonBucket = jsonS3["bucket"]; record.S3.Bucket = new S3BucketEntity(); record.S3.Bucket.Name = GetValueAsString(jsonBucket, "name"); record.S3.Bucket.Arn = GetValueAsString(jsonBucket, "arn"); if (jsonBucket["ownerIdentity"] != null) { var jsonOwnerIdentity = jsonBucket["ownerIdentity"]; record.S3.Bucket.OwnerIdentity = new UserIdentityEntity(); record.S3.Bucket.OwnerIdentity.PrincipalId = GetValueAsString(jsonOwnerIdentity, "principalId"); } } if (jsonS3["object"] != null) { var jsonObject = jsonS3["object"]; record.S3.Object = new S3ObjectEntity(); record.S3.Object.Key = GetValueAsString(jsonObject, "key"); record.S3.Object.Size = GetValueAsLong(jsonObject, "size"); record.S3.Object.ETag = GetValueAsString(jsonObject, "eTag"); record.S3.Object.VersionId = GetValueAsString(jsonObject, "versionId"); record.S3.Object.Sequencer = GetValueAsString(jsonObject, "sequencer"); } } if(jsonRecord["glacierEventData"] != null) { var jsonGlacier = jsonRecord["glacierEventData"]; record.GlacierEventData = new S3GlacierEventDataEntity(); if(jsonGlacier["restoreEventData"] != null) { var jsonRestore = jsonGlacier["restoreEventData"]; record.GlacierEventData.RestoreEventData = new S3RestoreEventDataEntity(); record.GlacierEventData.RestoreEventData.LifecycleRestorationExpiryTime = GetValueAsDateTime(jsonRestore, "lifecycleRestorationExpiryTime").GetValueOrDefault(); record.GlacierEventData.RestoreEventData.LifecycleRestoreStorageClass = GetValueAsString(jsonRestore, "lifecycleRestoreStorageClass"); } } s3Event.Records.Add(record); } } return s3Event; } catch(Exception e) { throw new AmazonClientException("Failed to parse json string: " + e.Message, e); } } /// /// Gets and sets the records for the S3 event notification /// public List Records {get;set;} /// /// The class holds the user identity properties. /// public class UserIdentityEntity { /// /// Gets and sets the PrincipalId property. /// public string PrincipalId { get; set; } } /// /// This class contains the identity information for an S3 bucket. /// public class S3BucketEntity { /// /// Gets and sets the name of the bucket. /// public string Name {get; set;} /// /// Gets and sets the bucket owner id. /// public UserIdentityEntity OwnerIdentity {get; set;} /// /// Gets and sets the S3 bucket arn. /// public string Arn {get; set;} } /// /// This class contains the information for an object in S3. /// public class S3ObjectEntity { /// /// Gets and sets the key for the object stored in S3. /// public string Key { get; set; } /// /// Gets and sets the size of the object in S3. /// public long Size { get; set; } /// /// Gets and sets the etag of the object. This can be used to determine if the object has changed. /// public string ETag { get; set; } /// /// Gets and sets the version id of the object in S3. /// public string VersionId { get; set; } /// /// Gets and sets the sequencer a string representation of a hexadecimal value used to determine event sequence, only used with PUTs and DELETEs. /// public string Sequencer { get; set; } } /// /// Gets and sets the meta information describing S3. /// public class S3Entity { /// /// Gets and sets the ConfigurationId. This ID can be found in the bucket notification configuration. /// public string ConfigurationId {get;set;} /// /// Gets and sets the Bucket property. /// public S3BucketEntity Bucket {get;set;} /// /// Gets and sets the Object property. /// public S3ObjectEntity Object { get; set; } /// /// Gets and sets the S3SchemaVersion property. /// public string S3SchemaVersion { get; set; } } /// /// The class holds the request parameters /// public class RequestParametersEntity { /// /// Gets and sets the SourceIPAddress. This is the ip address where the request came from. /// public string SourceIPAddress {get;set;} } /// /// This class holds the response elements. /// public class ResponseElementsEntity { /// /// Gets and sets the XAmzId2 Property. This is the Amazon S3 host that processed the request. /// public string XAmzId2 {get;set;} /// /// Gets and sets the XAmzRequestId. This is the Amazon S3 generated request ID. /// public string XAmzRequestId {get;set;} } /// /// The class holds the glacier event data elements. /// public class S3GlacierEventDataEntity { /// /// Gets and sets the RestoreEventData property. /// public S3RestoreEventDataEntity RestoreEventData { get; set; } } /// /// The class holds the restore event data elements. /// public class S3RestoreEventDataEntity { /// /// Gets and sets the LifecycleRestorationExpiryTime the time when the object restoration will be expired. /// public DateTime LifecycleRestorationExpiryTime { get; set; } /// /// Gets and sets the LifecycleRestoreStorageClass the source storage class for restore. /// public string LifecycleRestoreStorageClass { get; set; } } /// /// The class holds the event notification. /// public class S3EventNotificationRecord { /// /// Gets and sets the AwsRegion property. /// public string AwsRegion {get;set;} /// /// Gets and sets the EventName property. This identities what type of event occurred. /// For example for an object just put in S3 this will be set to EventType.ObjectCreatedPut. /// public EventType EventName { get; set; } /// /// Gets and sets the EventSource property. /// public string EventSource {get;set;} /// /// Gets and sets the EventType property. The time when S3 finished processing the request. /// public DateTime EventTime {get;set;} /// /// Gets and sets the EventVersion property. /// public string EventVersion {get;set;} /// /// Gets and sets the RequestParameters property. /// public RequestParametersEntity RequestParameters { get; set; } /// /// Gets and sets the ResponseElements property. /// public ResponseElementsEntity ResponseElements { get; set; } /// /// Gets and sets the S3 property. /// public S3Entity S3 { get; set; } /// /// Gets and sets the UserIdentity property. /// public UserIdentityEntity UserIdentity { get; set; } /// /// Get and sets the GlacierEventData property. /// public S3GlacierEventDataEntity GlacierEventData { get; set; } } private static string GetValueAsString(JsonData data, string key) { if (data[key] != null) return (string)data[key]; return null; } private static DateTime? GetValueAsDateTime(JsonData data, string key) { var str = GetValueAsString(data, key); if (string.IsNullOrEmpty(str)) return null; return DateTime.Parse(str, CultureInfo.InvariantCulture); } private static long GetValueAsLong(JsonData data, string key) { if (data[key] != null) { if (data[key].IsInt) return (int)data[key]; else return (long)data[key]; } return 0; } } }