Пример #1
0
        /// <summary>
        /// Lists all buckets available on the Riak cluster.
        /// </summary>
        /// <returns>
        /// An <see cref="System.Collections.Generic.IEnumerable&lt;T&gt;"/> of <see cref="string"/> bucket names.
        /// </returns>
        /// <remarks>Buckets provide a logical namespace for keys. Listing buckets requires folding over all keys in a cluster and
        /// reading a list of buckets from disk. This operation, while non-blocking in Riak 1.0 and newer, still produces considerable
        /// physical I/O and can take a long time.</remarks>
        public RiakResult <IEnumerable <string> > ListBuckets()
        {
            var result = UseConnection(conn => conn.PbcWriteRead <RpbListBucketsResp>(MessageCode.ListBucketsReq));

            if (result.IsSuccess)
            {
                var buckets = result.Value.buckets.Select(b => b.FromRiakString());
                return(RiakResult <IEnumerable <string> > .Success(buckets.ToList()));
            }
            return(RiakResult <IEnumerable <string> > .Error(result.ResultCode, result.ErrorMessage, result.NodeOffline));
        }
Пример #2
0
 public Task <RiakResult <RiakServerInfo> > GetServerInfo()
 {
     return(UseConnection(conn => conn.PbcWriteRead <RpbGetServerInfoResp>(MessageCode.GetServerInfoReq))
            .ContinueWith((Task <RiakResult <RpbGetServerInfoResp> > finishedTask) => {
         var result = finishedTask.Result;
         if (result.IsSuccess)
         {
             return RiakResult <RiakServerInfo> .Success(new RiakServerInfo(result.Value));
         }
         return RiakResult <RiakServerInfo> .Error(result.ResultCode, result.ErrorMessage, result.NodeOffline);
     }));
 }
Пример #3
0
        public RiakResult <RiakSearchResult> Search(RiakSearchRequest search)
        {
            var request  = search.ToMessage();
            var response = UseConnection(conn => conn.PbcWriteRead <RpbSearchQueryReq, RpbSearchQueryResp>(request));

            if (response.IsSuccess)
            {
                return(RiakResult <RiakSearchResult> .Success(new RiakSearchResult(response.Value)));
            }

            return(RiakResult <RiakSearchResult> .Error(response.ResultCode, response.ErrorMessage, response.NodeOffline));
        }
Пример #4
0
        public RiakResult <RiakMapReduceResult> MapReduce(RiakMapReduceQuery query)
        {
            var request  = query.ToMessage();
            var response = UseConnection(conn => conn.PbcWriteRead <RpbMapRedReq, RpbMapRedResp>(request, r => r.IsSuccess && !r.Value.done));

            if (response.IsSuccess)
            {
                return(RiakResult <RiakMapReduceResult> .Success(new RiakMapReduceResult(response.Value)));
            }

            return(RiakResult <RiakMapReduceResult> .Error(response.ResultCode, response.ErrorMessage, response.NodeOffline));
        }
Пример #5
0
        public RiakResult <RiakStreamedMapReduceResult> StreamMapReduce(RiakMapReduceQuery query)
        {
            var request  = query.ToMessage();
            var response = UseDelayedConnection((conn, onFinish) =>
                                                conn.PbcWriteStreamRead <RpbMapRedReq, RpbMapRedResp>(request, r => r.IsSuccess && !r.Value.Done, onFinish));

            if (response.IsSuccess)
            {
                return(RiakResult <RiakStreamedMapReduceResult> .Success(new RiakStreamedMapReduceResult(response.Value)));
            }
            return(RiakResult <RiakStreamedMapReduceResult> .Error(response.ResultCode, response.ErrorMessage));
        }
Пример #6
0
 public Task <RiakResult <IEnumerable <string> > > ListBuckets()
 {
     return(UseConnection(conn => conn.PbcWriteRead <RpbListBucketsResp>(MessageCode.ListBucketsReq))
            .ContinueWith((Task <RiakResult <RpbListBucketsResp> > finishedTask) => {
         var result = finishedTask.Result;
         if (result.IsSuccess)
         {
             var buckets = result.Value.buckets.Select(b => b.FromRiakString());
             return RiakResult <IEnumerable <string> > .Success(buckets.ToList());
         }
         return RiakResult <IEnumerable <string> > .Error(result.ResultCode, result.ErrorMessage, result.NodeOffline);
     }));
 }
Пример #7
0
        public Task <IEnumerable <RiakResult <RiakObject> > > Get(IEnumerable <RiakObjectId> bucketKeyPairs, RiakGetOptions options = null)
        {
            bucketKeyPairs = bucketKeyPairs.ToList();
            options        = options ?? new RiakGetOptions();

            return(UseConnection(conn => {
                return AfterAll(bucketKeyPairs.Select(bkp => {
                    // modified closure FTW
                    var bk = bkp;
                    if (!IsValidBucketOrKey(bk.Bucket))
                    {
                        return RiakResult <RpbGetResp> .ErrorTask(ResultCode.InvalidRequest, InvalidBucketErrorMessage, false);
                    }
                    if (!IsValidBucketOrKey(bk.Key))
                    {
                        return RiakResult <RpbGetResp> .ErrorTask(ResultCode.InvalidRequest, InvalidKeyErrorMessage, false);
                    }

                    var req = new RpbGetReq {
                        bucket = bk.Bucket.ToRiakString(), key = bk.Key.ToRiakString()
                    };
                    options.Populate(req);

                    return conn.PbcWriteRead <RpbGetReq, RpbGetResp>(req);
                })).ContinueWith((Task <IEnumerable <RiakResult <RpbGetResp> > > finishedTask) => {
                    return RiakResult <IEnumerable <RiakResult <RpbGetResp> > > .Success(finishedTask.Result);
                });
            }).ContinueWith((Task <RiakResult <IEnumerable <RiakResult <RpbGetResp> > > > finishedTask) => {
                // zip up results
                var results = RiakResult <IEnumerable <RiakResult <RpbGetResp> > > .Success(finishedTask.Result.Value);
                return results.Value.Zip(bucketKeyPairs, Tuple.Create).Select(result => {
                    if (!result.Item1.IsSuccess)
                    {
                        return RiakResult <RiakObject> .Error(result.Item1.ResultCode, result.Item1.ErrorMessage, result.Item1.NodeOffline);
                    }
                    if (result.Item1.Value.vclock == null)
                    {
                        return RiakResult <RiakObject> .Error(ResultCode.NotFound, "Unable to find value in Riak", false);
                    }

                    var o = new RiakObject(result.Item2.Bucket, result.Item2.Key, result.Item1.Value.content.First(), result.Item1.Value.vclock);
                    if (result.Item1.Value.content.Count > 1)
                    {
                        o.Siblings = result.Item1.Value.content.Select(
                            c => new RiakObject(result.Item2.Bucket, result.Item2.Key, c, result.Item1.Value.vclock)).ToList();
                    }

                    return RiakResult <RiakObject> .Success(o);
                });
            }));
        }
Пример #8
0
        public Task <RiakResult <RiakMapReduceResult> > MapReduce(RiakMapReduceQuery query)
        {
            var request = query.ToMessage();

            return(UseConnection(conn => conn.PbcWriteRead <RpbMapRedReq, RpbMapRedResp>(request, r => r.IsSuccess && !r.Value.done))
                   .ContinueWith((Task <RiakResult <IEnumerable <RiakResult <RpbMapRedResp> > > > finishedTask) => {
                var result = finishedTask.Result;
                if (result.IsSuccess)
                {
                    return RiakResult <RiakMapReduceResult> .Success(new RiakMapReduceResult(result.Value));
                }
                return RiakResult <RiakMapReduceResult> .Error(result.ResultCode, result.ErrorMessage, result.NodeOffline);
            }));
        }
Пример #9
0
        private static RiakResult <IEnumerable <string> > ListKeys(IRiakConnection conn, string bucket)
        {
            var lkReq = new RpbListKeysReq {
                Bucket = bucket.ToRiakString()
            };
            var result = conn.PbcWriteRead <RpbListKeysReq, RpbListKeysResp>(lkReq,
                                                                             lkr => lkr.IsSuccess && !lkr.Value.Done);

            if (result.IsSuccess)
            {
                var keys = result.Value.Where(r => r.IsSuccess).SelectMany(r => r.Value.KeyNames).Distinct().ToList();
                return(RiakResult <IEnumerable <string> > .Success(keys));
            }
            return(RiakResult <IEnumerable <string> > .Error(result.ResultCode, result.ErrorMessage));
        }
Пример #10
0
        public RiakResult <IEnumerable <string> > StreamListKeys(string bucket)
        {
            var lkReq = new RpbListKeysReq {
                Bucket = bucket.ToRiakString()
            };
            var result = UseDelayedConnection((conn, onFinish) =>
                                              conn.PbcWriteStreamRead <RpbListKeysReq, RpbListKeysResp>(lkReq, lkr => lkr.IsSuccess && !lkr.Value.Done, onFinish));

            if (result.IsSuccess)
            {
                var keys = result.Value.Where(r => r.IsSuccess).SelectMany(r => r.Value.KeyNames);
                return(RiakResult <IEnumerable <string> > .Success(keys));
            }
            return(RiakResult <IEnumerable <string> > .Error(result.ResultCode, result.ErrorMessage));
        }
Пример #11
0
        public Task <RiakResult <RiakSearchResult> > Search(RiakSearchRequest search)
        {
            var request = search.ToMessage();

            return(UseConnection(conn => conn.PbcWriteRead <RpbSearchQueryReq, RpbSearchQueryResp>(request))
                   .ContinueWith((Task <RiakResult <RpbSearchQueryResp> > finishedTask) => {
                var result = finishedTask.Result;
                if (result.IsSuccess)
                {
                    return RiakResult <RiakSearchResult> .Success(new RiakSearchResult(result.Value));
                }

                return RiakResult <RiakSearchResult> .Error(result.ResultCode, result.ErrorMessage, result.NodeOffline);
            }));
        }
Пример #12
0
        /// <summary>
        /// Deletes the contents of the specified <paramref name="bucket"/>.
        /// </summary>
        /// <returns>
        /// A <see cref="System.Collections.Generic.IEnumerable&lt;T&gt;"/> of <see cref="CorrugatedIron.RiakResult"/> listing the success of all deletes
        /// </returns>
        /// <param name='bucket'>
        /// The bucket to be deleted.
        /// </param>
        /// <param name='deleteOptions'>
        /// Options for Riak delete operation <see cref="CorrugatedIron.Models.RiakDeleteOptions"/>
        /// </param>
        /// <remarks>
        /// <para>
        /// A delete bucket operation actually deletes all keys in the bucket individually.
        /// A <see cref="CorrugatedIron.RiakClient.ListKeys"/> operation is performed to retrieve a list of keys
        /// The keys retrieved from the <see cref="CorrugatedIron.RiakClient.ListKeys"/> are then deleted through
        /// <see cref="CorrugatedIron.RiakClient.Delete"/>.
        /// </para>
        /// <para>
        /// Because of the <see cref="CorrugatedIron.RiakClient.ListKeys"/> operation, this may be a time consuming operation on
        /// production systems and may cause memory problems for the client. This should be used either in testing or on small buckets with
        /// known amounts of data.
        /// </para>
        /// </remarks>
        public IEnumerable <RiakResult> DeleteBucket(string bucket, RiakDeleteOptions deleteOptions)
        {
            var results = UseConnection(conn =>
            {
                var keyResults = ListKeys(conn, bucket);
                if (keyResults.IsSuccess)
                {
                    var objectIds = keyResults.Value.Select(key => new RiakObjectId(bucket, key)).ToList();
                    return(Delete(conn, objectIds, deleteOptions));
                }
                return(RiakResult <IEnumerable <RiakResult> > .Error(keyResults.ResultCode, keyResults.ErrorMessage, keyResults.NodeOffline));
            });

            return(results.Value);
        }
Пример #13
0
        /// <summary>
        /// Persist an <see href="System.Collections.Generic.IEnumerable&lt;T&gt;"/> of <see cref="CorrugatedIron.Models.RiakObjectId"/> to Riak.
        /// </summary>
        /// <param name='values'>
        /// The <see href="System.Collections.Generic.IEnumerable&lt;T&gt;"/> of <see cref="CorrugatedIron.Models.RiakObjectId"/> to save.
        /// </param>
        /// <param name='options'>
        /// Put options.
        /// </param>
        public IEnumerable <RiakResult <RiakObject> > Put(IEnumerable <RiakObject> values, RiakPutOptions options = null)
        {
            options = options ?? new RiakPutOptions();

            values = values.ToList();
            var messages = values.Select(v =>
            {
                var m = v.ToMessage();
                options.Populate(m);
                return(m);
            }).ToList();

            var results = UseConnection(conn =>
            {
                var responses = messages.Select(conn.PbcWriteRead <RpbPutReq, RpbPutResp>).ToList();
                return(RiakResult <IEnumerable <RiakResult <RpbPutResp> > > .Success(responses));
            });

            var resultsArray = results.Value.ToArray();

            for (var i = 0; i < resultsArray.Length; i++)
            {
                if (resultsArray[i].IsSuccess)
                {
                    values.ElementAt(i).MarkClean();
                }
            }

            return(results.Value.Zip(values, Tuple.Create).Select(t =>
            {
                if (t.Item1.IsSuccess)
                {
                    var finalResult = options.ReturnBody
                        ? new RiakObject(t.Item2.Bucket, t.Item2.Key, t.Item1.Value.Content.First(), t.Item1.Value.VectorClock)
                        : t.Item2;

                    if (options.ReturnBody && t.Item1.Value.Content.Count > 1)
                    {
                        finalResult.Siblings = t.Item1.Value.Content.Select(c =>
                                                                            new RiakObject(t.Item2.Bucket, t.Item2.Key, c, t.Item1.Value.VectorClock)).ToList();
                    }

                    return RiakResult <RiakObject> .Success(finalResult);
                }

                return RiakResult <RiakObject> .Error(t.Item1.ResultCode, t.Item1.ErrorMessage);
            }));
        }
Пример #14
0
        /// <summary>
        /// Persist an <see href="System.Collections.Generic.IEnumerable{T}"/> of <see cref="CorrugatedIron.Models.RiakObjectId"/> to Riak.
        /// </summary>
        /// <param name='values'>
        /// The <see href="System.Collections.Generic.IEnumerable{T}"/> of <see cref="CorrugatedIron.Models.RiakObjectId"/> to save.
        /// </param>
        /// <param name='options'>
        /// Put options.
        /// </param>
        /// <returns>An <see cref="System.Collections.Generic.IEnumerable{T}"/> of <see cref="RiakResult{T}"/>
        /// is returned. You should verify the success or failure of each result separately.</returns>
        /// <remarks>Riak does not support multi put behavior. CorrugatedIron's multi put functionality wraps multiple
        /// put requests and returns results as an IEnumerable{RiakResult{RiakObject}}. Callers should be aware that
        /// this may result in partial success - all results should be evaluated individually in the calling application.
        /// In addition, applications should plan for multiple failures or multiple cases of siblings being present.</remarks>
        public IEnumerable <RiakResult <RiakObject> > Put(IEnumerable <RiakObject> values, RiakPutOptions options = null)
        {
            options = options ?? new RiakPutOptions();

            var results = UseConnection(conn =>
            {
                var responses = values.Select(v =>
                {
                    if (!IsValidBucketOrKey(v.Bucket))
                    {
                        return(RiakResult <RpbPutResp> .Error(ResultCode.InvalidRequest, InvalidBucketErrorMessage, false));
                    }

                    if (!IsValidBucketOrKey(v.Key))
                    {
                        return(RiakResult <RpbPutResp> .Error(ResultCode.InvalidRequest, InvalidKeyErrorMessage, false));
                    }

                    var msg = v.ToMessage();
                    options.Populate(msg);

                    return(conn.PbcWriteRead <RpbPutReq, RpbPutResp>(msg));
                }).ToList();

                return(RiakResult <IEnumerable <RiakResult <RpbPutResp> > > .Success(responses));
            });

            return(results.Value.Zip(values, Tuple.Create).Select(t =>
            {
                if (t.Item1.IsSuccess)
                {
                    var finalResult = options.ReturnBody
                        ? new RiakObject(t.Item2.Bucket, t.Item2.Key, t.Item1.Value.content.First(), t.Item1.Value.vclock)
                        : t.Item2;

                    if (options.ReturnBody && t.Item1.Value.content.Count > 1)
                    {
                        finalResult.Siblings = t.Item1.Value.content.Select(c =>
                                                                            new RiakObject(t.Item2.Bucket, t.Item2.Key, c, t.Item1.Value.vclock)).ToList();
                    }

                    return RiakResult <RiakObject> .Success(finalResult);
                }

                return RiakResult <RiakObject> .Error(t.Item1.ResultCode, t.Item1.ErrorMessage, t.Item1.NodeOffline);
            }));
        }
Пример #15
0
        public Task <RiakResult <RiakBucketProperties> > GetBucketProperties(string bucket, bool extended = false)
        {
            // bucket names cannot have slashes in the names, the REST interface doesn't like it at all
            if (!IsValidBucketOrKey(bucket))
            {
                return(RiakResult <RiakBucketProperties> .ErrorTask(ResultCode.InvalidRequest, InvalidBucketErrorMessage, false));
            }

            if (extended)
            {
                var request = new RiakRestRequest(ToBucketUri(bucket), RiakConstants.Rest.HttpMethod.Get)
                              .AddQueryParam(RiakConstants.Rest.QueryParameters.Bucket.GetPropertiesKey,
                                             RiakConstants.Rest.QueryParameters.Bucket.GetPropertiesValue);

                return(UseConnection(conn => conn.RestRequest(request))
                       .ContinueWith((Task <RiakResult <RiakRestResponse> > finishedTask) => {
                    var result = finishedTask.Result;
                    if (result.IsSuccess)
                    {
                        if (result.Value.StatusCode == HttpStatusCode.OK)
                        {
                            var response = new RiakBucketProperties(result.Value);
                            return RiakResult <RiakBucketProperties> .Success(response);
                        }
                        return RiakResult <RiakBucketProperties> .Error(ResultCode.InvalidResponse,
                                                                        "Unexpected Status Code: {0} ({1})".Fmt(result.Value.StatusCode, (int)result.Value.StatusCode), false);
                    }
                    return RiakResult <RiakBucketProperties> .Error(result.ResultCode, result.ErrorMessage, result.NodeOffline);
                }));
            }
            else
            {
                var bpReq = new RpbGetBucketReq {
                    bucket = bucket.ToRiakString()
                };
                return(UseConnection(conn => conn.PbcWriteRead <RpbGetBucketReq, RpbGetBucketResp>(bpReq))
                       .ContinueWith((Task <RiakResult <RpbGetBucketResp> > finishedTask) => {
                    var result = finishedTask.Result;
                    if (result.IsSuccess)
                    {
                        var props = new RiakBucketProperties(result.Value.props);
                        return RiakResult <RiakBucketProperties> .Success(props);
                    }
                    return RiakResult <RiakBucketProperties> .Error(result.ResultCode, result.ErrorMessage, result.NodeOffline);
                }));
            }
        }
Пример #16
0
        private static RiakResult <IEnumerable <string> > ListKeys(IRiakConnection conn, string bucket)
        {
            System.Diagnostics.Debug.Write(ListKeysWarning);
            System.Diagnostics.Trace.TraceWarning(ListKeysWarning);
            Console.WriteLine(ListKeysWarning);

            var lkReq = new RpbListKeysReq {
                bucket = bucket.ToRiakString()
            };
            var result = conn.PbcWriteRead <RpbListKeysReq, RpbListKeysResp>(lkReq,
                                                                             lkr => lkr.IsSuccess && !lkr.Value.done);

            if (result.IsSuccess)
            {
                var keys = result.Value.Where(r => r.IsSuccess).SelectMany(r => r.Value.keys).Select(k => k.FromRiakString()).Distinct().ToList();
                return(RiakResult <IEnumerable <string> > .Success(keys));
            }
            return(RiakResult <IEnumerable <string> > .Error(result.ResultCode, result.ErrorMessage, result.NodeOffline));
        }
Пример #17
0
        public RiakResult <IEnumerable <string> > StreamListKeys(string bucket)
        {
            System.Diagnostics.Debug.Write(ListKeysWarning);
            System.Diagnostics.Trace.TraceWarning(ListKeysWarning);
            Console.WriteLine(ListKeysWarning);

            var lkReq = new RpbListKeysReq {
                bucket = bucket.ToRiakString()
            };
            var result = UseDelayedConnection((conn, onFinish) =>
                                              conn.PbcWriteStreamRead <RpbListKeysReq, RpbListKeysResp>(lkReq, lkr => lkr.IsSuccess && !lkr.Value.done, onFinish));

            if (result.IsSuccess)
            {
                var keys = result.Value.Where(r => r.IsSuccess).SelectMany(r => r.Value.keys).Select(k => k.FromRiakString());
                return(RiakResult <IEnumerable <string> > .Success(keys));
            }
            return(RiakResult <IEnumerable <string> > .Error(result.ResultCode, result.ErrorMessage, result.NodeOffline));
        }
Пример #18
0
        private RiakResult <IList <string> > IndexGetEquals(string bucket, string indexName, string value)
        {
            var message = new RpbIndexReq
            {
                bucket = bucket.ToRiakString(),
                index  = indexName.ToRiakString(),
                key    = value.ToRiakString(),
                qtype  = RpbIndexReq.IndexQueryType.eq
            };

            var result = UseConnection(conn => conn.PbcWriteRead <RpbIndexReq, RpbIndexResp>(message));

            if (result.IsSuccess)
            {
                return(RiakResult <IList <string> > .Success(result.Value.keys.Select(k => k.FromRiakString()).ToList()));
            }

            return(RiakResult <IList <string> > .Error(result.ResultCode, result.ErrorMessage, result.NodeOffline));
        }
Пример #19
0
        /// <summary>
        /// Retrieve arbitrarily deep list of links for a <see cref="RiakObject"/>
        /// </summary>
        /// <returns>
        /// A list of <see cref="RiakObject"/> identified by the list of links.
        /// </returns>
        /// <param name='riakObject'>
        /// The initial object to use for the beginning of the link walking.
        /// </param>
        /// <param name='riakLinks'>
        /// A list of link definitions
        /// </param>
        /// <remarks>Refer to http://wiki.basho.com/Links-and-Link-Walking.html for more information.</remarks>
        public RiakResult <IList <RiakObject> > WalkLinks(RiakObject riakObject, IList <RiakLink> riakLinks)
        {
            System.Diagnostics.Debug.Assert(riakLinks.Count > 0, "Link walking requires at least one link");

            var input = new RiakBucketKeyInput();

            input.AddBucketKey(riakObject.Bucket, riakObject.Key);

            var query = new RiakMapReduceQuery()
                        .Inputs(input);

            var lastLink = riakLinks.Last();

            foreach (var riakLink in riakLinks)
            {
                var link = riakLink;
                var keep = ReferenceEquals(link, lastLink);

                query.Link(l => l.FromRiakLink(link).Keep(keep));
            }

            var result = MapReduce(query);

            if (result.IsSuccess)
            {
                var linkResults       = result.Value.PhaseResults.GroupBy(r => r.Phase).Where(g => g.Key == riakLinks.Count - 1);
                var linkResultStrings = linkResults.SelectMany(lr => lr.ToList(), (lr, r) => new { lr, r })
                                        .SelectMany(@t => @t.r.Values, (@t, s) => s.FromRiakString());

                //var linkResultStrings = linkResults.SelectMany(g => g.Select(r => r.Values.Value.FromRiakString()));
                var rawLinks = linkResultStrings.SelectMany(RiakLink.ParseArrayFromJsonString).Distinct();
                var oids     = rawLinks.Select(l => new RiakObjectId(l.Bucket, l.Key)).ToList();

                var objects = Get(oids, new RiakGetOptions());

                // FIXME
                // we could be discarding results here. Not good?
                // This really should be a multi-phase map/reduce
                return(RiakResult <IList <RiakObject> > .Success(objects.Where(r => r.IsSuccess).Select(r => r.Value).ToList()));
            }
            return(RiakResult <IList <RiakObject> > .Error(result.ResultCode, result.ErrorMessage, result.NodeOffline));
        }
Пример #20
0
        private Task <RiakResult <IList <string> > > IndexGetRange(string bucket, string indexName, string minValue, string maxValue)
        {
            var message = new RpbIndexReq
            {
                bucket    = bucket.ToRiakString(),
                index     = indexName.ToRiakString(),
                qtype     = RpbIndexReq.IndexQueryType.range,
                range_min = minValue.ToRiakString(),
                range_max = maxValue.ToRiakString()
            };

            return(UseConnection(conn => conn.PbcWriteRead <RpbIndexReq, RpbIndexResp>(message))
                   .ContinueWith((Task <RiakResult <RpbIndexResp> > finishedTask) => {
                var result = finishedTask.Result;
                if (result.IsSuccess)
                {
                    return RiakResult <IList <string> > .Success(result.Value.keys.Select(k => k.FromRiakString()).ToList());
                }
                return RiakResult <IList <string> > .Error(result.ResultCode, result.ErrorMessage, result.NodeOffline);
            }));
        }
Пример #21
0
        /// <summary>
        /// Get the specified <paramref name="key"/> from the <paramref name="bucket"/>.
        /// Optionally can be read from <paramref name="rVal"/> instances. By default, the server's
        /// r-value will be used, but can be overridden by <paramref name="rVal"/>.
        /// </summary>
        /// <param name='bucket'>
        /// The name of the bucket containing the <paramref name="key"/>
        /// </param>
        /// <param name='key'>
        /// The key.
        /// </param>
        /// <param name='rVal'>
        /// The number of nodes required to successfully respond to the read before the read is considered a success.
        /// </param>
        /// <remarks>If a node does not respond, that does not necessarily mean that the
        /// <paramref name="bucket"/>/<paramref name="key"/> combination is not available. It simply means
        /// that less than <paramref name="rVal" /> nodes successfully responded to the read request. Unfortunatley,
        /// the Riak API does not allow us to distinguish between a 404 resulting from less than <paramref name="rVal"/>
        /// nodes successfully responding and a <paramref name="bucket"/>/<paramref name="key"/> combination
        /// not being found in Riak.
        /// </remarks>
        public RiakResult <RiakObject> Get(string bucket, string key, uint rVal = RiakConstants.Defaults.RVal)
        {
            var request = new RpbGetReq {
                Bucket = bucket.ToRiakString(), Key = key.ToRiakString(), R = rVal
            };
            var result = UseConnection(conn => conn.PbcWriteRead <RpbGetReq, RpbGetResp>(request));

            if (!result.IsSuccess)
            {
                return(RiakResult <RiakObject> .Error(result.ResultCode, result.ErrorMessage));
            }

            if (result.Value.VectorClock == null)
            {
                return(RiakResult <RiakObject> .Error(ResultCode.NotFound));
            }

            var o = new RiakObject(bucket, key, result.Value.Content, result.Value.VectorClock);

            return(RiakResult <RiakObject> .Success(o));
        }
Пример #22
0
        public override RiakResult <IEnumerable <TResult> > UseDelayedConnection <TResult>(Func <IRiakConnection, Action, RiakResult <IEnumerable <TResult> > > useFun, int retryAttempts)
        {
            if (retryAttempts < 0)
            {
                return(RiakResult <IEnumerable <TResult> > .Error(ResultCode.NoRetries, "Unable to access a connection on the cluster.", false));
            }
            if (_disposing)
            {
                return(RiakResult <IEnumerable <TResult> > .Error(ResultCode.ShuttingDown, "System currently shutting down", true));
            }

            var node = _loadBalancer.SelectNode();

            if (node != null)
            {
                var result = node.UseDelayedConnection(useFun);
                if (!result.IsSuccess)
                {
                    if (result.ResultCode == ResultCode.NoConnections)
                    {
                        Thread.Sleep(RetryWaitTime);
                        return(UseDelayedConnection(useFun, retryAttempts - 1));
                    }

                    if (result.ResultCode == ResultCode.CommunicationError)
                    {
                        if (result.NodeOffline)
                        {
                            DeactivateNode(node);
                        }

                        Thread.Sleep(RetryWaitTime);
                        return(UseDelayedConnection(useFun, retryAttempts - 1));
                    }
                }
                return(result);
            }
            return(RiakResult <IEnumerable <TResult> > .Error(ResultCode.ClusterOffline, "Unable to access functioning Riak node", true));
        }
Пример #23
0
        /// <summary>
        /// Reset the properties on a bucket back to their defaults.
        /// </summary>
        /// <param name="bucket">The name of the bucket to reset the properties on.</param>
        /// <returns>An indication of success or failure.</returns>
        /// <remarks>This function requires Riak v1.3+.</remarks>
        public RiakResult ResetBucketProperties(string bucket)
        {
            var request = new RiakRestRequest(ToBucketPropsUri(bucket), RiakConstants.Rest.HttpMethod.Delete);

            var result = UseConnection(conn => conn.RestRequest(request));

            if (result.IsSuccess)
            {
                switch (result.Value.StatusCode)
                {
                case HttpStatusCode.NoContent:
                    return(result);

                case HttpStatusCode.NotFound:
                    return(RiakResult.Error(ResultCode.NotFound, "Bucket {0} not found.".Fmt(bucket), false));

                default:
                    return(RiakResult.Error(ResultCode.InvalidResponse, "Unexpected Status Code: {0} ({1})".Fmt(result.Value.StatusCode, (int)result.Value.StatusCode), result.NodeOffline));
                }
            }
            return(result);
        }
Пример #24
0
        public Task <RiakResult <RiakObject> > Put(RiakObject value, RiakPutOptions options = null)
        {
            if (!IsValidBucketOrKey(value.Bucket))
            {
                return(RiakResult <RiakObject> .ErrorTask(ResultCode.InvalidRequest, InvalidBucketErrorMessage, false));
            }

            if (!IsValidBucketOrKey(value.Key))
            {
                return(RiakResult <RiakObject> .ErrorTask(ResultCode.InvalidRequest, InvalidKeyErrorMessage, false));
            }

            var request = value.ToMessage();

            options = options ?? new RiakPutOptions();
            options.Populate(request);

            return(UseConnection(conn => conn.PbcWriteRead <RpbPutReq, RpbPutResp>(request))
                   .ContinueWith((Task <RiakResult <RpbPutResp> > finishedTask) => {
                var result = finishedTask.Result;

                if (!result.IsSuccess)
                {
                    return RiakResult <RiakObject> .Error(result.ResultCode, result.ErrorMessage, result.NodeOffline);
                }

                var finalResult = options.ReturnBody
                        ? new RiakObject(value.Bucket, value.Key, result.Value.content.First(), result.Value.vclock)
                            : value;

                if (options.ReturnBody && result.Value.content.Count > 1)
                {
                    finalResult.Siblings = result.Value.content.Select(
                        c => new RiakObject(value.Bucket, value.Key, c, result.Value.vclock)).ToList();
                }

                return RiakResult <RiakObject> .Success(finalResult);
            }));
        }
Пример #25
0
        /// <summary>
        /// Delete the record identified by <paramref name="key"/> from a <paramref name="bucket"/>.
        /// </summary>
        /// <param name='bucket'>
        /// The name of the bucket that contains the record to be deleted.
        /// </param>
        /// <param name='key'>
        /// The key identifying the record to be deleted.
        /// </param>
        /// <param name='options'>
        /// Delete options
        /// </param>
        public RiakResult Delete(string bucket, string key, RiakDeleteOptions options = null)
        {
            if (!IsValidBucketOrKey(bucket))
            {
                return(RiakResult <RiakObject> .Error(ResultCode.InvalidRequest, InvalidBucketErrorMessage, false));
            }

            if (!IsValidBucketOrKey(key))
            {
                return(RiakResult <RiakObject> .Error(ResultCode.InvalidRequest, InvalidKeyErrorMessage, false));
            }

            options = options ?? new RiakDeleteOptions();

            var request = new RpbDelReq {
                bucket = bucket.ToRiakString(), key = key.ToRiakString()
            };

            options.Populate(request);
            var result = UseConnection(conn => conn.PbcWriteRead(request, MessageCode.DelResp));

            return(result);
        }
Пример #26
0
        public Task <T> Batch <T>(Func <IRiakBatchAsyncClient, Task <T> > batchFun)
        {
            var taskResult = default(T);

            // no idea what this is
            Func <IRiakConnection, Action, Task <RiakResult <IEnumerable <RiakResult <object> > > > > helperBatchFun = ((conn, onFinish) =>
            {
                return(Task.Factory.StartNew(() => batchFun(new RiakAsyncClient(conn))).Unwrap()
                       .ContinueWith((Task <T> finishedTask) => {
                    onFinish();

                    // exception or success
                    if (!finishedTask.IsFaulted)
                    {
                        taskResult = finishedTask.Result;
                        return RiakResult <IEnumerable <RiakResult <object> > > .Success(null);
                    }
                    else
                    {
                        var ex = finishedTask.Exception.Flatten().InnerExceptions.First();
                        return RiakResult <IEnumerable <RiakResult <object> > > .Error(
                            ResultCode.BatchException, "{0}\n{1}".Fmt(ex.Message, ex.StackTrace), true);
                    }
                }));
            });

            // apply task to connection
            return(_endPoint.UseDelayedConnection(helperBatchFun, RetryCount)
                   .ContinueWith((Task <RiakResult <IEnumerable <RiakResult <object> > > > finishedTask) => {
                var result = finishedTask.Result;
                if (!result.IsSuccess && result.ResultCode == ResultCode.BatchException)
                {
                    throw new Exception(result.ErrorMessage);
                }
                return taskResult;
            }));
        }
Пример #27
0
        /// <summary>
        /// Returns all properties for a <paramref name="bucket"/>.
        /// </summary>
        /// <returns>
        /// The bucket properties.
        /// </returns>
        /// <param name='bucket'>
        /// The Riak bucket.
        /// </param>
        /// <param name='extended'>
        /// Extended parameters are retrieved by HTTP requests.
        /// </param>
        public RiakResult <RiakBucketProperties> GetBucketProperties(string bucket, bool extended = false)
        {
            if (extended)
            {
                var request = new RiakRestRequest(ToBucketUri(bucket), RiakConstants.Rest.HttpMethod.Get)
                              .AddQueryParam(RiakConstants.Rest.QueryParameters.Bucket.GetPropertiesKey,
                                             RiakConstants.Rest.QueryParameters.Bucket.GetPropertiesValue);

                var result = UseConnection(conn => conn.RestRequest(request));

                if (result.IsSuccess)
                {
                    if (result.Value.StatusCode == HttpStatusCode.OK)
                    {
                        var response = new RiakBucketProperties(result.Value);
                        return(RiakResult <RiakBucketProperties> .Success(response));
                    }
                    return(RiakResult <RiakBucketProperties> .Error(ResultCode.InvalidResponse,
                                                                    "Unexpected Status Code: {0} ({1})".Fmt(result.Value.StatusCode, (int)result.Value.StatusCode)));
                }
                return(RiakResult <RiakBucketProperties> .Error(result.ResultCode, result.ErrorMessage));
            }
            else
            {
                var bpReq = new RpbGetBucketReq {
                    Bucket = bucket.ToRiakString()
                };
                var result = UseConnection(conn => conn.PbcWriteRead <RpbGetBucketReq, RpbGetBucketResp>(bpReq));

                if (result.IsSuccess)
                {
                    var props = new RiakBucketProperties(result.Value.Props);
                    return(RiakResult <RiakBucketProperties> .Success(props));
                }
                return(RiakResult <RiakBucketProperties> .Error(result.ResultCode, result.ErrorMessage));
            }
        }
Пример #28
0
        /// <summary>
        /// Retrieve multiple objects from Riak.
        /// </summary>
        /// <param name='bucketKeyPairs'>
        /// An <see href="System.Collections.Generic.IEnumerable&lt;T&gt;"/> of <see cref="CorrugatedIron.Models.RiakObjectId"/> to be retrieved
        /// </param>
        /// <param name='rVal'>
        /// The number of nodes required to successfully respond to the read before the read is considered a success.
        /// </param>
        public IEnumerable <RiakResult <RiakObject> > Get(IEnumerable <RiakObjectId> bucketKeyPairs,
                                                          uint rVal = RiakConstants.Defaults.RVal)
        {
            bucketKeyPairs = bucketKeyPairs.ToList();

            var requests = bucketKeyPairs.Select(bk => new RpbGetReq {
                Bucket = bk.Bucket.ToRiakString(), Key = bk.Key.ToRiakString(), R = rVal
            }).ToList();
            var results = UseConnection(conn =>
            {
                var responses = requests.Select(conn.PbcWriteRead <RpbGetReq, RpbGetResp>).ToList();
                return(RiakResult <IEnumerable <RiakResult <RpbGetResp> > > .Success(responses));
            });

            return(results.Value.Zip(bucketKeyPairs, Tuple.Create).Select(result =>
            {
                if (!result.Item1.IsSuccess)
                {
                    return RiakResult <RiakObject> .Error(result.Item1.ResultCode, result.Item1.ErrorMessage);
                }

                if (result.Item1.Value.VectorClock == null)
                {
                    return RiakResult <RiakObject> .Error(ResultCode.NotFound);
                }

                var o = new RiakObject(result.Item2.Bucket, result.Item2.Key, result.Item1.Value.Content.First(), result.Item1.Value.VectorClock);

                if (result.Item1.Value.Content.Count > 1)
                {
                    o.Siblings = result.Item1.Value.Content.Select(c =>
                                                                   new RiakObject(result.Item2.Bucket, result.Item2.Key, c, result.Item1.Value.VectorClock)).ToList();
                }

                return RiakResult <RiakObject> .Success(o);
            }));
        }
Пример #29
0
        public Task <RiakResult <RiakObject> > Get(string bucket, string key, RiakGetOptions options = null)
        {
            if (!IsValidBucketOrKey(bucket))
            {
                return(RiakResult <RiakObject> .ErrorTask(ResultCode.InvalidRequest, InvalidBucketErrorMessage, false));
            }

            if (!IsValidBucketOrKey(key))
            {
                return(RiakResult <RiakObject> .ErrorTask(ResultCode.InvalidRequest, InvalidKeyErrorMessage, false));
            }

            var request = new RpbGetReq {
                bucket = bucket.ToRiakString(), key = key.ToRiakString()
            };

            options = options ?? new RiakGetOptions();
            options.Populate(request);

            return(UseConnection(conn => conn.PbcWriteRead <RpbGetReq, RpbGetResp>(request))
                   .ContinueWith((Task <RiakResult <RpbGetResp> > finishedTask) => {
                var result = finishedTask.Result;
                if (!result.IsSuccess)
                {
                    return RiakResult <RiakObject> .Error(result.ResultCode, result.ErrorMessage, result.NodeOffline);
                }

                if (result.Value.vclock == null)
                {
                    return RiakResult <RiakObject> .Error(ResultCode.NotFound, "Unable to find value in Riak", false);
                }

                var o = new RiakObject(bucket, key, result.Value.content, result.Value.vclock);
                return RiakResult <RiakObject> .Success(o);
            }));
        }