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;
}
}
}