/// <summary> /// Subscribes received ovserver to the given request, intended to be used for EventSource connections /// </summary> /// <param name="request">EventSource request</param> /// <param name="observer">Observer that will treat events</param> private void SubscribeToServerEvents(HttpJsonRequest request, IObserver <string> observer) { var serverPullTask = request.ServerPullAsync(); serverPullTask.Wait(); var serverEvents = serverPullTask.Result; currentSubscription = serverEvents.Subscribe(observer); }
public void AddHeaders(HttpJsonRequest httpJsonRequest, AsyncServerClient serverClient, string currentUrl) { httpJsonRequest.AddHeader(Constants.Cluster.ClusterAwareHeader, "true"); if (serverClient.ClusterBehavior == ClusterBehavior.ReadFromAllWriteToLeader) httpJsonRequest.AddHeader(Constants.Cluster.ClusterReadBehaviorHeader, "All"); if (serverClient.ClusterBehavior == ClusterBehavior.ReadFromAllWriteToLeaderWithFailovers || serverClient.ClusterBehavior == ClusterBehavior.ReadFromLeaderWriteToLeaderWithFailovers) httpJsonRequest.AddHeader(Constants.Cluster.ClusterFailoverBehaviorHeader, "true"); }
public async Task <SynchronizationReport> PushChangesAsync(CancellationToken token) { token.Register(() => { }); //request.Abort() TODO: check this token.ThrowIfCancellationRequested(); if (sourceStream.CanRead == false) { throw new Exception("Stream does not support reading"); } var commands = (IAsyncFilesCommandsImpl)this.destination.Commands; var baseUrl = commands.UrlFor(); var credentials = commands.PrimaryCredentials; var conventions = commands.Conventions; request = commands.RequestFactory.CreateHttpJsonRequest( new CreateHttpJsonRequestParams(this, baseUrl + "/synchronization/MultipartProceed", "POST", credentials, conventions)); // REVIEW: (Oren) There is a mismatch of expectations in the AddHeaders. ETag must always have to be surrounded by quotes. // If AddHeader/s ever put an etag it should check for that. // I was hesitant to do the change though, because I do not understand the complete scope of such a change. request.AddHeaders(sourceMetadata); request.AddHeader("Content-Type", "multipart/form-data; boundary=" + syncingBoundary); request.AddHeader(SyncingMultipartConstants.FileName, fileName); request.AddHeader(SyncingMultipartConstants.SourceServerInfo, serverInfo.AsJson()); try { await request.WriteAsync(PrepareMultipartContent(token)); var response = await request.ReadResponseJsonAsync(); return(new JsonSerializer().Deserialize <SynchronizationReport>(new RavenJTokenReader(response))); } catch (Exception exception) { if (token.IsCancellationRequested) { throw new OperationCanceledException(token); } var webException = exception as ErrorResponseException; if (webException != null) { webException.SimplifyException(); } throw; } }
/// <summary> /// Begins an async get operation /// </summary> /// <param name="key">The key.</param> /// <returns></returns> public Task <JsonDocument> GetAsync(string key) { EnsureIsNotNullOrEmpty(key, "key"); var metadata = new JObject(); AddTransactionInformation(metadata); var request = HttpJsonRequest.CreateHttpJsonRequest(this, url + "/docs/" + key, "GET", metadata, credentials, convention); return(Task.Factory.FromAsync <string>(request.BeginReadResponseString, request.EndReadResponseString, null) .ContinueWith(task => { try { var responseString = task.Result; return new JsonDocument { DataAsJson = JObject.Parse(responseString), NonAuthoritiveInformation = request.ResponseStatusCode == HttpStatusCode.NonAuthoritativeInformation, Key = key, LastModified = DateTime.ParseExact(request.ResponseHeaders["Last-Modified"], "r", CultureInfo.InvariantCulture), Etag = new Guid(request.ResponseHeaders["ETag"]), Metadata = request.ResponseHeaders.FilterHeaders(isServerDocument: false) }; } catch (WebException e) { var httpWebResponse = e.Response as HttpWebResponse; if (httpWebResponse == null) { throw; } if (httpWebResponse.StatusCode == HttpStatusCode.NotFound) { return null; } if (httpWebResponse.StatusCode == HttpStatusCode.Conflict) { var conflicts = new StreamReader(httpWebResponse.GetResponseStreamWithHttpDecompression()); var conflictsDoc = JObject.Load(new JsonTextReader(conflicts)); var conflictIds = conflictsDoc.Value <JArray>("Conflicts").Select(x => x.Value <string>()).ToArray(); throw new ConflictException("Conflict detected on " + key + ", conflict must be resolved before the document will be accessible") { ConflictedVersionIds = conflictIds }; } throw; } })); }
/// <summary> /// Puts the document with the specified key in the database /// </summary> /// <param name="key">The key.</param> /// <param name="etag">The etag.</param> /// <param name="document">The document.</param> /// <param name="metadata">The metadata.</param> public Task <PutResult> PutAsync(string key, Guid?etag, JObject document, JObject metadata) { if (metadata == null) { metadata = new JObject(); } var method = String.IsNullOrEmpty(key) ? "POST" : "PUT"; if (etag != null) { metadata["ETag"] = new JValue(etag.Value.ToString()); } var request = HttpJsonRequest.CreateHttpJsonRequest(this, url + "/docs/" + key, method, metadata, credentials, convention); request.AddOperationHeaders(OperationsHeaders); return(request.WriteAsync(Encoding.UTF8.GetBytes(document.ToString())) .ContinueWith(task => { if (task.Exception != null) { throw new InvalidOperationException("Unable to write to server"); } return request.ReadResponseStringAsync() .ContinueWith(task1 => { try { return JsonConvert.DeserializeObject <PutResult>(task1.Result, new JsonEnumConverter()); } catch (AggregateException e) { var webexception = e.ExtractSingleInnerException() as WebException; if (ShouldThrowForPutAsync(webexception)) { throw; } throw ThrowConcurrencyException(webexception); } catch (WebException e) { if (ShouldThrowForPutAsync(e)) { throw; } throw ThrowConcurrencyException(e); } }); }) .Unwrap()); }
/// <summary> /// Puts the index definition for the specified name asyncronously /// </summary> /// <param name="name">The name.</param> /// <param name="indexDef">The index def.</param> /// <param name="overwrite">Should overwrite index</param> public Task <string> PutIndexAsync(string name, IndexDefinition indexDef, bool overwrite) { string requestUri = url + "/indexes/" + Uri.EscapeUriString(name); var webRequest = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(new Uri(requestUri)); AddOperationHeaders(webRequest); webRequest.Method = "HEAD"; webRequest.Credentials = credentials; return(webRequest.GetResponseAsync() .ContinueWith(task => { try { task.Result.Close(); if (overwrite == false) { throw new InvalidOperationException("Cannot put index: " + name + ", index already exists"); } } catch (AggregateException e) { var webException = e.ExtractSingleInnerException() as WebException; if (ShouldThrowForPutIndexAsync(webException)) { throw; } } catch (WebException e) { if (ShouldThrowForPutIndexAsync(e)) { throw; } } var request = HttpJsonRequest.CreateHttpJsonRequest(this, requestUri, "PUT", credentials, convention); request.AddOperationHeaders(OperationsHeaders); var serializeObject = JsonConvert.SerializeObject(indexDef, new JsonEnumConverter()); return request .WriteAsync(Encoding.UTF8.GetBytes(serializeObject)) .ContinueWith(writeTask => request.ReadResponseStringAsync() .ContinueWith(readStrTask => { //NOTE: JsonConvert.DeserializeAnonymousType() doesn't work in Silverlight because the ctr is private! var obj = JsonConvert.DeserializeObject <IndexContainer>(readStrTask.Result); return obj.Index; })).Unwrap(); }).Unwrap()); }
private async Task StartBulkInsertAsync(BulkInsertOptions options) { using (ConnectionOptions.Expect100Continue(operationClient.Url)) { var operationUrl = CreateOperationUrl(options); var token = await GetToken().ConfigureAwait(false); try { token = await ValidateThatWeCanUseAuthenticateTokens(token).ConfigureAwait(false); } catch (Exception e) { throw new InvalidOperationException("Could not authenticate token for bulk insert, if you are using ravendb in IIS make sure you have Anonymous Authentication enabled in the IIS configuration", e); } using (operationRequest = CreateOperationRequest(operationUrl, token)) { var cancellationToken = CreateCancellationToken(); var response = await operationRequest.ExecuteRawRequestAsync((stream, source) => Task.Factory.StartNew(() => { try { WriteQueueToServer(stream, options, cancellationToken); var x = source.TrySetResult(null); } catch (Exception e) { source.TrySetException(e); } }, TaskCreationOptions.LongRunning)).ConfigureAwait(false); await response.AssertNotFailingResponse(); long operationId; using (response) using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) using (var streamReader = new StreamReader(stream)) { var result = RavenJObject.Load(new JsonTextReader(streamReader)); operationId = result.Value <long>("OperationId"); } if (await IsOperationCompleted(operationId).ConfigureAwait(false)) { responseOperationId = operationId; } } } }
public void AddHeaders(HttpJsonRequest httpJsonRequest, AsyncServerClient serverClient, string currentUrl, bool withClusterFailoverHeader = false) { httpJsonRequest.AddHeader(Constants.Cluster.ClusterAwareHeader, "true"); if (serverClient.convention.FailoverBehavior == FailoverBehavior.ReadFromAllWriteToLeader) { httpJsonRequest.AddHeader(Constants.Cluster.ClusterReadBehaviorHeader, "All"); } if (withClusterFailoverHeader) { httpJsonRequest.AddHeader(Constants.Cluster.ClusterFailoverBehaviorHeader, "true"); } }
/// <summary> /// Deletes the attachment with the specified key asyncronously /// </summary> /// <param name="key">The key.</param> /// <param name="etag">The etag.</param> public Task DeleteAttachmentAsync(string key, Guid?etag) { var metadata = new JObject(); if (etag != null) { metadata["ETag"] = new JValue(etag.Value.ToString()); } var request = HttpJsonRequest.CreateHttpJsonRequest(this, url.Static(key), "DELETE", metadata, credentials, convention); request.AddOperationHeaders(OperationsHeaders); return(request.ReadResponseStringAsync()); }
/// <summary> /// Puts the document with the specified key in the database /// </summary> /// <param name="key">The key.</param> /// <param name="etag">The etag.</param> /// <param name="document">The document.</param> /// <param name="metadata">The metadata.</param> public Task <PutResult> PutAsync(string key, Guid?etag, JObject document, JObject metadata) { if (metadata == null) { metadata = new JObject(); } var method = String.IsNullOrEmpty(key) ? "POST" : "PUT"; if (etag != null) { metadata["ETag"] = new JValue(etag.Value.ToString()); } var request = HttpJsonRequest.CreateHttpJsonRequest(this, url + "/docs/" + key, method, metadata, credentials, convention); request.AddOperationHeaders(OperationsHeaders); var bytes = Encoding.UTF8.GetBytes(document.ToString()); return(Task.Factory.FromAsync(request.BeginWrite, request.EndWrite, bytes, null) .ContinueWith(task => { if (task.Exception != null) { throw new InvalidOperationException("Unable to write to server"); } return Task.Factory.FromAsync <string>(request.BeginReadResponseString, request.EndReadResponseString, null) .ContinueWith(task1 => { try { return JsonConvert.DeserializeObject <PutResult>(task1.Result, new JsonEnumConverter()); } catch (WebException e) { var httpWebResponse = e.Response as HttpWebResponse; if (httpWebResponse == null || httpWebResponse.StatusCode != HttpStatusCode.Conflict) { throw; } throw ThrowConcurrencyException(e); } }); }) .Unwrap()); }
public void AddHeaders(HttpJsonRequest httpJsonRequest, AsyncServerClient serverClient, string currentUrl) { if (serverClient.Url.Equals(currentUrl, StringComparison.OrdinalIgnoreCase)) { return; } if (ReplicationInformer.FailureCounters.GetFailureCount(serverClient.Url) <= 0) { return; // not because of failover, no need to do this. } var lastPrimaryCheck = ReplicationInformer.FailureCounters.GetFailureLastCheck(serverClient.Url); httpJsonRequest.AddHeader(Constants.Headers.RavenClientPrimaryServerUrl, ToRemoteUrl(serverClient.Url)); httpJsonRequest.AddHeader(Constants.Headers.RavenClientPrimaryServerLastCheck, lastPrimaryCheck.ToString("s")); httpJsonRequest.AddReplicationStatusChangeBehavior(serverClient.Url, currentUrl, HandleReplicationStatusChanges); }
public IAsyncResult BeginQuery(string index, IndexQuery query, AsyncCallback callback, object state) { EnsureIsNotNullOrEmpty(index, "index"); string path = query.GetIndexQueryUrl(url, index, "indexes"); var request = HttpJsonRequest.CreateHttpJsonRequest(this, path, "GET", credentials); var asyncCallback = callback; if (callback != null) { asyncCallback = ar => callback(new UserAsyncData(request, ar)); } var asyncResult = request.BeginReadResponseString(asyncCallback, state); return(new UserAsyncData(request, asyncResult)); }
/// <summary> /// Gets the indexes from the server asyncronously /// </summary> /// <param name="start">Paging start</param> /// <param name="pageSize">Size of the page.</param> public Task <IndexDefinition[]> GetIndexesAsync(int start, int pageSize) { var request = HttpJsonRequest.CreateHttpJsonRequest(this, url + "/indexes/?start=" + start + "&pageSize=" + pageSize, "GET", credentials, convention); return(request.ReadResponseStringAsync() .ContinueWith(task => { var serializer = convention.CreateSerializer(); using (var reader = new JsonTextReader(new StringReader(task.Result))) { var json = (JToken)serializer.Deserialize(reader); //NOTE: To review, I'm not confidence this is the correct way to deserialize the index definition return json .Select(x => JsonConvert.DeserializeObject <IndexDefinition>(x["definition"].ToString())) .ToArray(); } })); }
/// <summary> /// Begins the async query. /// </summary> /// <param name="query">A string representation of a Linq query</param> public Task <QueryResult> LinearQueryAsync(string linq, int start, int pageSize) { var query = @"{ Query: '" + linq + @"', Start: " + start + @", PageSize: " + pageSize + @" }" ; var metadata = new JObject(); var request = HttpJsonRequest.CreateHttpJsonRequest(this, url + "/linearQuery", "POST", metadata, credentials, convention); request.AddOperationHeaders(OperationsHeaders); return(request .WriteAsync(Encoding.UTF8.GetBytes(query)) .ContinueWith(write => { if (write.Exception != null) { throw new InvalidOperationException("Unable to write to server"); } return request.ReadResponseStringAsync(); }) .ContinueWith(task => { JToken json; using (var reader = new JsonTextReader(new StringReader(task.Result.Result))) json = (JToken)convention.CreateSerializer().Deserialize(reader); //TODO: the json includes LastScanResults and Errors, but it doesn't include the commented out properties below. // Should this change? return new QueryResult { //IsStale = Convert.ToBoolean(json["IsStale"].ToString()), //IndexTimestamp = json.Value<DateTime>("IndexTimestamp"), //IndexEtag = new Guid(request.ResponseHeaders["ETag"].First()), Results = json["Results"].Children().Cast <JObject>().ToList(), TotalResults = Convert.ToInt32(json["TotalResults"].ToString()), //SkippedResults = Convert.ToInt32(json["SkippedResults"].ToString()), //Includes = json["Includes"].Children().Cast<JObject>().ToList(), }; })); }
public bool CanFullyCache(HttpJsonRequestFactory jsonRequestFactory, HttpJsonRequest httpJsonRequest, string postedData) { if (allRequestsCanBeServedFromAggressiveCache) // can be fully served from aggressive cache { jsonRequestFactory.InvokeLogRequest(holdProfilingInformation, () => new RequestResultArgs { DurationMilliseconds = httpJsonRequest.CalculateDuration(), Method = httpJsonRequest.Method, HttpResult = 0, Status = RequestStatus.AggressivelyCached, Result = "", Url = httpJsonRequest.Url.ToString(), //TODO: check that is the same as: Url = httpJsonRequest.webRequest.RequestUri.PathAndQuery, PostedData = postedData }); return true; } return false; }
public IAsyncResult BeginMultiGet(string[] keys, AsyncCallback callback, object state) { var request = HttpJsonRequest.CreateHttpJsonRequest(this, url + "/queries/", "POST", credentials); var array = Encoding.UTF8.GetBytes(new JArray(keys).ToString(Formatting.None)); var multiStepAsyncResult = new MultiStepAsyncResult(state, request); var asyncResult = request.BeginWrite(array, ContinueOperation, new Contiuation { Callback = callback, State = state, Request = request, MultiAsyncResult = multiStepAsyncResult }); if (asyncResult.CompletedSynchronously) { ContinueOperation(asyncResult); } return(multiStepAsyncResult); }
/// <summary> /// Puts the index definition for the specified name asyncronously /// </summary> /// <param name="name">The name.</param> /// <param name="indexDef">The index def.</param> /// <param name="overwrite">Should overwrite index</param> public Task <string> PutIndexAsync(string name, IndexDefinition indexDef, bool overwrite) { string requestUri = url + "/indexes/" + name; var webRequest = (HttpWebRequest)WebRequest.Create(requestUri); AddOperationHeaders(webRequest); webRequest.Method = "HEAD"; webRequest.Credentials = credentials; return(webRequest.GetResponseAsync() .ContinueWith(task => { try { task.Result.Close(); if (overwrite == false) { throw new InvalidOperationException("Cannot put index: " + name + ", index already exists"); } } catch (WebException e) { var response = e.Response as HttpWebResponse; if (response == null || response.StatusCode != HttpStatusCode.NotFound) { throw; } } var request = HttpJsonRequest.CreateHttpJsonRequest(this, requestUri, "PUT", credentials, convention); request.AddOperationHeaders(OperationsHeaders); var serializeObject = JsonConvert.SerializeObject(indexDef, new JsonEnumConverter()); byte[] bytes = Encoding.UTF8.GetBytes(serializeObject); return Task.Factory.FromAsync(request.BeginWrite, request.EndWrite, bytes, null) .ContinueWith(writeTask => Task.Factory.FromAsync <string>(request.BeginReadResponseString, request.EndReadResponseString, null) .ContinueWith(readStrTask => { var obj = new { index = "" }; obj = JsonConvert.DeserializeAnonymousType(readStrTask.Result, obj); return obj.index; })).Unwrap(); }).Unwrap()); }
public RemoteBulkInsertOperation(BulkInsertOptions options, ServerClient client) { this.options = options; this.client = client; items = new BlockingCollection <RavenJObject>(options.BatchSize * 8); string requestUrl = "/bulkInsert?"; if (options.CheckForUpdates) { requestUrl += "checkForUpdates=true"; } if (options.CheckReferencesInIndexes) { requestUrl += "&checkReferencesInIndexes=true"; } var expect100Continue = client.Expect100Continue(); // this will force the HTTP layer to authenticate, meaning that our next request won't have to HttpJsonRequest req = client.CreateRequest("POST", requestUrl + "&no-op=for-auth-only", disableRequestCompression: true); req.PrepareForLongRequest(); req.ExecuteRequest(); httpJsonRequest = client.CreateRequest("POST", requestUrl, disableRequestCompression: true); // the request may take a long time to process, so we need to set a large timeout value httpJsonRequest.PrepareForLongRequest(); nextTask = httpJsonRequest.GetRawRequestStream() .ContinueWith(task => { try { expect100Continue.Dispose(); } catch (Exception) { } WriteQueueToServer(task); }); }
private async Task StartBulkInsertAsync(BulkInsertOptions options) { #if !SILVERLIGHT var expect100Continue = operationClient.Expect100Continue(); #endif var operationUrl = CreateOperationUrl(options); var token = await GetToken(operationUrl); try { token = await ValidateThatWeCanUseAuthenticateTokens(operationUrl, token); } catch (Exception e) { throw new InvalidOperationException( "Could not authenticate token for bulk insert, if you are using ravendb in IIS make sure you have Anonymous Authentication enabled in the IIS configuration", e); } operationRequest = CreateOperationRequest(operationUrl, token); var stream = await operationRequest.GetRawRequestStream(); #if !SILVERLIGHT try { if (expect100Continue != null) { expect100Continue.Dispose(); } } catch { } #endif var cancellationToken = CreateCancellationToken(); await Task.Factory.StartNew(() => WriteQueueToServer(stream, options, cancellationToken), TaskCreationOptions.LongRunning); }
public SendCustomRequest() { using (var store = new DocumentStore()) { #region custom_request_1 string key = "employees/1"; // http://localhost:8080/databases/Northwind/docs/employees/1 string url = store.Url // http://localhost:8080 .ForDatabase("Northwind") // /databases/Northwind .Doc(key); // /docs/employees/1 IDatabaseCommands commands = store.DatabaseCommands; using (HttpJsonRequest request = store .JsonRequestFactory .CreateHttpJsonRequest(new CreateHttpJsonRequestParams(commands, url, "GET", commands.PrimaryCredentials, store.Conventions))) { RavenJToken json = request.ReadResponseJson(); JsonDocument jsonDocument = SerializationHelper .DeserializeJsonDocument(key, json, request.ResponseHeaders, request.ResponseStatusCode); } #endregion } }
public async Task <IEnumerable <NamedApiKeyDefinition> > GetAllApiKeys() { HttpJsonRequest request = null; HttpResponseMessage resp = null; Stream stream; try { request = adminRequest.CreateStreamApiKeysRequest(); resp = await request.ExecuteRawResponseAsync(); await resp.AssertNotFailingResponse().ConfigureAwait(false); stream = await resp.GetResponseStreamWithHttpDecompression(); return(YieldResults(stream, request)); // stream and request - must be disposed manually when YieldResults finishes } catch (Exception) { request?.Dispose(); resp?.Dispose(); throw; } }
public RemoteBulkInsertOperation(BulkInsertOptions options, ServerClient client) { this.options = options; this.client = client; items = new BlockingCollection<RavenJObject>(options.BatchSize*8); string requestUrl = "/bulkInsert?"; if (options.CheckForUpdates) requestUrl += "checkForUpdates=true"; if (options.CheckReferencesInIndexes) requestUrl += "&checkReferencesInIndexes=true"; var expect100Continue = client.Expect100Continue(); // this will force the HTTP layer to authenticate, meaning that our next request won't have to HttpJsonRequest req = client.CreateRequest("POST", requestUrl + "&no-op=for-auth-only", disableRequestCompression: true); req.PrepareForLongRequest(); req.ExecuteRequest(); httpJsonRequest = client.CreateRequest("POST", requestUrl, disableRequestCompression: true); // the request may take a long time to process, so we need to set a large timeout value httpJsonRequest.PrepareForLongRequest(); nextTask = httpJsonRequest.GetRawRequestStream() .ContinueWith(task => { try { expect100Continue.Dispose(); } catch (Exception) { } WriteQueueToServer(task); }); }
public UserAsyncData(HttpJsonRequest request, IAsyncResult result) { Request = request; Result = result; }
public MultiStepAsyncResult(object state, HttpJsonRequest req) { this.state = state; this.req = req; manualResetEvent = new ManualResetEvent(false); }
/// <summary> /// Initializes a new instance of the <see cref="MultiStepAsyncResult"/> class. /// </summary> /// <param name="state">The state.</param> /// <param name="req">The request</param> public MultiStepAsyncResult(object state, HttpJsonRequest req) { this.state = state; this.req = req; manualResetEvent = new ManualResetEvent(false); }
protected StreamEnumerator(HttpJsonRequest request, Stream stream) { this.enumerator = new YieldStreamResults(request, stream); }
public HttpJsonRequest CreateHttpJsonRequest(CreateHttpJsonRequestParams createHttpJsonRequestParams) { var request = new HttpJsonRequest(createHttpJsonRequestParams.Url, createHttpJsonRequestParams.Method, createHttpJsonRequestParams.Metadata, createHttpJsonRequestParams.Convention, this); ConfigureRequest(createHttpJsonRequestParams.Owner, new WebRequestEventArgs {Client = request.httpClient}); return request; }
public CachingOfDocumentInclude() { HttpJsonRequest.ResetCache(); }
public CounterSummaryEnumerator(HttpJsonRequest request, Stream stream) : base(request, stream) { }
public static HttpJsonRequest ToJsonRequest(this string url, object requestor, ICredentials credentials, Document.DocumentConvention convention) { return(HttpJsonRequest.CreateHttpJsonRequest(requestor, url, "GET", credentials, convention)); }
public CachingOfDocumentLoad() { HttpJsonRequest.ResetCache(); }
public CounterGroupEnumerator(HttpJsonRequest request, Stream stream) : base(request, stream) { }