Exemplo n.º 1
0
        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);
            }
        }
Exemplo n.º 2
0
        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!");
                }
            }
        }
Exemplo n.º 3
0
        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));
            }
        }
Exemplo n.º 4
0
        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!");
            }
        }
Exemplo n.º 5
0
 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;
             }
         }
     }
 }
Exemplo n.º 6
0
 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;
             }
         }
     }
 }
Exemplo n.º 7
0
        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);
            }
        }
Exemplo n.º 9
0
        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);
        }
Exemplo n.º 12
0
        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);
            }
        }
Exemplo n.º 13
0
 /// <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;
 }
Exemplo n.º 14
0
 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;
 }
Exemplo n.º 17
0
 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);
 }
Exemplo n.º 18
0
 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;
            }
        }
Exemplo n.º 20
0
        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));
        }
Exemplo n.º 21
0
 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;
 }
Exemplo n.º 22
0
        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));
        }
Exemplo n.º 23
0
        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;
 }
Exemplo n.º 25
0
        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));
        }
Exemplo n.º 26
0
        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));
        }
Exemplo n.º 27
0
        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);
        }
Exemplo n.º 28
0
        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);
        }
Exemplo n.º 29
0
        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);
        }
Exemplo n.º 30
0
        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);
        }
Exemplo n.º 31
0
        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;
        }
Exemplo n.º 32
0
 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;
 }