Beispiel #1
0
        /// <summary>
        ///  Txn is used to apply multiple KV operations in a single, atomic transaction.
        /// </summary>
        /// <remarks>
        /// Transactions are defined as a
        /// list of operations to perform, using the KVOp constants and KVTxnOp structure
        /// to define operations. If any operation fails, none of the changes are applied
        /// to the state store. Note that this hides the internal raw transaction interface
        /// and munges the input and output types into KV-specific ones for ease of use.
        /// If there are more non-KV operations in the future we may break out a new
        /// transaction API client, but it will be easy to keep this KV-specific variant
        /// supported.
        ///
        /// Even though this is generally a write operation, we take a QueryOptions input
        /// and return a QueryMeta output. If the transaction contains only read ops, then
        /// Consul will fast-path it to a different endpoint internally which supports
        /// consistency controls, but not blocking. If there are write operations then
        /// the request will always be routed through raft and any consistency settings
        /// will be ignored.
        ///
        /// // If there is a problem making the transaction request then an error will be
        /// returned. Otherwise, the ok value will be true if the transaction succeeded
        /// or false if it was rolled back. The response is a structured return value which
        /// will have the outcome of the transaction. Its Results member will have entries
        /// for each operation. Deleted keys will have a nil entry in the, and to save
        /// space, the Value of each key in the Results will be nil unless the operation
        /// is a KVGet. If the transaction was rolled back, the Errors member will have
        /// entries referencing the index of the operation that failed along with an error
        /// message.
        /// </remarks>
        /// <param name="txn">The constructed transaction</param>
        /// <param name="q">Customized write options</param>
        /// <param name="ct">A CancellationToken to prematurely end the request</param>
        /// <returns>The transaction response</returns>
        public async Task <WriteResult <KVTxnResponse> > Txn(List <KVTxnOp> txn, WriteOptions q, CancellationToken ct = default(CancellationToken))
        {
            var txnOps = new List <TxnOp>(txn.Count);

            foreach (var kvTxnOp in txn)
            {
                txnOps.Add(new TxnOp()
                {
                    KV = kvTxnOp
                });
            }

            var req    = _client.Put <List <TxnOp>, KVTxnResponse>("/v1/txn", txnOps, q);
            var txnRes = await req.Execute(ct);

            var res = new WriteResult <KVTxnResponse>(txnRes, txnRes.Response);

            res.Response.Success = txnRes.StatusCode == System.Net.HttpStatusCode.OK;

            return(res);
        }
        /// <summary>
        /// Execute the POST request to the API
        /// </summary>
        /// <param name="ct">Cancellation token for long poll request. If set, OperationCanceledException will be thrown if the request is cancelled before completing</param>
        /// <returns>The result of the POST, including a deserialised generic type object</returns>
        public async Task <WriteResult <TOut> > Execute(CancellationToken ct)
        {
            Client.CheckDisposed();
            var timer  = Stopwatch.StartNew();
            var result = new WriteResult <TOut>();

            HttpContent content = null;

            var message = new HttpRequestMessage(HttpMethod.Post, BuildConsulUri(Endpoint, Params));

            ApplyHeaders(message, Client.Config);
            message.Content = content;
            var response = await Client.HttpClient.SendAsync(message, ct).ConfigureAwait(false);

            result.StatusCode = response.StatusCode;

            ResponseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);

            if (response.StatusCode != HttpStatusCode.NotFound && !response.IsSuccessStatusCode)
            {
                if (ResponseStream == null)
                {
                    throw new ConsulRequestException(string.Format("Unexpected response, status code {0}",
                                                                   response.StatusCode), response.StatusCode);
                }
                using (var sr = new StreamReader(ResponseStream))
                {
                    throw new ConsulRequestException(string.Format("Unexpected response, status code {0}: {1}",
                                                                   response.StatusCode, sr.ReadToEnd()), response.StatusCode);
                }
            }

            if (response.IsSuccessStatusCode)
            {
                result.Response = Deserialize <TOut>(ResponseStream);
            }

            result.RequestTime = timer.Elapsed;
            return(result);
        }
Beispiel #3
0
        public async Task <WriteResult <TOut> > Execute(CancellationToken ct)
        {
            Client.CheckDisposed();
            timer.Start();
            var result = new WriteResult <TOut>();

            var response = await Client.HttpClient.DeleteAsync(BuildConsulUri(Endpoint, Params), ct).ConfigureAwait(false);

            result.StatusCode = response.StatusCode;

            ResponseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);

            if (response.StatusCode != HttpStatusCode.NotFound && !response.IsSuccessStatusCode)
            {
                if (ResponseStream == null)
                {
                    throw new ConsulRequestException(string.Format("Unexpected response, status code {0}",
                                                                   response.StatusCode));
                }
                using (var sr = new StreamReader(ResponseStream))
                {
                    throw new ConsulRequestException(string.Format("Unexpected response, status code {0}: {1}",
                                                                   response.StatusCode, sr.ReadToEnd()));
                }
            }

            if (response.IsSuccessStatusCode)
            {
                result.Response = Deserialize <TOut>(ResponseStream);
            }

            result.RequestTime = timer.Elapsed;
            timer.Stop();

            return(result);
        }
Beispiel #4
0
 public WriteResult(WriteResult other) : base(other)
 {
 }