private async Task <int> AddInitialKeyPathAsync(string keyPath) { var response = await _kvEndpoint.List(keyPath); if (response.StatusCode != System.Net.HttpStatusCode.OK) { return(-1); } var dictionary = BuildDictionaryAsync(keyPath, response.Response); return(AddNewDictionaryToList(dictionary)); }
/// <summary> /// Lists the items beneath a path prefix, returning a dictionary with the keys set /// to the item names and the values raw bytes. An empty list if the key doesn't exist. /// The result keys will not include the key prefix. /// </summary> /// <param name="kv">The key/value endpoint.</param> /// <param name="keyPrefix">The path prefix.</param> /// <param name="cancellationToken">The optional cancellation token.</param> /// <returns>The item dictionary.</returns> /// <remarks> /// <note> /// Any exceptions thrown will be wrapped within an <see cref="AggregateException"/>. /// </note> /// </remarks> public static async Task <IDictionary <string, byte[]> > DictionaryOrEmpty(this IKVEndpoint kv, string keyPrefix, CancellationToken cancellationToken = default) { Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(keyPrefix)); var response = (await kv.List(keyPrefix, cancellationToken)).Response; var output = new Dictionary <string, byte[]>(); if (response == null) { return(output); } foreach (var item in response) { output.Add(StripKeyPrefix(item.Key), item.Value); } return(output); }
/// <summary> /// Lists the items beneath a path prefix and deserializes them as JSON objects, returning /// <c>null</c> if the key doesn't exist. /// </summary> /// <typeparam name="T">The item type.</typeparam> /// <param name="kv">The key/value endpoint.</param> /// <param name="keyPrefix">The path prefix.</param> /// <param name="cancellationToken">The optional cancellation token.</param> /// <returns>The item list or <c>null</c>.</returns> /// <remarks> /// <note> /// Any exceptions thrown will be wrapped within an <see cref="AggregateException"/>. /// </note> /// </remarks> public static async Task <IEnumerable <T> > ListOrDefault <T>(this IKVEndpoint kv, string keyPrefix, CancellationToken cancellationToken = default) where T : new() { Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(keyPrefix)); var response = (await kv.List(keyPrefix, cancellationToken)).Response; if (response == null) { return(null); } var items = new List <T>(response.Length); foreach (var item in response) { items.Add(NeonHelper.JsonDeserialize <T>(Encoding.UTF8.GetString(item.Value))); } return(items); }
/// <summary> /// Lists the items beneath a path prefix and returns a list of the item keys. /// </summary> /// <param name="kv">The key/value endpoint.</param> /// <param name="keyPrefix">The path prefix or <c>null</c> list the root keys.</param> /// <param name="mode">Specifies how the keys are to be listed. This defaults to <see cref="ConsulListMode.FullKey"/>.</param> /// <param name="cancellationToken">The optional cancellation token.</param> /// <returns>The items or an empty list if the prefix does not exist.</returns> public static async Task <IEnumerable <string> > ListKeys(this IKVEndpoint kv, string keyPrefix = null, ConsulListMode mode = ConsulListMode.FullKey, CancellationToken cancellationToken = default) { keyPrefix = keyPrefix ?? string.Empty; var response = (await kv.List(keyPrefix, cancellationToken)).Response; if (response == null) { return(new string[0]); } if (mode == ConsulListMode.FullKeyRecursive) { var items = new List <string>(response.Length); foreach (var item in response) { items.Add(item.Key); } return(items); } else { var items = new HashSet <string>(); var prefixWithoutSlash = keyPrefix; if (prefixWithoutSlash.EndsWith("/")) { prefixWithoutSlash = prefixWithoutSlash.Substring(0, prefixWithoutSlash.Length - 1); } foreach (var item in response) { // Trim off any portion of the listed key below the // prefix, including any forward slash. var key = item.Key; if (key.Length < prefixWithoutSlash.Length) { continue; // Don't think we'll ever see this, but we'll ignore this to be safe. } if (key.Length > prefixWithoutSlash.Length) { var slashPos = key.IndexOf('/', keyPrefix.Length == 0 ? 0 : prefixWithoutSlash.Length + 1); if (slashPos != -1) { key = key.Substring(0, slashPos); } } if (mode == ConsulListMode.PartialKey) { // Remove the key prefix. key = key.Substring(prefixWithoutSlash.Length + 1); } // We may see multiple subkeys beneath a key at this level, // so we'll use the HashSet to verify that we're returning // any given key just once. if (!items.Contains(key)) { items.Add(key); } } return(items); } }