protected virtual Task <OrientdbResponse <Stream> > DoAsyncRequest(HttpWebRequest request, byte[] data = null, IRequestConfiguration requestSpecificConfig = null) { var tcs = new TaskCompletionSource <OrientdbResponse <Stream> >(); if (ConnectionSettings.MaximumAsyncConnections <= 0 || _resourceLock == null) { return(CreateIterateTask(request, data, requestSpecificConfig, tcs)); } int timeout = GetRequestTimeout(requestSpecificConfig); string path = request.RequestUri.ToString(); string method = request.Method; if (!_resourceLock.WaitOne(timeout)) { string m = "Could not start the operation before the timeout of " + timeout + "ms completed while waiting for the semaphore"; OrientdbResponse <Stream> cs = OrientdbResponse <Stream> .CreateError(ConnectionSettings, new TimeoutException(m), method, path, data); tcs.SetResult(cs); return(tcs.Task); } try { return(CreateIterateTask(request, data, requestSpecificConfig, tcs)); } finally { _resourceLock.Release(); } }
public void OrientdbResponseOfDynamicDictionaryTest() { OrientdbResponse <DynamicDictionary> response = _orientdbClient.Command("select from OUser", _databaseName, CommandLanguage.Sql); Assert.IsNotNull(response); Assert.AreEqual(200, response.HttpStatusCode); }
protected OrientdbResponse <T> StreamToTypedResponse <T>( OrientdbResponse <Stream> streamResponse, ITransportRequestState requestState, byte[] readBytes ) { //set response if (typeof(T) == typeof(string) || typeof(T) == typeof(byte[])) { OrientdbResponse <T> clone = OrientdbResponse.CloneFrom(streamResponse, default(T)); SetStringOrByteResult(clone, readBytes); return(clone); } OrientdbResponse <T> typedResponse = OrientdbResponse.CloneFrom(streamResponse, default(T)); using (streamResponse.Response) { Func <IOrientdbResponse, Stream, object> deserializationState = requestState.ResponseCreationOverride; var customConverter = deserializationState as Func <IOrientdbResponse, Stream, T>; if (customConverter != null) { T t = customConverter(typedResponse, streamResponse.Response); typedResponse.Response = t; return(typedResponse); } var deserialized = _serializer.Deserialize <T>(streamResponse.Response); typedResponse.Response = deserialized; return(typedResponse); } }
protected void OptionallyCloseResponseStreamAndSetSuccess <T>( ITransportRequestState requestState, OrientdbServerError error, OrientdbResponse <T> typedResponse, OrientdbResponse <Stream> streamResponse) { if (streamResponse.Response != null && !typeof(Stream).IsAssignableFrom(typeof(T))) { streamResponse.Response.Close(); } if (error != null) { typedResponse.Success = false; if (typedResponse.OriginalException == null) { typedResponse.OriginalException = new OrientdbServerException(error); } } //TODO UNIT TEST OR BEGONE if (!typedResponse.Success && requestState.RequestConfiguration != null && requestState.RequestConfiguration.AllowedStatusCodes.HasAny(i => i == streamResponse.HttpStatusCode)) { typedResponse.Success = true; } }
private OrientdbResponse <T> CoordinateRequest <T>(TransportRequestState <T> requestState, int maxRetries, int retried, ref bool aliveResponse) { OrientdbResponse <T> pingRetryRequest = SelectNextNode(requestState); if (pingRetryRequest != null) { return(pingRetryRequest); } OrientdbResponse <Stream> streamResponse = DoOrientdbCall(requestState); aliveResponse = streamResponse.SuccessOrKnownError; if (!DoneProcessing(streamResponse, requestState, maxRetries, retried)) { return(null); } OrientdbServerError error = null; OrientdbResponse <T> typedResponse = ReturnStreamOrVoidResponse(requestState, streamResponse) ?? ReturnTypedResponse(requestState, streamResponse, out error); OptionallyCloseResponseStreamAndSetSuccess(requestState, error, typedResponse, streamResponse); if (error != null && _settings.ThrowOnOrientdbServerExceptions) { throw new OrientdbServerException(error); } return(typedResponse); }
public void GetQueryTest() { OrientdbResponse <BaseResult <Foo> > response = _orientdbClient.GetQuery <BaseResult <Foo> >("select * from Foo", _databaseName, CommandLanguage.Sql); Assert.IsNotNull(response); Assert.AreEqual(200, response.HttpStatusCode); }
public void OrientdbResponseOfTTest() { OrientdbResponse <BaseResult <OUser> > response = _orientdbClient.Command <BaseResult <OUser> >("select from OUser", _databaseName, CommandLanguage.Sql); Assert.IsNotNull(response); Assert.AreEqual(200, response.HttpStatusCode); Assert.AreEqual(3, response.Response.Result.Count); }
private OrientdbResponse <T> DoRequest <T>(TransportRequestState <T> requestState) { OrientdbResponse <T> sniffAuthResponse = TrySniffOnStaleClusterState(requestState); if (sniffAuthResponse != null) { return(sniffAuthResponse); } bool aliveResponse = false; bool seenError = false; int retried = requestState.Retried; int maxRetries = _delegator.GetMaximumRetries(requestState.RequestConfiguration); try { OrientdbResponse <T> response = CoordinateRequest(requestState, maxRetries, retried, ref aliveResponse); if (response != null) { return(response); } } catch (OrientdbAuthenticationException e) { return(HandleAuthenticationException(requestState, e)); } catch (MaxRetryException) { //TODO ifdef ExceptionDispatchInfo.Capture(ex).Throw(); throw; } catch (OrientdbServerException) { //TODO ifdef ExceptionDispatchInfo.Capture(ex).Throw(); throw; } catch (Exception e) { requestState.SeenExceptions.Add(e); if (!requestState.UsingPooling || maxRetries == 0 && retried == 0) { //TODO ifdef ExceptionDispatchInfo.Capture(ex).Throw(); throw; } seenError = true; return(RetryRequest(requestState)); } finally { //make sure we always call markalive on the uri if the connection was succesful if (!seenError && aliveResponse) { _connectionPool.MarkAlive(requestState.CurrentNode); } } return(RetryRequest(requestState)); }
private OrientdbResponse <Stream> WebToOrientdbResponse(byte[] data, Stream responseStream, HttpWebResponse response, string method, string path) { OrientdbResponse <Stream> cs = OrientdbResponse <Stream> .Create(ConnectionSettings, (int)response.StatusCode, method, path, data); cs.Response = responseStream; return(cs); }
protected override Task <OrientdbResponse <Stream> > DoAsyncRequest(HttpWebRequest request, byte[] data = null, IRequestConfiguration requestSpecificConfig = null) { return(Task.Factory.StartNew(() => { OrientdbResponse <Stream> cs = ReturnConnectionStatus(request, data, requestSpecificConfig); return cs; })); }
public OrientdbResponse <T> Request <T>(TransportRequestState <T> requestState, object data = null) { byte[] postData = PostData(data); requestState.TickSerialization(postData); OrientdbResponse <T> response = DoRequest(requestState); requestState.SetResult(response); return(response); }
bool ITransportDelegator.SniffOnFaultDiscoveredMoreNodes(ITransportRequestState requestState, int retried, OrientdbResponse <Stream> streamResponse) { if (!requestState.UsingPooling || retried != 0 || (streamResponse != null && streamResponse.SuccessOrKnownError)) { return(false); } Self.SniffOnConnectionFailure(requestState); return(Self.GetMaximumRetries(requestState.RequestConfiguration) > 0); }
Task <bool> ITransportDelegator.PingAsync(ITransportRequestState requestState) { int pingTimeout = Settings.PingTimeout.GetValueOrDefault(DefaultPingTimeout); pingTimeout = requestState.RequestConfiguration != null ? requestState.RequestConfiguration.ConnectTimeout.GetValueOrDefault(pingTimeout) : pingTimeout; var requestOverrides = new RequestConfiguration { ConnectTimeout = pingTimeout, RequestTimeout = pingTimeout }; IRequestTimings rq = requestState.InitiateRequest(RequestType.Ping); try { return(Connection.Head(requestState.CreatePathOnCurrentNode(""), requestOverrides) .ContinueWith(t => { if (t.IsFaulted) { rq.Finish(false, null); rq.Dispose(); throw new PingException(requestState.CurrentNode, t.Exception); } rq.Finish(t.Result.Success, t.Result.HttpStatusCode); rq.Dispose(); OrientdbResponse <Stream> response = t.Result; if (!response.HttpStatusCode.HasValue || response.HttpStatusCode.Value == -1) { throw new PingException(requestState.CurrentNode, t.Exception); } if (response.HttpStatusCode == (int)HttpStatusCode.Unauthorized) { throw new OrientdbAuthenticationException(response); } using (response.Response) return response.Success; })); } catch (OrientdbAuthenticationException) { throw; } catch (Exception e) { var tcs = new TaskCompletionSource <bool>(); var pingException = new PingException(requestState.CurrentNode, e); tcs.SetException(pingException); return(tcs.Task); } }
/// <summary> /// Determines whether the stream response is our final stream response: /// IF response is success or known error /// OR maxRetries is 0 and retried is 0 (maxRetries could change in between retries to 0) /// AND sniff on connection fault does not find more nodes (causing maxRetry to grow) /// AND maxretries is no retried /// </summary> protected bool DoneProcessing <T>( OrientdbResponse <Stream> streamResponse, TransportRequestState <T> requestState, int maxRetries, int retried) { return((streamResponse != null && streamResponse.SuccessOrKnownError) || (maxRetries == 0 && retried == 0 && !_delegator.SniffOnFaultDiscoveredMoreNodes(requestState, retried, streamResponse) )); }
private IEnumerable <Task> _AsyncSteps(HttpWebRequest request, TaskCompletionSource <OrientdbResponse <Stream> > tcs, byte[] data, IRequestConfiguration requestSpecificConfig) { int timeout = GetRequestTimeout(requestSpecificConfig); if (data != null) { Task <Stream> getRequestStream = Task.Factory.FromAsync <Stream>(request.BeginGetRequestStream, request.EndGetRequestStream, null); ThreadPool.RegisterWaitForSingleObject((getRequestStream as IAsyncResult).AsyncWaitHandle, ThreadTimeoutCallback, request, timeout, true); yield return(getRequestStream); Stream requestStream = getRequestStream.Result; try { Task writeToRequestStream = Task.Factory.FromAsync(requestStream.BeginWrite, requestStream.EndWrite, data, 0, data.Length, null); yield return(writeToRequestStream); } finally { requestStream.Close(); } } // Get the response Task <WebResponse> getResponse = Task.Factory.FromAsync <WebResponse>(request.BeginGetResponse, request.EndGetResponse, null); ThreadPool.RegisterWaitForSingleObject((getResponse as IAsyncResult).AsyncWaitHandle, ThreadTimeoutCallback, request, timeout, true); yield return(getResponse); string path = request.RequestUri.ToString(); string method = request.Method; //http://msdn.microsoft.com/en-us/library/system.net.httpwebresponse.getresponsestream.aspx //Either the stream or the response object needs to be closed but not both (although it won't) //throw any errors if both are closed atleast one of them has to be Closed. //Since we expose the stream we let closing the stream determining when to close the connection var response = (HttpWebResponse)getResponse.Result; Stream responseStream = response.GetResponseStream(); OrientdbResponse <Stream> cs = OrientdbResponse <Stream> .Create(ConnectionSettings, (int)response.StatusCode, method, path, data); cs.Response = responseStream; tcs.TrySetResult(cs); }
protected OrientdbResponse <T> HandleAuthenticationException <T>(TransportRequestState <T> requestState, OrientdbAuthenticationException exception) { if (requestState.ClientSettings.ThrowOnOrientdbServerExceptions) { throw exception.ToElasticsearchServerException(); } OrientdbResponse <T> response = OrientdbResponse.CloneFrom(exception.Response, default(T)); response.Request = requestState.PostData; response.RequestUrl = requestState.Path; response.RequestMethod = requestState.Method; return(response); }
protected bool SetStringOrByteResult <T>(OrientdbResponse <T> original, byte[] bytes) { Type type = typeof(T); if (type == typeof(string)) { SetStringResult(original as OrientdbResponse <string>, bytes); return(true); } if (type == typeof(byte[])) { SetByteResult(original as OrientdbResponse <byte[]>, bytes); return(true); } return(false); }
private OrientdbResponse <Stream> HandleWebException(byte[] data, WebException webException, string method, string path) { OrientdbResponse <Stream> cs; var httpEx = webException.Response as HttpWebResponse; if (httpEx != null) { //StreamReader ms = new StreamReader(httpEx.GetResponseStream()); //var response = ms.ReadToEnd(); cs = WebToOrientdbResponse(data, httpEx.GetResponseStream(), httpEx, method, path); return(cs); } cs = OrientdbResponse <Stream> .CreateError(ConnectionSettings, webException, method, path, data); return(cs); }
private OrientdbResponse <T> ReturnTypedResponse <T>( TransportRequestState <T> requestState, OrientdbResponse <Stream> streamResponse, out OrientdbServerError error) { error = null; // Read to memory stream if needed bool hasResponse = streamResponse.Response != null; bool forceRead = _settings.KeepRawResponse || typeof(T) == typeof(string) || typeof(T) == typeof(byte[]); byte[] bytes = null; if (hasResponse && forceRead) { MemoryStream ms = _memoryStreamProvider.New(); streamResponse.Response.CopyTo(ms); bytes = ms.ToArray(); streamResponse.Response.Close(); streamResponse.Response = ms; streamResponse.Response.Position = 0; } // Set rawresponse if needed if (_settings.KeepRawResponse) { streamResponse.ResponseRaw = bytes; } bool isValidResponse = IsValidResponse(requestState, streamResponse); if (isValidResponse) { return(StreamToTypedResponse <T>(streamResponse, requestState, bytes)); } // If error read error error = GetErrorFromStream <T>(streamResponse.Response); OrientdbResponse <T> typedResponse = OrientdbResponse.CloneFrom(streamResponse, default(T)); SetStringOrByteResult(typedResponse, bytes); return(typedResponse); }
private void Iterate(HttpWebRequest request, byte[] data, IEnumerable <Task> asyncIterator, TaskCompletionSource <OrientdbResponse <Stream> > tcs) { IEnumerator <Task> enumerator = asyncIterator.GetEnumerator(); Action <Task> recursiveBody = null; recursiveBody = completedTask => { if (completedTask != null && completedTask.IsFaulted) { //none of the individual steps in _AsyncSteps run in parallel for 1 request //as this would be impossible we can assume Aggregate Exception.InnerException Exception exception = completedTask.Exception.InnerException; //cleanly exit from exceptions in stages if the exception is a webexception if (exception is WebException) { string path = request.RequestUri.ToString(); string method = request.Method; OrientdbResponse <Stream> response = HandleWebException(data, exception as WebException, method, path); tcs.SetResult(response); } else { tcs.TrySetException(exception); } enumerator.Dispose(); } else if (enumerator.MoveNext()) { enumerator.Current.ContinueWith(recursiveBody, TaskContinuationOptions.ExecuteSynchronously); } else { enumerator.Dispose(); } }; recursiveBody(null); }
private OrientdbResponse <Stream> ReturnConnectionStatus(HttpWebRequest request, byte[] data, IRequestConfiguration requestSpecificConfig = null) { string method = request.Method; string path = request.RequestUri.ToString(); OrientdbResponse <Stream> cs = OrientdbResponse <Stream> .Create(ConnectionSettings, _statusCode, method, path, data); cs.Response = new MemoryStream(_fixedResultBytes); if (ConnectionSettings.ConnectionStatusHandler != null) { ConnectionSettings.ConnectionStatusHandler(cs); } if (RecordRequests) { Requests.Add(Tuple.Create(method, request.RequestUri, data)); } return(cs); }
private OrientdbResponse <T> ReturnStreamOrVoidResponse <T>( TransportRequestState <T> requestState, OrientdbResponse <Stream> streamResponse) { // If the response never recieved a status code and has a caught exception make sure we throw it if (streamResponse.HttpStatusCode.GetValueOrDefault(-1) <= 0 && streamResponse.OriginalException != null) { throw streamResponse.OriginalException; } // If the user explicitly wants a stream returned the undisposed stream if (typeof(Stream).IsAssignableFrom(typeof(T))) { return(streamResponse as OrientdbResponse <T>); } if (!typeof(VoidResponse).IsAssignableFrom(typeof(T))) { return(null); } OrientdbResponse <VoidResponse> voidResponse = OrientdbResponse.CloneFrom <VoidResponse>(streamResponse, null); return(voidResponse as OrientdbResponse <T>); }
public OrientdbAuthenticationException(OrientdbResponse <Stream> response) { Response = response; }
protected void SetByteResult(OrientdbResponse <byte[]> response, byte[] rawResponse) { response.Response = rawResponse; }
protected void SetStringResult(OrientdbResponse <string> response, byte[] rawResponse) { response.Response = rawResponse.Utf8String(); }