protected async Task RemoveBotStateAsync(BotStoreType type, string key, CancellationToken cancellationToken = default(CancellationToken)) { using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, Activity)) { // Get Bot Data var botData = scope.Resolve <IBotData>(); // Load Bot Data await botData.LoadAsync(cancellationToken); switch (type) { case BotStoreType.BotUserData: botData.UserData.RemoveValue(key); break; case BotStoreType.BotConversationData: botData.ConversationData.RemoveValue(key); break; case BotStoreType.BotPrivateConversationData: botData.PrivateConversationData.RemoveValue(key); break; default: throw new ArgumentException($"{type} is not a valid store type!"); } // Save Bot Data await botData.FlushAsync(cancellationToken); } }
protected async Task <T> GetBotStateAsync <T>(BotStoreType type, string key, T defaultValue = default(T), CancellationToken cancellationToken = default(CancellationToken)) { using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, Activity)) { // Get Bot Data var botData = scope.Resolve <IBotData>(); // Load Bot Data await botData.LoadAsync(cancellationToken); switch (type) { case BotStoreType.BotUserData: return(botData.UserData.GetValueOrDefault(key, defaultValue)); case BotStoreType.BotConversationData: return(botData.ConversationData.GetValueOrDefault(key, defaultValue)); case BotStoreType.BotPrivateConversationData: return(botData.PrivateConversationData.GetValueOrDefault(key, defaultValue)); default: throw new ArgumentException($"{type} is not a valid store type!"); } } }
public Task SaveAsync(BotDataKey key, BotStoreType botStoreType, object value) { try { if (!ValidateKey(key)) { throw new ArgumentException("Invalid bot data key!"); } switch (botStoreType) { case BotStoreType.BotConversationData: message.BotConversationData = value; break; case BotStoreType.BotPerUserInConversationData: message.BotPerUserInConversationData = value; break; case BotStoreType.BotUserData: message.BotUserData = value; break; default: throw new ArgumentException($"key {botStoreType} is not supported by this message store"); } return(Task.FromResult(Type.Missing)); } catch (Exception e) { return(Task.FromException(e)); } }
public async Task SaveAsync(IAddress key, BotStoreType botStoreType, BotData data, CancellationToken cancellationToken) { var channelId = GetChannelId(key); switch (botStoreType) { case BotStoreType.BotConversationData: await DataStoreClient.SetConversationDataAsync(channelId, key.ConversationId, data, cancellationToken); break; case BotStoreType.BotUserData: await DataStoreClient.SetUserDataAsync(channelId, key.UserId, data, cancellationToken); break; case BotStoreType.BotPrivateConversationData: await DataStoreClient.SetPrivateConversationDataAsync(channelId, key.ConversationId, key.UserId, data, cancellationToken); break; default: throw new ArgumentException($"{botStoreType} is not a valid store type!"); } }
async Task IBotDataStore <BotData> .SaveAsync(IAddress key, BotStoreType botStoreType, BotData botData, CancellationToken cancellationToken) { lock (locks[botStoreType]) { if (botData.Data != null) { store.AddOrUpdate(GetKey(key, botStoreType), (dictionaryKey) => { botData.ETag = Guid.NewGuid().ToString("n"); return(Serialize(botData)); }, (dictionaryKey, value) => { ValidateETag(botData, value); botData.ETag = Guid.NewGuid().ToString("n"); return(Serialize(botData)); }); } else { // remove record on null string value; if (store.TryGetValue(GetKey(key, botStoreType), out value)) { ValidateETag(botData, value); store.TryRemove(GetKey(key, botStoreType), out value); return; } } } }
async Task IBotDataStore <BotData> .SaveAsync(IAddress key, BotStoreType botStoreType, BotData botData, CancellationToken cancellationToken) { lock (locks[botStoreType]) { string storeKey = GetKey(key, botStoreType); string oldValue = (string)store.Get(storeKey); if (botData.Data != null) { if (oldValue != null) { ValidateETag(botData, oldValue); } botData.ETag = Guid.NewGuid().ToString("n"); store.Set(GetKey(key, botStoreType), Serialize(botData), cacheItemPolicy); } else { // remove record on null if (oldValue != null) { ValidateETag(botData, oldValue); store.Remove(storeKey); return; } } } }
async Task <BotData> IBotDataStore <BotData> .LoadAsync(IAddress key, BotStoreType botStoreType, CancellationToken cancellationToken) { BotData botData; switch (botStoreType) { case BotStoreType.BotConversationData: botData = await stateClient.BotState.GetConversationDataAsync(key.ChannelId, key.ConversationId, cancellationToken); break; case BotStoreType.BotUserData: botData = await stateClient.BotState.GetUserDataAsync(key.ChannelId, key.UserId, cancellationToken); break; case BotStoreType.BotPrivateConversationData: botData = await stateClient.BotState.GetPrivateConversationDataAsync(key.ChannelId, key.ConversationId, key.UserId, cancellationToken); break; default: throw new ArgumentException($"{botStoreType} is not a valid store type!"); } return(botData); }
async Task<BotData> IBotDataStore<BotData>.LoadAsync(IAddress key, BotStoreType botStoreType, CancellationToken cancellationToken) { try { var entityKey = DocDbBotDataEntity.GetEntityKey(key, botStoreType); var response = await documentClient.ReadDocumentAsync(UriFactory.CreateDocumentUri(databaseId, collectionId, entityKey)); // The Resource property of the response, of type IDynamicMetaObjectProvider, has a dynamic nature, // similar to DynamicTableEntity in Azure storage. When casting to a static type, properties that exist in the static type will be // populated from the dynamic type. DocDbBotDataEntity entity = (dynamic)response.Resource; return new BotData(response?.Resource.ETag, entity?.Data); } catch (DocumentClientException e) { if (e.StatusCode.HasValue && e.StatusCode.Value == HttpStatusCode.NotFound) { return new BotData(string.Empty, null); } throw new HttpException(e.StatusCode.HasValue ? (int)e.StatusCode.Value : 0, e.Message, e); } }
async Task <object> IBotDataStore <object> .LoadAsync(BotDataKey key, BotStoreType botStoreType, CancellationToken cancellationToken) { DataEntry entry; object obj = null; if (!cache.TryGetValue(key, out entry)) { entry = new DataEntry(); cache[key] = entry; BotData value = await inner.LoadAsync(key, botStoreType, cancellationToken); if (value?.Data != null) { obj = value.Data; } SetValue(entry, botStoreType, obj); return(obj); } else { switch (botStoreType) { case BotStoreType.BotConversationData: if (entry.BotConversationData != null) { obj = entry.BotConversationData; } break; case BotStoreType.BotPrivateConversationData: if (entry.BotPrivateConversationData != null) { obj = entry.BotPrivateConversationData; } break; case BotStoreType.BotUserData: if (entry.BotUserData != null) { obj = entry.BotUserData; } break; } if (obj == null) { BotData value = await inner.LoadAsync(key, botStoreType, cancellationToken); if (value?.Data != null) { obj = value.Data; SetValue(entry, botStoreType, obj); } } return(obj); } }
async Task IBotDataStore <BotData> .SaveAsync(IAddress key, BotStoreType botStoreType, BotData data, CancellationToken cancellationToken) { Connect(); var redisKey = GetKey(key, botStoreType); var serializedData = Serialize(data.Data); var database = _connection.GetDatabase(_options.Database); var tran = database.CreateTransaction(); if (data.ETag != "*") { tran.AddCondition(Condition.HashEqual(redisKey, ETAG_KEY, data.ETag)); } tran.HashSetAsync(redisKey, new HashEntry[] { new HashEntry(ETAG_KEY, DateTime.UtcNow.Ticks.ToString()), new HashEntry(DATA_KEY, serializedData) }); bool committed = await tran.ExecuteAsync(); if (!committed) { throw new ConcurrencyException("Inconsistent SaveAsync based on ETag!"); } }
internal static SqlBotDataEntity GetSqlBotDataEntity(IAddress key, BotStoreType botStoreType, ConversationDataContext context) { SqlBotDataEntity entity = null; var query = context.BotData.OrderByDescending(d => d.Timestamp); switch (botStoreType) { case BotStoreType.BotConversationData: entity = query.FirstOrDefault(d => d.BotStoreType == botStoreType && d.ChannelId == key.ChannelId && d.ConversationId == key.ConversationId); break; case BotStoreType.BotUserData: entity = query.FirstOrDefault(d => d.BotStoreType == botStoreType && d.ChannelId == key.ChannelId && d.UserId == key.UserId); break; case BotStoreType.BotPrivateConversationData: entity = query.FirstOrDefault(d => d.BotStoreType == botStoreType && d.ChannelId == key.ChannelId && d.ConversationId == key.ConversationId && d.UserId == key.UserId); break; default: throw new ArgumentException("Unsupported bot store type!"); } return(entity); }
public async Task <T> LoadAsync <T>(BotDataKey key, BotStoreType botStoreType) { DataEntry entry; T obj = default(T); if (!cache.TryGetValue(key, out entry)) { entry = new DataEntry(); cache[key] = entry; string value; if (store.TryGetValue(GetKey(key, botStoreType), out value)) { obj = (T)JsonConvert.DeserializeObject(value); } SetValue(entry, botStoreType, obj); return(obj); } else { switch (botStoreType) { case BotStoreType.BotConversationData: if (entry.BotConversationData != null) { obj = (T)entry.BotConversationData; } break; case BotStoreType.BotPerUserInConversationData: if (entry.BotPerUserInConversationData != null) { obj = (T)entry.BotPerUserInConversationData; } break; case BotStoreType.BotUserData: if (entry.BotUserData != null) { obj = (T)entry.BotUserData; } break; } if (obj == null) { string value; if (store.TryGetValue(GetKey(key, botStoreType), out value)) { obj = (T)JsonConvert.DeserializeObject(value); SetValue(entry, botStoreType, obj); } } return(obj); } }
/// <summary> /// Constructs a new <see cref="V3V4Storage"/> /// </summary> /// <param name="v3DataStore">A Bot Builder SDK V3 <see cref="IBotDataStore"/> (required)</param> /// <param name="botStoreType">THe Type of Data Storage (UserData, ConversationData, PrivateConversationData) /// <see cref="BotStoreType"/>Type of storage</param> /// <param name="statePropertyName">This is only relavent in code. The name of the BotState property, /// retrieved and accessed through a property accessor created from an instance of <see cref="V3V4State"/>.</param> public V3V4Storage(IBotDataStore <BotData> v3DataStore, BotStoreType botStoreType = BotStoreType.BotUserData, string statePropertyName = "V3State") { _v3DataStore = v3DataStore ?? throw new ArgumentNullException(nameof(v3DataStore)); _botStoreType = botStoreType; _statePropertyName = statePropertyName; }
public BotDataStoreDao(BotStoreType type, string botId, string channelId, string conversationId, string userId, BotData botData) { Type = type; BotId = botId; ChannelId = channelId; ConversationId = conversationId; UserId = userId; BotData = botData; }
internal SqlBotDataEntity(BotStoreType botStoreType, string botId, string channelId, string conversationId, string userId, object data) { this.BotStoreType = botStoreType; this.BotId = botId; this.ChannelId = channelId; this.ConversationId = conversationId; this.UserId = userId; this.Data = Serialize(data); }
internal DocDbBotDataEntity(IAddress key, BotStoreType botStoreType, BotData botData) { this.Id = GetEntityKey(key, botStoreType); this.BotId = key.BotId; this.ChannelId = key.ChannelId; this.ConversationId = key.ConversationId; this.UserId = key.UserId; this.Data = botData.Data; }
public async Task SaveAsync(IAddress key, BotStoreType botStoreType, BotData data, CancellationToken cancellationToken) { var model = new BotDataStoreDao(key, botStoreType, data) { TimeStamp = DateTime.Now }; var service = new SqlDataStoreService(ConnectionString); await service.InsertOrUpdateAsync(model); }
public async Task SaveAsync(IAddress key, BotStoreType botStoreType, BotData data, CancellationToken cancellationToken) { using (var context = new FeedbackDatastoreDbContext(_connectionStringName)) { var d = data as FeedbackEntity; context.FeedbackData.Add(d); context.SaveChanges(); } }
async Task IBotDataStore <BotData> .SaveAsync(IAddress key, BotStoreType botStoreType, BotData botData, CancellationToken cancellationToken) { try { var requestOptions = new RequestOptions() { AccessCondition = new AccessCondition() { Type = AccessConditionType.IfMatch, Condition = botData.ETag } }; var entity = new DocDbBotDataEntity(key, botStoreType, botData); var entityKey = DocDbBotDataEntity.GetEntityKey(key, botStoreType); if (string.IsNullOrEmpty(botData.ETag)) { await documentClient.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(databaseId, collectionId), entity, requestOptions); } else if (botData.ETag == "*") { if (botData.Data != null) { await documentClient.UpsertDocumentAsync(UriFactory.CreateDocumentCollectionUri(databaseId, collectionId), entity, requestOptions); } else { await documentClient.DeleteDocumentAsync(UriFactory.CreateDocumentUri(databaseId, collectionId, entityKey), requestOptions); } } else { if (botData.Data != null) { await documentClient.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(databaseId, collectionId, entityKey), entity, requestOptions); } else { await documentClient.DeleteDocumentAsync(UriFactory.CreateDocumentUri(databaseId, collectionId, entityKey), requestOptions); } } } catch (DocumentClientException e) { //if (e.StatusCode.HasValue && e.StatusCode.Value == HttpStatusCode.Conflict) //{ // throw new HttpException((int)HttpStatusCode.PreconditionFailed, e.Message, e); //} //throw new HttpException(e.StatusCode.HasValue ? (int)e.StatusCode.Value : 0, e.Message, e); throw; } }
async Task <BotData> IBotDataStore <BotData> .LoadAsync(BotDataKey key, BotStoreType botStoreType, CancellationToken cancellationToken) { string serializedData; serializedData = store.GetOrAdd(GetKey(key, botStoreType), dictionaryKey => Serialize(new BotData { ETag = DateTime.UtcNow.ToString() })); return(Deserialize(serializedData)); }
public BotDataStoreDao(IAddress key, BotStoreType type, BotData botData) { Type = type; BotId = key.BotId; ChannelId = key.ChannelId; ConversationId = key.ConversationId; UserId = key.UserId; ServiceUrl = key.ServiceUrl; BotData = botData; }
async Task <BotData> IBotDataStore <BotData> .LoadAsync(IAddress key, BotStoreType botStoreType, CancellationToken cancellationToken) { string serializedData = (string)store.Get(GetKey(key, botStoreType)); if (serializedData != null) { return(Deserialize(serializedData)); } return(new BotData(eTag: String.Empty)); }
async Task <BotData> IBotDataStore <BotData> .LoadAsync(IAddress key, BotStoreType botStoreType, CancellationToken cancellationToken) { string serializedData; if (store.TryGetValue(GetKey(key, botStoreType), out serializedData)) { return(Deserialize(serializedData)); } return(new BotData(eTag: String.Empty)); }
internal SqlBotDataEntity(BotStoreType botStoreType, string botId, string channelId, string conversationId, string userId, object data) { BotStoreType = botStoreType; BotId = botId; ChannelId = channelId; ConversationId = conversationId; UserId = userId; Data = Serialize(data); Timestamp = DateTimeOffset.UtcNow; }
private async Task <IBotDataBag> LoadData(BotStoreType botStoreType, CancellationToken cancellationToken) { var botData = await this.botDataStore.LoadAsync(botDataKey, botStoreType, cancellationToken); if (botData?.Data == null) { botData.Data = this.MakeData(); await this.botDataStore.SaveAsync(botDataKey, botStoreType, botData, cancellationToken); } return(this.WrapData((T)botData.Data)); }
private async Task <IBotDataBag> LoadData(BotStoreType botStoreType) { T data = await this.botDataStore.LoadAsync <T>(botDataKey, botStoreType); if (data == null) { data = this.MakeData(); await this.botDataStore.SaveAsync(botDataKey, botStoreType, data); } return(this.WrapData(data)); }
async Task IBotDataStore <BotData> .SaveAsync(IAddress key, BotStoreType botStoreType, BotData value, CancellationToken cancellationToken) { CacheEntry entry; if (!cache.TryGetValue(key, out entry)) { entry = new CacheEntry(); cache.Add(key, entry); } SetCachedValue(entry, botStoreType, value); }
async Task IBotDataStore <object> .SaveAsync(BotDataKey key, BotStoreType botStoreType, object value, CancellationToken cancellationToken) { DataEntry entry; if (!cache.TryGetValue(key, out entry)) { entry = new DataEntry(); cache[key] = entry; } SetValue(entry, botStoreType, value); }
public async Task SaveAsync(BotDataKey key, BotStoreType botStoreType, object value) { DataEntry entry; if (!cache.TryGetValue(key, out entry)) { entry = new DataEntry(); cache[key] = entry; } SetValue(entry, botStoreType, value); }
async Task IBotDataStore <BotData> .SaveAsync(IAddress key, BotStoreType botStoreType, BotData value, CancellationToken cancellationToken) { var cacheKey = GetCacheKey(key); CacheEntry cacheEntry = (CacheEntry)cache.Get(GetCacheKey(key)); if (cacheEntry == null) { cacheEntry = new CacheEntry(); cache.Add(cacheKey, cacheEntry, cacheItemPolicy); } SetCachedValue(cacheEntry, botStoreType, value); }
protected async Task<HttpOperationResponse<object>> UpsertData(string botId, string channelId, string userId, string conversationId, BotStoreType storeType, BotData data) { var _result = new HttpOperationResponse<object>(); try { await memoryDataStore.SaveAsync(new BotDataKey { BotId = botId, UserId = userId, ConversationId = conversationId, ChannelId = channelId }, storeType, data, CancellationToken.None); } catch(HttpException e) { _result.Body = e.Data; _result.Response = new HttpResponseMessage { StatusCode = HttpStatusCode.PreconditionFailed }; return _result; } catch(Exception) { _result.Response = new HttpResponseMessage { StatusCode = HttpStatusCode.InternalServerError }; return _result; } _result.Body = data; _result.Response = new HttpResponseMessage { StatusCode = HttpStatusCode.OK }; return _result; }
protected async Task<HttpOperationResponse<object>> GetData(string botId, string channelId, string userId, string conversationId, BotStoreType storeType) { var _result = new HttpOperationResponse<object>(); BotData data; data = await memoryDataStore.LoadAsync(new BotDataKey { BotId = botId, UserId = userId, ConversationId = conversationId, ChannelId = channelId }, storeType, CancellationToken.None); _result.Body = data; _result.Response = new HttpResponseMessage { StatusCode = HttpStatusCode.OK }; return _result; }