/// <summary> /// The create log document. /// </summary> /// <param name="logEvent"> /// The log event. /// </param> /// <returns> /// The <see cref="Document"/>. /// </returns> private Document CreateLogDocument(LogEventInfo logEvent) { var log = new Document(); log["Id"] = logEvent.SequenceID; log["TimeStamp"] = logEvent.TimeStamp; log["Level"] = logEvent.Level.ToString(); log["Message"] = logEvent.Message; log["UserStackFrameNumber"] = logEvent.UserStackFrameNumber; if (logEvent.UserStackFrame != null) { log["FileName"] = logEvent.UserStackFrame.GetFileName(); log["FileLineNumber"] = logEvent.UserStackFrame.GetFileLineNumber(); log["FileColumnNumber"] = logEvent.UserStackFrame.GetFileColumnNumber(); log["MethodName"] = logEvent.UserStackFrame.GetMethod().Name; } if (logEvent.Exception != null) { log["ExceptionMessage"] = logEvent.Exception.Message; log["ExceptionHResult"] = logEvent.Exception.HResult; log["ExceptionStackTrace"] = logEvent.Exception.StackTrace; log["ExceptionSource"] = logEvent.Exception.Source; } log["UserEmail"] = logEvent.Properties["UserEmail"].ToString(); log["OrderId"] = logEvent.Properties["OrderId"].ToString(); log["PackageId"] = logEvent.Properties["PackageId"].ToString(); log["TransactionId"] = logEvent.Properties["TransactionId"].ToString(); return log; }
/// <summary> /// Releases a lock on an item in the session data store. /// </summary> /// <param name="context">The HttpContext for the current request.</param> /// <param name="sessionId">The session identifier for the current request.</param> /// <param name="lockId">The lock identifier for the current request.</param> public override void ReleaseItemExclusive(HttpContext context, string sessionId, object lockId) { Document doc = this._table.GetItem(GetHashKey(sessionId)); doc[ATTRIBUTE_LOCKED] = false; doc[ATTRIBUTE_EXPIRES] = DateTime.Now.Add(this._timeout); Document expected = new Document(); expected[ATTRIBUTE_LOCK_ID] = lockId.ToString(); try { this._table.UpdateItem(doc, new UpdateItemOperationConfig() { Expected = expected }); } catch (ConditionalCheckFailedException) { } }
internal Document PutItemHelper(Document doc, PutItemOperationConfig config, bool isAsync) { var currentConfig = config ?? new PutItemOperationConfig(); PutItemRequest req = new PutItemRequest { TableName = TableName, Item = doc.ToAttributeMap() }; req.BeforeRequestEvent += isAsync ? new RequestEventHandler(UserAgentRequestEventHandlerAsync) : new RequestEventHandler(UserAgentRequestEventHandlerSync); if (currentConfig.Expected != null) req.Expected = currentConfig.Expected.ToExpectedAttributeMap(); if (currentConfig.ReturnValues == ReturnValues.AllOldAttributes) { req.ReturnValues = EnumToStringMapper.Convert(currentConfig.ReturnValues); } var resp = DDBClient.PutItem(req); doc.CommitChanges(); Document ret = null; if (currentConfig.ReturnValues == ReturnValues.AllOldAttributes) { ret = Document.FromAttributeMap(resp.PutItemResult.Attributes); } return ret; }
/// <summary> /// Update a document in DynamoDB, with a hash-and-range primary key to identify /// the document, and using the specified config. /// </summary> /// <param name="doc">Attributes to update.</param> /// <param name="hashKey">Hash key element of the document.</param> /// <param name="rangeKey">Range key element of the document.</param> /// <param name="config">Configuration to use.</param> /// <returns>Null or updated attributes, depending on config.</returns> /// <seealso cref="Amazon.DynamoDB.DocumentModel.UpdateItemOperationConfig"/> public Document UpdateItem(Document doc, Primitive hashKey, Primitive rangeKey, UpdateItemOperationConfig config) { return UpdateHelper(doc, MakeKey(hashKey, rangeKey), config, false); }
/// <summary> /// Update a document in DynamoDB, with a hash-and-range primary key /// to identify the document. /// </summary> /// <param name="doc">Attributes to update.</param> /// <param name="hashKey">Hash key element of the document.</param> /// <param name="rangeKey">Range key element of the document.</param> public void UpdateItem(Document doc, Primitive hashKey, Primitive rangeKey) { UpdateHelper(doc, MakeKey(hashKey, rangeKey), null, false); }
/// <summary> /// Puts a document into DynamoDB, using specified configs. /// </summary> /// <param name="doc">Document to save.</param> /// <param name="config">Configuration to use.</param> /// <returns>Null or updated attributes, depending on config.</returns> public Document PutItem(Document doc, PutItemOperationConfig config) { return PutItemHelper(doc, config, false); }
/// <summary> /// Delete a document in DynamoDB, using specified configs. /// </summary> /// <param name="document">Document to delete.</param> /// <param name="config">Configuration to use.</param> /// <returns>Null or old attributes, depending on config.</returns> public Document DeleteItem(Document document, DeleteItemOperationConfig config) { return DeleteHelper(MakeKey(document), config, false); }
/// <summary> /// Initiates the asynchronous execution of the UpdateItem operation. /// <seealso cref="Amazon.DynamoDB.DocumentModel.Table.UpdateItem"/> /// </summary> /// <param name="doc">Attributes to update.</param> /// <param name="hashKey">Hash key element of the document.</param> /// <param name="rangeKey">Range key element of the document.</param> /// <param name="config">Configuration to use.</param> /// <param name="callback">An AsyncCallback delegate that is invoked when the operation completes.</param> /// <param name="state">A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback /// procedure using the AsyncState property.</param> /// <returns>An IAsyncResult that can be used to poll or wait for results, or both; this value is also needed when invoking EndUpdateItem /// operation.</returns> public IAsyncResult BeginUpdateItem(Document doc, Primitive hashKey, Primitive rangeKey, UpdateItemOperationConfig config, AsyncCallback callback, object state) { return DynamoDBAsyncExecutor.BeginOperation(() => UpdateHelper(doc, MakeKey(hashKey, rangeKey), config, true), callback, state); }
/// <summary> /// Update a document in DynamoDB, with hash primary key to identify the document. /// </summary> /// <param name="doc">Attributes to update.</param> /// <param name="hashKey">Hash key element of the document.</param> public void UpdateItem(Document doc, Primitive hashKey) { UpdateHelper(doc, MakeKey(hashKey,null), null); }
internal void AddKey(Document document) { Keys.Add(TargetTable.MakeKey(document)); }
/// <summary> /// Get the session for DynamoDB and optionally lock the record. /// </summary> /// <param name="lockRecord"></param> /// <param name="context"></param> /// <param name="sessionId"></param> /// <param name="locked"></param> /// <param name="lockAge"></param> /// <param name="lockId"></param> /// <param name="actionFlags"></param> /// <returns></returns> private SessionStateStoreData GetSessionStoreItem(bool lockRecord, HttpContext context, string sessionId, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actionFlags) { // Initial values for return value and out parameters. SessionStateStoreData item = null; lockAge = TimeSpan.Zero; lockId = Guid.NewGuid().ToString(); locked = false; actionFlags = SessionStateActions.None; bool foundRecord = false; bool deleteData = false; DateTime newLockedDate = DateTime.Now; Document session = null; if (lockRecord) { Document lockDoc = new Document(); lockDoc[ATTRIBUTE_SESSION_ID] = GetHashKey(sessionId); lockDoc[ATTRIBUTE_LOCK_ID] = lockId.ToString(); lockDoc[ATTRIBUTE_LOCKED] = true; lockDoc[ATTRIBUTE_LOCK_DATE] = DateTime.Now; try { session = this._table.UpdateItem(lockDoc, LOCK_UPDATE_CONFIG); locked = false; } catch (ConditionalCheckFailedException) { // This means the record is already locked by another request. locked = true; } } if (session == null) { session = this._table.GetItem(GetHashKey(sessionId), CONSISTENT_READ_GET); if (session == null && lockRecord) { locked = true; } } string serializedItems = null; if (session != null) { DateTime expire = (DateTime)session[ATTRIBUTE_EXPIRES]; if (expire < DateTime.Now) { deleteData = true; locked = false; } else { foundRecord = true; DynamoDBEntry entry; if (session.TryGetValue(ATTRIBUTE_SESSION_ITEMS, out entry)) { serializedItems = (string)entry; } if (session.Contains(ATTRIBUTE_LOCK_ID)) lockId = (string)session[ATTRIBUTE_LOCK_ID]; if (session.Contains(ATTRIBUTE_FLAGS)) actionFlags = (SessionStateActions)((int)session[ATTRIBUTE_FLAGS]); if (session[ATTRIBUTE_LOCK_DATE] != null) { DateTime lockDate = (DateTime)session[ATTRIBUTE_LOCK_DATE]; lockAge = DateTime.Now.Subtract(lockDate); } } } if (deleteData) { this.deleteItem(sessionId); } // The record was not found. Ensure that locked is false. if (!foundRecord) { locked = false; lockId = null; } // If the record was found and you obtained a lock, then clear the actionFlags, // and create the SessionStateStoreItem to return. if (foundRecord && !locked) { if (actionFlags == SessionStateActions.InitializeItem) { Document updateDoc = new Document(); updateDoc[ATTRIBUTE_SESSION_ID] = GetHashKey(sessionId); updateDoc[ATTRIBUTE_FLAGS] = 0; this._table.UpdateItem(updateDoc); item = CreateNewStoreData(context, (int)this._timeout.TotalMinutes); } else { item = deserialize(context, serializedItems, (int)this._timeout.TotalMinutes); } } return item; }
private void deleteItem(string sessionId) { Document doc = new Document(); doc[ATTRIBUTE_SESSION_ID] = GetHashKey(sessionId); this._table.DeleteItem(doc); }
/// <summary> /// Updates the session-item information in the session-state data store with values from the current request, and clears the lock on the data. /// </summary> /// <param name="context">The HttpContext for the current request.</param> /// <param name="sessionId">The session identifier for the current request.</param> /// <param name="item">The SessionStateStoreData object that contains the current session values to be stored.</param> /// <param name="lockId">The lock identifier for the current request.</param> /// <param name="newItem">true to identify the session item as a new item; false to identify the session item as an existing item.</param> public override void SetAndReleaseItemExclusive(HttpContext context, string sessionId, SessionStateStoreData item, object lockId, bool newItem) { string serialized = serialize(item.Items as SessionStateItemCollection); Document newValues = new Document(); newValues[ATTRIBUTE_SESSION_ID] = GetHashKey(sessionId); newValues[ATTRIBUTE_LOCKED] = false; newValues[ATTRIBUTE_LOCK_ID] = null; newValues[ATTRIBUTE_LOCK_DATE] = DateTime.Now; newValues[ATTRIBUTE_EXPIRES] = DateTime.Now.Add(this._timeout); newValues[ATTRIBUTE_FLAGS] = 0; newValues[ATTRIBUTE_SESSION_ITEMS] = serialized; newValues[ATTRIBUTE_RECORD_FORMAT_VERSION] = CURRENT_RECORD_FORMAT_VERSION; if (newItem) { newValues[ATTRIBUTE_CREATE_DATE] = DateTime.Now; this._table.PutItem(newValues); } else { Document expected = new Document(); expected[ATTRIBUTE_LOCK_ID] = lockId.ToString(); // Not really any reason the condition should fail unless we get in some sort of weird // app pool reset mode. try { this._table.UpdateItem(newValues, new UpdateItemOperationConfig() { Expected = expected }); } catch (ConditionalCheckFailedException) { } } }
/// <summary> /// Updates the expiration date and time of an item in the DynamoDB table. /// </summary> /// <param name="context"></param> /// <param name="sessionId"></param> public override void ResetItemTimeout(HttpContext context, string sessionId) { Document doc = new Document(); doc[ATTRIBUTE_SESSION_ID] = GetHashKey(sessionId); doc[ATTRIBUTE_LOCKED] = false; doc[ATTRIBUTE_EXPIRES] = DateTime.Now.Add(this._timeout); this._table.UpdateItem(doc); }
/// <summary> /// Initiates the asynchronous execution of the PutItem operation. /// <seealso cref="Amazon.DynamoDB.DocumentModel.Table.PutItem"/> /// </summary> /// <param name="doc">Document to save.</param> /// <param name="config">Configuration to use.</param> /// <param name="callback">An AsyncCallback delegate that is invoked when the operation completes.</param> /// <param name="state">A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback /// procedure using the AsyncState property.</param> /// <returns>An IAsyncResult that can be used to poll or wait for results, or both; this value is also needed when invoking EndPutItem /// operation.</returns> public IAsyncResult BeginPutItem(Document doc, PutItemOperationConfig config, AsyncCallback callback, object state) { return DynamoDBAsyncExecutor.BeginOperation(() => PutItemHelper(doc, config, true), callback, state); }
/// <summary> /// Update a document in DynamoDB, with a hash primary key to identify the /// document, and using the specified config. /// </summary> /// <param name="doc">Attributes to update.</param> /// <param name="hashKey">Hash key element of the document.</param> /// <param name="config">Configuration to use.</param> /// <returns>Null or updated attributes, depending on config.</returns> /// <seealso cref="Amazon.DynamoDB.DocumentModel.UpdateItemOperationConfig"/> public Document UpdateItem(Document doc, Primitive hashKey, UpdateItemOperationConfig config) { return UpdateHelper(doc, MakeKey(hashKey, null), config); }
/// <summary> /// Initiates the asynchronous execution of the UpdateItem operation. /// <seealso cref="Amazon.DynamoDB.DocumentModel.Table.UpdateItem"/> /// </summary> /// <param name="doc">Document to update.</param> /// <param name="callback">An AsyncCallback delegate that is invoked when the operation completes.</param> /// <param name="state">A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback /// procedure using the AsyncState property.</param> /// <returns>An IAsyncResult that can be used to poll or wait for results, or both; this value is also needed when invoking EndUpdateItem /// operation.</returns> public IAsyncResult BeginUpdateItem(Document doc, AsyncCallback callback, object state) { return DynamoDBAsyncExecutor.BeginOperation(() => UpdateHelper(doc, MakeKey(doc), null, true), callback, state); }
private Document UpdateHelper(Document doc, Key key, UpdateItemOperationConfig config) { var currentConfig = config ?? new UpdateItemOperationConfig(); var attributeUpdates = doc.ToAttributeUpdateMap(true); foreach (var keyName in this.keyNames) { if (keyName != null) { attributeUpdates.Remove(keyName); } } UpdateItemRequest req = new UpdateItemRequest { TableName = TableName, Key = key, AttributeUpdates = attributeUpdates, ReturnValues = EnumToStringMapper.Convert(currentConfig.ReturnValues) }; req.BeforeRequestEvent += new RequestEventHandler(this.UserAgentRequestEventHandler); if (currentConfig.Expected != null) req.Expected = currentConfig.Expected.ToExpectedAttributeMap(); var resp = DDBClient.UpdateItem(req); doc.CommitChanges(); Document ret = null; if (currentConfig.ReturnValues != ReturnValues.None) { ret = Document.FromAttributeMap(resp.UpdateItemResult.Attributes); } return ret; }
/// <summary> /// Delete a document in DynamoDB. /// </summary> /// <param name="document">Document to delete.</param> public void DeleteItem(Document document) { DeleteHelper(MakeKey(document), null, false); }
internal Document(Document source) { originalValues = new Dictionary<string, DynamoDBEntry>(source.originalValues); currentValues = new Dictionary<string, DynamoDBEntry>(source.currentValues); }
/// <summary> /// Puts a document into DynamoDB. /// </summary> /// <param name="doc">Document to save.</param> public void PutItem(Document doc) { PutItem(doc, null); }
/// <summary> /// Creates a Document from an attribute map. /// </summary> /// <param name="data">Map of attribute names to attribute values.</param> /// <returns>Document representing the data.</returns> public static Document FromAttributeMap(Dictionary<string, AttributeValue> data) { Document doc = new Document(); if (data != null) { // Add Primitives and PrimitiveLists foreach (var attribute in data) { string wholeKey = attribute.Key; AttributeValue value = attribute.Value; DynamoDBEntry convertedValue = AttributeValueToDynamoDBEntry(value); if (convertedValue != null) doc.currentValues[wholeKey] = convertedValue; } } doc.CommitChanges(); return doc; }
/// <summary> /// Update a document in DynamoDB. /// </summary> /// <param name="doc">Document to update.</param> public void UpdateItem(Document doc) { UpdateHelper(doc, MakeKey(doc), null, false); }
// Checks if key attributes have been updated private bool HaveKeysChanged(Document doc) { foreach (var keyName in this.keyNames) { if (doc.IsAttributeChanged(keyName)) return true; } return false; }
/// <summary> /// Update a document in DynamoDB, using specified config. /// </summary> /// <param name="doc">Document to update.</param> /// <param name="config">Configuration to use.</param> /// <returns>Null or updated attributes, depending on config.</returns> /// <seealso cref="Amazon.DynamoDB.DocumentModel.UpdateItemOperationConfig"/> public Document UpdateItem(Document doc, UpdateItemOperationConfig config) { return UpdateHelper(doc, MakeKey(doc), config, false); }
/// <summary> /// Initiates the asynchronous execution of the DeleteItem operation. /// <seealso cref="Amazon.DynamoDB.DocumentModel.Table.DeleteItem"/> /// </summary> /// <param name="document">Document to delete.</param> /// <param name="callback">An AsyncCallback delegate that is invoked when the operation completes.</param> /// <param name="state">A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback /// procedure using the AsyncState property.</param> /// <returns>An IAsyncResult that can be used to poll or wait for results, or both; this value is also needed when invoking EndDeleteItem /// operation.</returns> public IAsyncResult BeginDeleteItem(Document document, AsyncCallback callback, object state) { return DynamoDBAsyncExecutor.BeginOperation(() => { DeleteHelper(MakeKey(document), null, true); return null; }, callback, state); }
internal Key MakeKey(Document doc) { DynamoDBEntry entry; Primitive hashKey; if (doc.TryGetValue(HashKeyName, out entry) && (entry is Primitive)) { hashKey = (entry as Primitive); } else { throw new InvalidOperationException("Document does not contain valid hash key attribute"); } Primitive rangeKey; if (!string.IsNullOrEmpty(RangeKeyName)) { if (doc.TryGetValue(RangeKeyName, out entry) && (entry is Primitive)) rangeKey = (entry as Primitive); else throw new InvalidOperationException("Document does not contain valid range key attribute"); } else { rangeKey = null; } return MakeKey(hashKey, rangeKey); }
/// <summary> /// Initiates the asynchronous execution of the DeleteItem operation. /// <seealso cref="Amazon.DynamoDB.DocumentModel.Table.DeleteItem"/> /// </summary> /// <param name="document">Document to delete.</param> /// <param name="config">Configuration to use.</param> /// <param name="callback">An AsyncCallback delegate that is invoked when the operation completes.</param> /// <param name="state">A user-defined state object that is passed to the callback procedure. Retrieve this object from within the callback /// procedure using the AsyncState property.</param> /// <returns>An IAsyncResult that can be used to poll or wait for results, or both; this value is also needed when invoking EndDeleteItem /// operation.</returns> public IAsyncResult BeginDeleteItem(Document document, DeleteItemOperationConfig config, AsyncCallback callback, object state) { return DynamoDBAsyncExecutor.BeginOperation(() => DeleteHelper(MakeKey(document), config, true), callback, state); }
internal Document UpdateHelper(Document doc, Key key, UpdateItemOperationConfig config, bool isAsync) { var currentConfig = config ?? new UpdateItemOperationConfig(); // If the keys have been changed, treat entire document as having changed bool haveKeysChanged = HaveKeysChanged(doc); bool updateChangedAttributesOnly = !haveKeysChanged; var attributeUpdates = doc.ToAttributeUpdateMap(updateChangedAttributesOnly); foreach (var keyName in this.keyNames) { attributeUpdates.Remove(keyName); } UpdateItemRequest req = new UpdateItemRequest { TableName = TableName, Key = key, AttributeUpdates = attributeUpdates.Count == 0 ? new Dictionary<string,AttributeValueUpdate>() : attributeUpdates, ReturnValues = EnumToStringMapper.Convert(currentConfig.ReturnValues) }; req.BeforeRequestEvent += isAsync ? new RequestEventHandler(UserAgentRequestEventHandlerAsync) : new RequestEventHandler(UserAgentRequestEventHandlerSync); if (currentConfig.Expected != null) req.Expected = currentConfig.Expected.ToExpectedAttributeMap(); var resp = DDBClient.UpdateItem(req); var returnedAttributes = resp.UpdateItemResult.Attributes; doc.CommitChanges(); Document ret = null; if (currentConfig.ReturnValues != ReturnValues.None) { ret = Document.FromAttributeMap(returnedAttributes); } return ret; }
/// <summary> /// Creates an initial session record in the DynamoDB table. /// </summary> /// <param name="context"></param> /// <param name="sessionId"></param> /// <param name="timeout"></param> public override void CreateUninitializedItem(HttpContext context, string sessionId, int timeout) { Document session = new Document(); session[ATTRIBUTE_SESSION_ID] = GetHashKey(sessionId); session[ATTRIBUTE_LOCKED] = false; session[ATTRIBUTE_CREATE_DATE] = DateTime.Now; session[ATTRIBUTE_EXPIRES] = DateTime.Now.Add(this._timeout); session[ATTRIBUTE_FLAGS] = 1; session[ATTRIBUTE_RECORD_FORMAT_VERSION] = CURRENT_RECORD_FORMAT_VERSION; this._table.PutItem(session); }