public Task GetCpuCredits() { using (ServerStore.ContextPool.AllocateOperationContext(out TransactionOperationContext context)) using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream())) { var json = Server.CpuCreditsBalance.ToJson(); writer.WriteObject(context.ReadObject(json, "cpu/credits")); return(Task.CompletedTask); } }
protected override void PersistFields(JsonOperationContext context, BlittableJsonTextWriter writer) { var builder = IndexDefinition.ToJson(); using (var json = context.ReadObject(builder, nameof(IndexDefinition), BlittableJsonDocumentBuilder.UsageMode.ToDisk)) { writer.WritePropertyName(nameof(IndexDefinition)); writer.WriteObject(json); } }
public Task GetClientConfiguration() { var inherit = GetBoolValueQueryString("inherit", required: false) ?? true; var configuration = Database.ClientConfiguration; long etag = configuration?.Etag ?? -1; var serverConfiguration = GetServerClientConfiguration(out long serverIndex); etag = Hashing.Combine(etag, serverConfiguration?.Etag ?? -2); if (inherit) { if (configuration == null || configuration.Disabled) { if (serverConfiguration != null) { configuration = serverConfiguration; etag = serverIndex; } } } using (ContextPool.AllocateOperationContext(out JsonOperationContext context)) { BlittableJsonReaderObject clientConfigurationJson = null; if (configuration != null) { var val = configuration.ToJson(); clientConfigurationJson = context.ReadObject(val, Constants.Configuration.ClientId); } using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream())) { writer.WriteStartObject(); writer.WritePropertyName(nameof(GetClientConfigurationOperation.Result.Etag)); writer.WriteInteger(etag); writer.WriteComma(); writer.WritePropertyName(nameof(GetClientConfigurationOperation.Result.Configuration)); if (clientConfigurationJson != null) { writer.WriteObject(clientConfigurationJson); } else { writer.WriteNull(); } writer.WriteEndObject(); } } return(Task.CompletedTask); }
public Task WhoAmI() { var feature = HttpContext.Features.Get <IHttpAuthenticationFeature>() as RavenServer.AuthenticateConnection; var clientCert = feature?.Certificate; if (clientCert == null) { return(NoContent()); } using (ServerStore.ContextPool.AllocateOperationContext(out TransactionOperationContext ctx)) { BlittableJsonReaderObject certificate; using (ctx.OpenReadTransaction()) certificate = ServerStore.Cluster.Read(ctx, Constants.Certificates.Prefix + clientCert.Thumbprint); if (certificate == null && clientCert.Equals(Server.Certificate.Certificate)) { var certKey = Constants.Certificates.Prefix + clientCert.Thumbprint; using (ctx.OpenReadTransaction()) certificate = ServerStore.Cluster.Read(ctx, certKey) ?? ServerStore.Cluster.GetLocalState(ctx, certKey); if (certificate == null && Server.Certificate.Certificate != null) { // Since we didn't go through EnsureNotPassive(), the server certificate is not registered yet so we'll add it to the local state. var serverCertDef = new CertificateDefinition { Name = "Server Certificate", Certificate = Convert.ToBase64String(Server.Certificate.Certificate.Export(X509ContentType.Cert)), Permissions = new Dictionary <string, DatabaseAccess>(), SecurityClearance = SecurityClearance.ClusterNode, Thumbprint = Server.Certificate.Certificate.Thumbprint, NotAfter = Server.Certificate.Certificate.NotAfter }; certificate = ctx.ReadObject(serverCertDef.ToJson(), "Server/Certificate/Definition"); using (var tx = ctx.OpenWriteTransaction()) { ServerStore.Cluster.PutLocalState(ctx, Constants.Certificates.Prefix + Server.Certificate.Certificate.Thumbprint, certificate); tx.Commit(); } } } using (var writer = new BlittableJsonTextWriter(ctx, ResponseBodyStream())) { writer.WriteObject(certificate); } } return(Task.CompletedTask); }
private void HandleException(JsonOperationContext context, BlittableJsonTextWriter writer, Exception e, string url, string query) { var djv = new DynamicJsonValue { [nameof(ExceptionDispatcher.ExceptionSchema.Url)] = url + query, [nameof(ExceptionDispatcher.ExceptionSchema.Type)] = e.GetType().FullName, [nameof(ExceptionDispatcher.ExceptionSchema.Message)] = e.Message, [nameof(ExceptionDispatcher.ExceptionSchema.Error)] = e.ToString() }; using (var json = context.ReadObject(djv, "exception")) writer.WriteObject(json); }
public Task Report() { using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context)) { using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream())) { writer.WriteStartObject(); writer.WritePropertyName("BasePath"); writer.WriteString(Database.Configuration.Core.DataDirectory.FullPath); writer.WriteComma(); writer.WritePropertyName("Results"); writer.WriteStartArray(); var first = true; foreach (var env in Database.GetAllStoragesEnvironment()) { if (first == false) { writer.WriteComma(); } first = false; writer.WriteStartObject(); writer.WritePropertyName("Name"); writer.WriteString(env.Name); writer.WriteComma(); writer.WritePropertyName("Type"); writer.WriteString(env.Type.ToString()); writer.WriteComma(); var djv = (DynamicJsonValue)TypeConverter.ToBlittableSupportedType(GetReport(env)); writer.WritePropertyName("Report"); writer.WriteObject(context.ReadObject(djv, env.Name)); writer.WriteEndObject(); } writer.WriteEndArray(); writer.WriteEndObject(); } } return(Task.CompletedTask); }
protected override void PersistMapFields(JsonOperationContext context, BlittableJsonTextWriter writer) { writer.WritePropertyName(nameof(MapFields)); writer.WriteStartArray(); var first = true; foreach (var field in MapFields.Values.Select(x => x.As <AutoIndexField>())) { if (first == false) { writer.WriteComma(); } writer.WriteStartObject(); writer.WritePropertyName(nameof(field.Name)); writer.WriteString(field.Name); writer.WriteComma(); writer.WritePropertyName(nameof(field.Indexing)); writer.WriteString(field.Indexing.ToString()); writer.WriteComma(); writer.WritePropertyName(nameof(field.Aggregation)); writer.WriteInteger((int)field.Aggregation); writer.WriteComma(); writer.WritePropertyName(nameof(field.Spatial)); if (field.Spatial == null) { writer.WriteNull(); } else { writer.WriteObject(DocumentConventions.DefaultForServer.Serialization.DefaultConverter.ToBlittable(field.Spatial, context)); } writer.WriteComma(); writer.WritePropertyName(nameof(field.HasSuggestions)); writer.WriteBool(field.HasSuggestions); writer.WriteEndObject(); first = false; } writer.WriteEndArray(); }
public Task EnvironmentReport() { var name = GetStringQueryString("name"); var typeAsString = GetStringQueryString("type"); var details = GetBoolValueQueryString("details", required: false) ?? false; StorageEnvironmentWithType.StorageEnvironmentType type; if (Enum.TryParse(typeAsString, out type) == false) { throw new InvalidOperationException("Query string value 'type' is not a valid environment type: " + typeAsString); } var env = Database.GetAllStoragesEnvironment() .FirstOrDefault(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase) && x.Type == type); if (env == null) { HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound; return(Task.CompletedTask); } DocumentsOperationContext context; using (ContextPool.AllocateOperationContext(out context)) { using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream())) { writer.WriteStartObject(); writer.WritePropertyName("Name"); writer.WriteString(env.Name); writer.WriteComma(); writer.WritePropertyName("Type"); writer.WriteString(env.Type.ToString()); writer.WriteComma(); var djv = (DynamicJsonValue)TypeConverter.ToBlittableSupportedType(GetDetailedReport(env, details)); writer.WritePropertyName("Report"); writer.WriteObject(context.ReadObject(djv, env.Name)); writer.WriteEndObject(); } } return(Task.CompletedTask); }
public static string ConvertResultToString(ScriptRunnerResult result) { var ms = new MemoryStream(); using (var ctx = JsonOperationContext.ShortTermSingleUse()) using (var writer = new BlittableJsonTextWriter(ctx, ms)) { writer.WriteStartObject(); writer.WritePropertyName("Result"); if (result.IsNull) { writer.WriteNull(); } else if (result.RawJsValue.IsBoolean()) { writer.WriteBool(result.RawJsValue.AsBoolean()); } else if (result.RawJsValue.IsString()) { writer.WriteString(result.RawJsValue.AsString()); } else if (result.RawJsValue.IsDate()) { var date = result.RawJsValue.AsDate(); writer.WriteString(date.ToDateTime().ToString("O")); } else if (result.RawJsValue.IsNumber()) { writer.WriteDouble(result.RawJsValue.AsNumber()); } else { writer.WriteObject(result.TranslateToObject(ctx)); } writer.WriteEndObject(); writer.Flush(); } var str = Encoding.UTF8.GetString(ms.ToArray()); return(str); }
public Task WhoAmI() { var feature = HttpContext.Features.Get <IHttpAuthenticationFeature>() as RavenServer.AuthenticateConnection; var clientCert = feature?.Certificate; using (ServerStore.ContextPool.AllocateOperationContext(out TransactionOperationContext ctx)) using (ctx.OpenReadTransaction()) { var certificate = ServerStore.Cluster.Read(ctx, Constants.Certificates.Prefix + clientCert?.Thumbprint); using (var writer = new BlittableJsonTextWriter(ctx, ResponseBodyStream())) { writer.WriteObject(certificate); } } return(Task.CompletedTask); }
public Task PostScriptTest() { using (Database.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext context)) { var dbDoc = context.ReadForMemory(RequestBodyStream(), "TestSqlEtlScript"); var testScript = JsonDeserializationServer.TestSqlEtlScript(dbDoc); var result = (SqlEtlTestScriptResult)SqlEtl.TestScript(testScript, Database, ServerStore, context); using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream())) { var djv = (DynamicJsonValue)TypeConverter.ToBlittableSupportedType(result); writer.WriteObject(context.ReadObject(djv, "et/sql/test")); } } return(Task.CompletedTask); }
public Task PostSimulateSqlReplication() { using (Database.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext context)) { context.OpenReadTransaction(); var dbDoc = context.ReadForMemory(RequestBodyStream(), "SimulateSqlReplicationResult"); var simulateSqlReplication = JsonDeserializationServer.SimulateSqlReplication(dbDoc); var result = SqlEtl.SimulateSqlEtl(simulateSqlReplication, Database, ServerStore, context); using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream())) { var djv = (DynamicJsonValue)TypeConverter.ToBlittableSupportedType(result); writer.WriteObject(context.ReadObject(djv, "et/sql/simulate")); } } return(Task.CompletedTask); }
public Task GetConfiguration() { using (ServerStore.ContextPool.AllocateOperationContext(out JsonOperationContext context)) using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream())) { var djv = new DynamicJsonValue { [nameof(GetLogsConfigurationResult.CurrentMode)] = LoggingSource.Instance.LogMode, [nameof(GetLogsConfigurationResult.Mode)] = ServerStore.Configuration.Logs.Mode, [nameof(GetLogsConfigurationResult.Path)] = ServerStore.Configuration.Logs.Path.FullPath, [nameof(GetLogsConfigurationResult.UseUtcTime)] = ServerStore.Configuration.Logs.UseUtcTime }; var json = context.ReadObject(djv, "logs/configuration"); writer.WriteObject(json); } return(Task.CompletedTask); }
private void WriteIntermidiateResults(List <GraphQueryRunner.Match> matches) { _writer.WritePropertyName("Results"); _writer.WriteStartArray(); var first = true; foreach (var match in matches) { if (first == false) { _writer.WriteComma(); } first = false; var djv = new DynamicJsonValue(); match.PopulateVertices(djv); _writer.WriteObject(_ctx.ReadObject(djv, null)); } _writer.WriteEndArray(); }
public Task GetStudioConfiguration() { using (ServerStore.ContextPool.AllocateOperationContext(out TransactionOperationContext context)) { using (context.OpenReadTransaction()) { var studioConfigurationJson = ServerStore.Cluster.Read(context, Constants.Configuration.StudioId, out long _); if (studioConfigurationJson == null) { HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound; return(Task.CompletedTask); } using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream())) { writer.WriteObject(studioConfigurationJson); } } } return(Task.CompletedTask); }
public Task GetOids() { using (ServerStore.ContextPool.AllocateOperationContext(out TransactionOperationContext context)) using (context.OpenReadTransaction()) { using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream())) { var djv = new DynamicJsonValue { [nameof(SnmpOids.Server)] = SnmpOids.Server.ToJson(), [nameof(SnmpOids.Cluster)] = SnmpOids.Cluster.ToJson(), [nameof(SnmpOids.Databases)] = SnmpOids.Databases.ToJson(ServerStore, context) }; var json = context.ReadObject(djv, "snmp/oids"); writer.WriteObject(json); } } return(Task.CompletedTask); }
public Task GetStudioConfiguration() { var configuration = Database.StudioConfiguration; if (configuration == null) { HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound; return(Task.CompletedTask); } using (ContextPool.AllocateOperationContext(out JsonOperationContext context)) { var val = configuration.ToJson(); var clientConfigurationJson = context.ReadObject(val, Constants.Configuration.StudioId); using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream())) { writer.WriteObject(clientConfigurationJson); } } return(Task.CompletedTask); }
public Task Operation() { var id = GetLongQueryString("id"); // ReSharper disable once PossibleInvalidOperationException var operation = Database.Operations.GetOperation(id.Value); if (operation == null) { HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound; return(Task.CompletedTask); } DocumentsOperationContext context; using (ContextPool.AllocateOperationContext(out context)) { using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream())) { writer.WriteObject(context.ReadObject(operation.ToJson(), "operation")); } } return(Task.CompletedTask); }
public static void WriteIndexStats(this BlittableJsonTextWriter writer, JsonOperationContext context, IndexStats stats) { var djv = (DynamicJsonValue)TypeConverter.ToBlittableSupportedType(stats); writer.WriteObject(context.ReadObject(djv, "index/stats")); }
public static void WriteTreePagesRecursively(this BlittableJsonTextWriter writer, IEnumerable <ReduceTreePage> pages) { var first = true; foreach (var page in pages) { if (first == false) { writer.WriteComma(); } writer.WriteStartObject(); writer.WritePropertyName(nameof(TreePage.PageNumber)); writer.WriteInteger(page.PageNumber); writer.WriteComma(); writer.WritePropertyName(nameof(ReduceTreePage.AggregationResult)); if (page.AggregationResult != null) { writer.WriteObject(page.AggregationResult); } else { writer.WriteNull(); } writer.WriteComma(); writer.WritePropertyName(nameof(ReduceTreePage.Children)); if (page.Children != null) { writer.WriteStartArray(); WriteTreePagesRecursively(writer, page.Children); writer.WriteEndArray(); } else { writer.WriteNull(); } writer.WriteComma(); writer.WritePropertyName(nameof(ReduceTreePage.Entries)); if (page.Entries != null) { writer.WriteStartArray(); var firstEntry = true; foreach (var entry in page.Entries) { if (firstEntry == false) { writer.WriteComma(); } writer.WriteStartObject(); writer.WritePropertyName(nameof(MapResultInLeaf.Data)); writer.WriteObject(entry.Data); writer.WriteComma(); writer.WritePropertyName(nameof(MapResultInLeaf.Source)); writer.WriteString(entry.Source); writer.WriteEndObject(); firstEntry = false; } writer.WriteEndArray(); } else { writer.WriteNull(); } writer.WriteEndObject(); first = false; } }
public static void WaitForIndexing(IDocumentStore store, string dbName = null, TimeSpan?timeout = null) { var admin = store.Maintenance.ForDatabase(dbName); timeout = timeout ?? (Debugger.IsAttached ? TimeSpan.FromMinutes(15) : TimeSpan.FromMinutes(1)); var sp = Stopwatch.StartNew(); while (sp.Elapsed < timeout.Value) { var databaseStatistics = admin.Send(new GetStatisticsOperation()); var indexes = databaseStatistics.Indexes .Where(x => x.State != IndexState.Disabled); if (indexes.All(x => x.IsStale == false && x.Name.StartsWith("ReplacementOf/") == false)) { return; } if (databaseStatistics.Indexes.Any(x => x.State == IndexState.Error)) { break; } Thread.Sleep(32); } var perf = admin.Send(new GetIndexPerformanceStatisticsOperation()); var errors = admin.Send(new GetIndexErrorsOperation()); var stats = admin.Send(new GetIndexesStatisticsOperation()); var total = new { Errors = errors, Stats = stats, Performance = perf }; var file = Path.GetTempFileName() + ".json"; using (var stream = File.Open(file, FileMode.OpenOrCreate)) using (var context = JsonOperationContext.ShortTermSingleUse()) using (var writer = new BlittableJsonTextWriter(context, stream)) { var djv = (DynamicJsonValue)TypeConverter.ToBlittableSupportedType(total); var json = context.ReadObject(djv, "errors"); writer.WriteObject(json); writer.Flush(); } var statistics = admin.Send(new GetStatisticsOperation()); var corrupted = statistics.Indexes.Where(x => x.State == IndexState.Error).ToList(); if (corrupted.Count > 0) { throw new InvalidOperationException( $"The following indexes are with error state: {string.Join(",", corrupted.Select(x => x.Name))} - details at " + file); } throw new TimeoutException("The indexes stayed stale for more than " + timeout.Value + ", stats at " + file); }
private async Task RequestHandler(HttpContext context) { string database = null; try { context.Response.StatusCode = (int)HttpStatusCode.OK; context.Response.Headers["Content-Type"] = "application/json; charset=utf-8"; var sp = Stopwatch.StartNew(); database = await _router.HandlePath(context, context.Request.Method, context.Request.Path.Value); sp.Stop(); if (_logger.IsInfoEnabled && SkipHttpLogging == false) { _logger.Info($"{context.Request.Method} {context.Request.Path.Value}?{context.Request.QueryString.Value} - {context.Response.StatusCode} - {sp.ElapsedMilliseconds:#,#;;0} ms"); } if (TrafficWatchManager.HasRegisteredClients) { LogTrafficWatch(context, sp.ElapsedMilliseconds, database); } } catch (Exception e) { if (TrafficWatchManager.HasRegisteredClients) { LogTrafficWatch(context, 0, database ?? "N/A"); } if (context.RequestAborted.IsCancellationRequested) { return; } if (context.Request.Headers.TryGetValue(Constants.Headers.ClientVersion, out var versions)) { var version = versions.ToString(); if (version.Length > 0 && version[0] != RavenVersionAttribute.Instance.MajorVersionAsChar) { e = new ClientVersionMismatchException($"RavenDB does not support interaction between Client API and Server when major version does not match. Client: {version}. Server: {RavenVersionAttribute.Instance.AssemblyVersion}", e); } } MaybeSetExceptionStatusCode(context, e); using (_server.ServerStore.ContextPool.AllocateOperationContext(out JsonOperationContext ctx)) { var djv = new DynamicJsonValue { [nameof(ExceptionDispatcher.ExceptionSchema.Url)] = $"{context.Request.Path}{context.Request.QueryString}", [nameof(ExceptionDispatcher.ExceptionSchema.Type)] = e.GetType().FullName, [nameof(ExceptionDispatcher.ExceptionSchema.Message)] = e.Message, [nameof(ExceptionDispatcher.ExceptionSchema.Error)] = e.ToString() }; #if EXCEPTION_ERROR_HUNT var f = Guid.NewGuid() + ".error"; File.WriteAllText(f, $"{context.Request.Path}{context.Request.QueryString}" + Environment.NewLine + errorString); #endif MaybeAddAdditionalExceptionData(djv, e); using (var writer = new BlittableJsonTextWriter(ctx, context.Response.Body)) { var json = ctx.ReadObject(djv, "exception"); writer.WriteObject(json); } #if EXCEPTION_ERROR_HUNT File.Delete(f); #endif } } }
public Task WhoAmI() { var clientCert = GetCurrentCertificate(); if (clientCert == null) { return(NoContent()); } using (ServerStore.ContextPool.AllocateOperationContext(out TransactionOperationContext ctx)) { var certKey = Constants.Certificates.Prefix + clientCert.Thumbprint; BlittableJsonReaderObject certificate; using (ctx.OpenReadTransaction()) certificate = ServerStore.Cluster.Read(ctx, certKey) ?? ServerStore.Cluster.GetLocalState(ctx, certKey); if (certificate == null) { // The client certificate is not registered in the ServerStore. // Let's check if the client is using the server certificate or one of the well known admin certs. var wellKnown = ServerStore.Configuration.Security.WellKnownAdminCertificates; if (clientCert.Equals(Server.Certificate.Certificate)) { if (Server.Certificate.Certificate != null) { var serverCertDef = new CertificateDefinition { Name = "Server Certificate", Certificate = Convert.ToBase64String(Server.Certificate.Certificate.Export(X509ContentType.Cert)), Permissions = new Dictionary <string, DatabaseAccess>(), SecurityClearance = SecurityClearance.ClusterNode, Thumbprint = Server.Certificate.Certificate.Thumbprint, NotAfter = Server.Certificate.Certificate.NotAfter }; certificate = ctx.ReadObject(serverCertDef.ToJson(), "Server/Certificate/Definition"); } } else if (wellKnown != null && wellKnown.Contains(clientCert.Thumbprint, StringComparer.OrdinalIgnoreCase)) { var serverCertDef = new CertificateDefinition { Name = "Well Known Admin Certificate", Permissions = new Dictionary <string, DatabaseAccess>(), SecurityClearance = SecurityClearance.ClusterAdmin, Thumbprint = clientCert.Thumbprint, }; certificate = ctx.ReadObject(serverCertDef.ToJson(), "WellKnown/Certificate/Definition"); } } using (var writer = new BlittableJsonTextWriter(ctx, ResponseBodyStream())) { writer.WriteObject(certificate); } } return(Task.CompletedTask); }
private async Task RequestHandler(HttpContext context) { try { context.Response.StatusCode = 200; var sp = Stopwatch.StartNew(); var tenant = await _router.HandlePath(context, context.Request.Method, context.Request.Path.Value); sp.Stop(); if (_logger.IsInfoEnabled) { _logger.Info($"{context.Request.Method} {context.Request.Path.Value}?{context.Request.QueryString.Value} - {context.Response.StatusCode} - {sp.ElapsedMilliseconds:#,#;;0} ms"); } if (TrafficWatchManager.HasRegisteredClients) { var requestId = Interlocked.Increment(ref _requestId); var twn = new TrafficWatchNotification { TimeStamp = DateTime.UtcNow, RequestId = requestId, // counted only for traffic watch HttpMethod = context.Request.Method ?? "N/A", // N/A ? ElapsedMilliseconds = sp.ElapsedMilliseconds, ResponseStatusCode = context.Response.StatusCode, RequestUri = context.Request.GetEncodedUrl(), AbsoluteUri = $@"{context.Request.Scheme}://{context.Request.Host}", TenantName = tenant ?? "N/A", CustomInfo = "", // TODO: Implement InnerRequestsCount = 0, // TODO: Implement QueryTimings = null, // TODO: Implement }; TrafficWatchManager.DispatchMessage(twn); } } catch (Exception e) { if (context.RequestAborted.IsCancellationRequested) { return; } //TODO: special handling for argument exception (400 bad request) //TODO: database not found (503) //TODO: operaton cancelled (timeout) //TODO: Invalid data exception 422 //TODO: Proper json output, not like this var response = context.Response; var documentConflictException = e as DocumentConflictException; if (response.HasStarted == false) { if (documentConflictException != null) { response.StatusCode = 409; } else if (response.StatusCode < 400) { response.StatusCode = 500; } } JsonOperationContext ctx; using (_server.ServerStore.ContextPool.AllocateOperationContext(out ctx)) { var djv = new DynamicJsonValue { ["Url"] = $"{context.Request.Path}?{context.Request.QueryString}", ["Type"] = e.GetType().FullName, ["Message"] = e.Message }; string errorString; try { errorString = e.ToAsyncString(); } catch (Exception) { errorString = e.ToString(); } djv["Error"] = errorString; var indexCompilationException = e as IndexCompilationException; if (indexCompilationException != null) { djv[nameof(IndexCompilationException.IndexDefinitionProperty)] = indexCompilationException.IndexDefinitionProperty; djv[nameof(IndexCompilationException.ProblematicText)] = indexCompilationException.ProblematicText; } if (documentConflictException != null) { djv["ConflictInfo"] = ReplicationUtils.GetJsonForConflicts( documentConflictException.DocId, documentConflictException.Conflicts); } using (var writer = new BlittableJsonTextWriter(ctx, response.Body)) { var json = ctx.ReadObject(djv, "exception"); writer.WriteObject(json); } } } }
public static void WriteIndexQuery(this BlittableJsonTextWriter writer, DocumentConventions conventions, JsonOperationContext context, IndexQuery query) { writer.WriteStartObject(); writer.WritePropertyName(nameof(query.Query)); writer.WriteString(query.Query); writer.WriteComma(); if (query.PageSizeSet && query.PageSize >= 0) { writer.WritePropertyName(nameof(query.PageSize)); writer.WriteInteger(query.PageSize); writer.WriteComma(); } if (query.WaitForNonStaleResults) { writer.WritePropertyName(nameof(query.WaitForNonStaleResults)); writer.WriteBool(query.WaitForNonStaleResults); writer.WriteComma(); } if (query.Start > 0) { writer.WritePropertyName(nameof(query.Start)); writer.WriteInteger(query.Start); writer.WriteComma(); } if (query.WaitForNonStaleResultsTimeout.HasValue) { writer.WritePropertyName(nameof(query.WaitForNonStaleResultsTimeout)); writer.WriteString(query.WaitForNonStaleResultsTimeout.Value.ToInvariantString()); writer.WriteComma(); } if (query.DisableCaching) { writer.WritePropertyName(nameof(query.DisableCaching)); writer.WriteBool(query.DisableCaching); writer.WriteComma(); } #if FEATURE_EXPLAIN_SCORES if (query.ExplainScores) { writer.WritePropertyName(nameof(query.ExplainScores)); writer.WriteBool(query.ExplainScores); writer.WriteComma(); } #endif #if FEATURE_SHOW_TIMINGS if (query.ShowTimings) { writer.WritePropertyName(nameof(query.ShowTimings)); writer.WriteBool(query.ShowTimings); writer.WriteComma(); } #endif if (query.SkipDuplicateChecking) { writer.WritePropertyName(nameof(query.SkipDuplicateChecking)); writer.WriteBool(query.SkipDuplicateChecking); writer.WriteComma(); } writer.WritePropertyName(nameof(query.QueryParameters)); if (query.QueryParameters != null) { writer.WriteObject(EntityToBlittable.ConvertCommandToBlittable(query.QueryParameters, context)); } else { writer.WriteNull(); } writer.WriteEndObject(); }
private async Task RequestHandler(HttpContext context) { string database = null; try { context.Response.StatusCode = (int)HttpStatusCode.OK; context.Response.Headers["Content-Type"] = "application/json; charset=utf-8"; var sp = Stopwatch.StartNew(); database = await _router.HandlePath(context, context.Request.Method, context.Request.Path.Value); sp.Stop(); if (_logger.IsInfoEnabled && SkipHttpLogging == false) { _logger.Info($"{context.Request.Method} {context.Request.Path.Value}?{context.Request.QueryString.Value} - {context.Response.StatusCode} - {sp.ElapsedMilliseconds:#,#;;0} ms"); } if (TrafficWatchManager.HasRegisteredClients) { LogTrafficWatch(context, sp.ElapsedMilliseconds, database); } } catch (Exception e) { if (TrafficWatchManager.HasRegisteredClients) { LogTrafficWatch(context, 0, database ?? "N/A"); } if (context.RequestAborted.IsCancellationRequested) { return; } //TODO: special handling for argument exception (400 bad request) //TODO: operation canceled (timeout) //TODO: Invalid data exception 422 //TODO: Proper json output, not like this MaybeSetExceptionStatusCode(context, e); using (_server.ServerStore.ContextPool.AllocateOperationContext(out JsonOperationContext ctx)) { var djv = new DynamicJsonValue { [nameof(ExceptionDispatcher.ExceptionSchema.Url)] = $"{context.Request.Path}{context.Request.QueryString}", [nameof(ExceptionDispatcher.ExceptionSchema.Type)] = e.GetType().FullName, [nameof(ExceptionDispatcher.ExceptionSchema.Message)] = e.Message }; #if EXCEPTION_ERROR_HUNT var f = Guid.NewGuid() + ".error"; File.WriteAllText(f, $"{context.Request.Path}{context.Request.QueryString}" + Environment.NewLine + errorString); #endif djv[nameof(ExceptionDispatcher.ExceptionSchema.Error)] = e.ToString(); MaybeAddAdditionalExceptionData(djv, e); var response = context.Response; using (var writer = new BlittableJsonTextWriter(ctx, response.Body)) { var json = ctx.ReadObject(djv, "exception"); writer.WriteObject(json); } #if EXCEPTION_ERROR_HUNT File.Delete(f); #endif } } }
public async Task Patch() { var id = GetQueryStringValueAndAssertIfSingleAndNotEmpty("id"); var isTest = GetBoolValueQueryString("test", required: false) ?? false; var debugMode = GetBoolValueQueryString("debug", required: false) ?? isTest; var skipPatchIfChangeVectorMismatch = GetBoolValueQueryString("skipPatchIfChangeVectorMismatch", required: false) ?? false; using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context)) { var request = context.Read(RequestBodyStream(), "ScriptedPatchRequest"); if (request.TryGet("Patch", out BlittableJsonReaderObject patchCmd) == false || patchCmd == null) { throw new ArgumentException("The 'Patch' field in the body request is mandatory"); } var patch = PatchRequest.Parse(patchCmd, out var patchArgs); PatchRequest patchIfMissing = null; BlittableJsonReaderObject patchIfMissingArgs = null; if (request.TryGet("PatchIfMissing", out BlittableJsonReaderObject patchIfMissingCmd) && patchIfMissingCmd != null) { patchIfMissing = PatchRequest.Parse(patchIfMissingCmd, out patchIfMissingArgs); } var changeVector = context.GetLazyString(GetStringFromHeaders("If-Match")); var command = new PatchDocumentCommand(context, id, changeVector, skipPatchIfChangeVectorMismatch, (patch, patchArgs), (patchIfMissing, patchIfMissingArgs), Database, isTest, debugMode, true, returnDocument: false ); if (isTest == false) { await Database.TxMerger.Enqueue(command); } else { // PutDocument requires the write access to the docs storage // testing patching is rare enough not to optimize it using (context.OpenWriteTransaction()) { command.Execute(context, null); } } switch (command.PatchResult.Status) { case PatchStatus.DocumentDoesNotExist: HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound; return; case PatchStatus.Created: HttpContext.Response.StatusCode = (int)HttpStatusCode.Created; break; case PatchStatus.Skipped: HttpContext.Response.StatusCode = (int)HttpStatusCode.NotModified; return; case PatchStatus.Patched: case PatchStatus.NotModified: HttpContext.Response.StatusCode = (int)HttpStatusCode.OK; break; default: throw new ArgumentOutOfRangeException(); } using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream())) { writer.WriteStartObject(); writer.WritePropertyName(nameof(command.PatchResult.Status)); writer.WriteString(command.PatchResult.Status.ToString()); writer.WriteComma(); writer.WritePropertyName(nameof(command.PatchResult.ModifiedDocument)); writer.WriteObject(command.PatchResult.ModifiedDocument); if (debugMode) { writer.WriteComma(); writer.WritePropertyName(nameof(command.PatchResult.OriginalDocument)); if (isTest) { writer.WriteObject(command.PatchResult.OriginalDocument); } else { writer.WriteNull(); } writer.WriteComma(); writer.WritePropertyName(nameof(command.PatchResult.Debug)); context.Write(writer, new DynamicJsonValue { ["Info"] = new DynamicJsonArray(command.DebugOutput), ["Actions"] = command.DebugActions }); } switch (command.PatchResult.Status) { case PatchStatus.Created: case PatchStatus.Patched: writer.WriteComma(); writer.WritePropertyName(nameof(command.PatchResult.LastModified)); writer.WriteString(command.PatchResult.LastModified.GetDefaultRavenFormat(isUtc: command.PatchResult.LastModified.Kind == DateTimeKind.Utc)); writer.WriteComma(); writer.WritePropertyName(nameof(command.PatchResult.ChangeVector)); writer.WriteString(command.PatchResult.ChangeVector); writer.WriteComma(); writer.WritePropertyName(nameof(command.PatchResult.Collection)); writer.WriteString(command.PatchResult.Collection); break; } writer.WriteEndObject(); } } }
private async Task RequestHandler(HttpContext context) { var requestHandlerContext = new RequestHandlerContext { HttpContext = context }; Exception exception = null; Stopwatch sp = null; try { context.Response.StatusCode = (int)HttpStatusCode.OK; context.Response.Headers["Content-Type"] = "application/json; charset=utf-8"; context.Response.Headers[Constants.Headers.ServerVersion] = RavenVersionAttribute.Instance.AssemblyVersion; if (_server.ServerStore.Initialized == false) { await _server.ServerStore.InitializationCompleted.WaitAsync(); } sp = Stopwatch.StartNew(); await _router.HandlePath(requestHandlerContext); sp.Stop(); } catch (Exception e) { sp?.Stop(); exception = e; CheckVersionAndWrapException(context, ref e); MaybeSetExceptionStatusCode(context, _server.ServerStore, e); if (context.RequestAborted.IsCancellationRequested) { return; } using (_server.ServerStore.ContextPool.AllocateOperationContext(out JsonOperationContext ctx)) { var djv = new DynamicJsonValue { [nameof(ExceptionDispatcher.ExceptionSchema.Url)] = $"{context.Request.Path}{context.Request.QueryString}", [nameof(ExceptionDispatcher.ExceptionSchema.Type)] = e.GetType().FullName, [nameof(ExceptionDispatcher.ExceptionSchema.Message)] = e.Message, [nameof(ExceptionDispatcher.ExceptionSchema.Error)] = e.ToString() }; #if EXCEPTION_ERROR_HUNT var f = Guid.NewGuid() + ".error"; File.WriteAllText(f, $"{context.Request.Path}{context.Request.QueryString}" + Environment.NewLine + errorString); #endif MaybeAddAdditionalExceptionData(djv, e); using (var writer = new BlittableJsonTextWriter(ctx, context.Response.Body)) { var json = ctx.ReadObject(djv, "exception"); writer.WriteObject(json); } #if EXCEPTION_ERROR_HUNT File.Delete(f); #endif } } finally { // check if TW has clients if (TrafficWatchManager.HasRegisteredClients) { var database = requestHandlerContext.Database?.Name; LogTrafficWatch(context, sp?.ElapsedMilliseconds ?? 0, database); } if (sp != null && requestHandlerContext.HttpContext.Response.StatusCode != (int)HttpStatusCode.SwitchingProtocols) // exclude web sockets { var requestDuration = sp.ElapsedMilliseconds; requestHandlerContext.RavenServer?.Metrics.Requests.UpdateDuration(requestDuration); requestHandlerContext.Database?.Metrics.Requests.UpdateDuration(requestDuration); } if (_logger.IsInfoEnabled && SkipHttpLogging == false) { _logger.Info($"{context.Request.Method} {context.Request.Path.Value}{context.Request.QueryString.Value} - {context.Response.StatusCode} - {(sp?.ElapsedMilliseconds ?? 0):#,#;;0} ms", exception); } } }
public async Task Try() { using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context)) { var json = await context.ReadForMemoryAsync(RequestBodyStream(), null); var tryout = JsonDeserializationServer.SubscriptionTryout(json); var(collection, (script, functions), revisions) = SubscriptionConnection.ParseSubscriptionQuery(tryout.Query); SubscriptionPatchDocument patch = null; if (string.IsNullOrEmpty(script) == false) { patch = new SubscriptionPatchDocument(script, functions); } if (collection == null) { throw new ArgumentException("Collection must be specified"); } var pageSize = GetIntValueQueryString("pageSize") ?? 1; var state = new SubscriptionState { ChangeVectorForNextBatchStartingPoint = tryout.ChangeVector, Query = tryout.Query }; var fetcher = new SubscriptionDocumentsFetcher(Database, pageSize, -0x42, new IPEndPoint(HttpContext.Connection.RemoteIpAddress, HttpContext.Connection.RemotePort), collection, revisions, state, patch); if (Enum.TryParse( tryout.ChangeVector, out Constants.Documents.SubscriptionChangeVectorSpecialStates changeVectorSpecialValue)) { switch (changeVectorSpecialValue) { case Constants.Documents.SubscriptionChangeVectorSpecialStates.BeginningOfTime: case Constants.Documents.SubscriptionChangeVectorSpecialStates.DoNotChange: state.ChangeVectorForNextBatchStartingPoint = null; break; case Constants.Documents.SubscriptionChangeVectorSpecialStates.LastDocument: state.ChangeVectorForNextBatchStartingPoint = Database.DocumentsStorage.GetLastDocumentChangeVector(context, collection); break; } } using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream())) { writer.WriteStartObject(); writer.WritePropertyName("Results"); writer.WriteStartArray(); using (context.OpenReadTransaction()) { var first = true; foreach (var itemDetails in fetcher.GetDataToSend(context, 0)) { if (itemDetails.Doc.Data == null) { continue; } if (first == false) { writer.WriteComma(); } if (itemDetails.Exception == null) { writer.WriteDocument(context, itemDetails.Doc, metadataOnly: false); } else { var docWithExcepton = new DocumentWithException { Exception = itemDetails.Exception.ToString(), ChangeVector = itemDetails.Doc.ChangeVector, Id = itemDetails.Doc.Id, DocumentData = itemDetails.Doc.Data }; writer.WriteObject(context.ReadObject(docWithExcepton.ToJson(), "")); } first = false; } } writer.WriteEndArray(); writer.WriteEndObject(); } } }
public async Task Try() { using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context)) { BlittableJsonReaderObject json = await context.ReadForMemoryAsync(RequestBodyStream(), null); SubscriptionTryout tryout = JsonDeserializationServer.SubscriptionTryout(json); SubscriptionConnection.ParsedSubscription sub = SubscriptionConnection.ParseSubscriptionQuery(tryout.Query); SubscriptionPatchDocument patch = null; if (string.IsNullOrEmpty(sub.Script) == false) { patch = new SubscriptionPatchDocument(sub.Script, sub.Functions); } if (sub.Collection == null) { throw new ArgumentException("Collection must be specified"); } const int maxPageSize = 1024; var pageSize = GetIntValueQueryString("pageSize") ?? 1; if (pageSize > maxPageSize) { throw new ArgumentException($"Cannot gather more than {maxPageSize} results during tryouts, but requested number was {pageSize}."); } var state = new SubscriptionState { ChangeVectorForNextBatchStartingPoint = tryout.ChangeVector, Query = tryout.Query }; var fetcher = new SubscriptionDocumentsFetcher(Database, int.MaxValue, -0x42, new IPEndPoint(HttpContext.Connection.RemoteIpAddress, HttpContext.Connection.RemotePort), sub.Collection, sub.Revisions, state, patch); var includeCmd = new IncludeDocumentsCommand(Database.DocumentsStorage, context, sub.Includes, isProjection: patch != null); if (Enum.TryParse( tryout.ChangeVector, out Constants.Documents.SubscriptionChangeVectorSpecialStates changeVectorSpecialValue)) { switch (changeVectorSpecialValue) { case Constants.Documents.SubscriptionChangeVectorSpecialStates.BeginningOfTime: case Constants.Documents.SubscriptionChangeVectorSpecialStates.DoNotChange: state.ChangeVectorForNextBatchStartingPoint = null; break; case Constants.Documents.SubscriptionChangeVectorSpecialStates.LastDocument: using (context.OpenReadTransaction()) { state.ChangeVectorForNextBatchStartingPoint = Database.DocumentsStorage.GetLastDocumentChangeVector(context.Transaction.InnerTransaction, context, sub.Collection); } break; } } else { state.ChangeVectorForNextBatchStartingPoint = tryout.ChangeVector; } var changeVector = state.ChangeVectorForNextBatchStartingPoint.ToChangeVector(); var cv = changeVector.FirstOrDefault(x => x.DbId == Database.DbBase64Id); var sp = Stopwatch.StartNew(); var timeLimit = TimeSpan.FromSeconds(GetIntValueQueryString("timeLimit", false) ?? 15); var startEtag = cv.Etag; using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream())) using (context.OpenReadTransaction()) { writer.WriteStartObject(); writer.WritePropertyName("Results"); writer.WriteStartArray(); var numberOfDocs = 0; while (numberOfDocs == 0 && sp.Elapsed < timeLimit) { var first = true; var lastEtag = startEtag; foreach (var itemDetails in fetcher.GetDataToSend(context, includeCmd, startEtag)) { if (itemDetails.Doc.Data != null) { using (itemDetails.Doc.Data) { includeCmd.Gather(itemDetails.Doc); if (first == false) { writer.WriteComma(); } if (itemDetails.Exception == null) { writer.WriteDocument(context, itemDetails.Doc, metadataOnly: false); } else { var documentWithException = new DocumentWithException { Exception = itemDetails.Exception.ToString(), ChangeVector = itemDetails.Doc.ChangeVector, Id = itemDetails.Doc.Id, DocumentData = itemDetails.Doc.Data }; writer.WriteObject(context.ReadObject(documentWithException.ToJson(), "")); } first = false; if (++numberOfDocs >= pageSize) { break; } } } if (sp.Elapsed >= timeLimit) { break; } lastEtag = itemDetails.Doc.Etag; } if (startEtag == lastEtag) { break; } startEtag = lastEtag; } writer.WriteEndArray(); writer.WriteComma(); writer.WritePropertyName("Includes"); var includes = new List <Document>(); includeCmd.Fill(includes); writer.WriteIncludes(context, includes); writer.WriteEndObject(); } } }