예제 #1
0
        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;

                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, _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);
                }
            }
        }
        protected Document GetProjection(Lucene.Net.Documents.Document input, Lucene.Net.Search.ScoreDoc scoreDoc, string lowerId, IState state)
        {
            using (_projectionScope = _projectionScope?.Start() ?? RetrieverScope?.For(nameof(QueryTimingsScope.Names.Projection)))
            {
                Document doc = null;
                if (FieldsToFetch.AnyExtractableFromIndex == false)
                {
                    using (_projectionStorageScope = _projectionStorageScope?.Start() ?? _projectionScope?.For(nameof(QueryTimingsScope.Names.Storage)))
                        doc = DirectGet(input, lowerId, DocumentFields.All, state);

                    if (doc == null)
                    {
                        if (FieldsToFetch.Projection.MustExtractFromDocument)
                        {
                            if (FieldsToFetch.Projection.MustExtractOrThrow)
                            {
                                FieldsToFetch.Projection.ThrowCouldNotExtractProjectionOnDocumentBecauseDocumentDoesNotExistException(lowerId);
                            }
                        }

                        return(null);
                    }

                    return(GetProjectionFromDocumentInternal(doc, input, scoreDoc, FieldsToFetch, _context, state));
                }

                var result = new DynamicJsonValue();

                Dictionary <string, FieldsToFetch.FieldToFetch> fields = null;
                if (FieldsToFetch.ExtractAllFromIndex)
                {
                    fields = input.GetFields()
                             .Where(x => x.Name != Constants.Documents.Indexing.Fields.DocumentIdFieldName &&
                                    x.Name != Constants.Documents.Indexing.Fields.SourceDocumentIdFieldName &&
                                    x.Name != Constants.Documents.Indexing.Fields.ReduceKeyHashFieldName &&
                                    x.Name != Constants.Documents.Indexing.Fields.ReduceKeyValueFieldName &&
                                    x.Name != Constants.Documents.Indexing.Fields.ValueFieldName &&
                                    FieldUtil.GetRangeTypeFromFieldName(x.Name) == RangeType.None)
                             .Distinct(UniqueFieldNames.Instance)
                             .ToDictionary(x => x.Name, x => new FieldsToFetch.FieldToFetch(x.Name, null, null, x.IsStored, isDocumentId: false, isTimeSeries: false));
                }

                if (fields == null)
                {
                    fields = FieldsToFetch.Fields;
                }
                else if (FieldsToFetch.Fields != null && FieldsToFetch.Fields.Count > 0)
                {
                    foreach (var kvp in FieldsToFetch.Fields)
                    {
                        if (fields.ContainsKey(kvp.Key))
                        {
                            continue;
                        }

                        fields[kvp.Key] = kvp.Value;
                    }
                }

                foreach (var fieldToFetch in fields.Values)
                {
                    if (TryExtractValueFromIndex(fieldToFetch, input, result, state))
                    {
                        continue;
                    }

                    if (FieldsToFetch.Projection.MustExtractFromIndex)
                    {
                        if (FieldsToFetch.Projection.MustExtractOrThrow)
                        {
                            FieldsToFetch.Projection.ThrowCouldNotExtractFieldFromIndexBecauseIndexDoesNotContainSuchFieldOrFieldValueIsNotStored(fieldToFetch.Name.Value);
                        }

                        continue;
                    }

                    if (doc == null)
                    {
                        using (_projectionStorageScope = _projectionStorageScope?.Start() ?? _projectionScope?.For(nameof(QueryTimingsScope.Names.Storage)))
                            doc = DirectGet(input, lowerId, DocumentFields.All, state);

                        if (doc == null)
                        {
                            if (FieldsToFetch.Projection.MustExtractFromDocument)
                            {
                                if (FieldsToFetch.Projection.MustExtractOrThrow)
                                {
                                    FieldsToFetch.Projection.ThrowCouldNotExtractFieldFromDocumentBecauseDocumentDoesNotExistException(lowerId, fieldToFetch.Name.Value);
                                }

                                break;
                            }

                            // we don't return partial results
                            return(null);
                        }
                    }

                    if (TryGetValue(fieldToFetch, doc, input, state, FieldsToFetch.IndexFields, FieldsToFetch.AnyDynamicIndexFields, out var key, out var fieldVal))
                    {
                        if (FieldsToFetch.SingleBodyOrMethodWithNoAlias)
                        {
                            if (fieldVal is BlittableJsonReaderObject nested)
                            {
                                doc.Data = nested;
                            }
                            else if (fieldVal is Document d)
                            {
                                doc = d;
                            }
                            else
                            {
                                ThrowInvalidQueryBodyResponse(fieldVal);
                            }
                            FinishDocumentSetup(doc, scoreDoc);
                            return(doc);
                        }

                        if (fieldVal is List <object> list)
                        {
                            fieldVal = new DynamicJsonArray(list);
                        }

                        if (fieldVal is Document d2)
                        {
                            fieldVal = d2.Data;
                        }

                        result[key] = fieldVal;
                    }
예제 #3
0
 public static void SetMinimalHumaneMeterData(this MeterMetric self, string name, DynamicJsonValue obj)
 {
     obj["HumaneTotal" + name]     = Sizes.Humane(self.Count);
     obj["Humane" + name + "Rate"] = Sizes.Humane((long)self.OneMinuteRate);
 }
예제 #4
0
 public override void FillJson(DynamicJsonValue json)
 {
     json[nameof(ConnectionString)] = ConnectionString.ToJson();
 }
예제 #5
0
 public override void FillJson(DynamicJsonValue json)
 {
     json[nameof(NodeTag)]          = NodeTag;
     json[nameof(RaftCommandIndex)] = RaftCommandIndex;
 }
예제 #6
0
        public async Task Should_unload_db_and_send_notification_on_catastrophic_failure()
        {
            UseNewLocalServer();
            using (var store = GetDocumentStore())
            {
                var notifications = new AsyncQueue <DynamicJsonValue>();

                using (Server.ServerStore.NotificationCenter.TrackActions(notifications, null))
                {
                    var database = await GetDatabase(store.Database);

                    Assert.Equal(1, Server.ServerStore.DatabasesLandlord.DatabasesCache.Count());

                    try
                    {
                        throw new Exception("Catastrophy");
                    }
                    catch (Exception e)
                    {
                        database.GetAllStoragesEnvironment().First().Environment.Options.SetCatastrophicFailure(ExceptionDispatchInfo.Capture(e));
                    }

                    var ex = Assert.Throws <Exception>(() =>
                    {
                        using (var context = DocumentsOperationContext.ShortTermSingleUse(database))
                        {
                            using (var tx = context.OpenWriteTransaction())
                            {
                                var dynamicJsonValue = new DynamicJsonValue();
                                using (var doc = context.ReadObject(dynamicJsonValue, "users/1", BlittableJsonDocumentBuilder.UsageMode.ToDisk))
                                {
                                    database.DocumentsStorage.Put(context, "users/1", null, doc);
                                }

                                tx.Commit();
                            }
                        }
                    });

                    Assert.Equal("Catastrophy", ex.Message);

                    // db unloaded
                    Assert.True(SpinWait.SpinUntil(() => Server.ServerStore.DatabasesLandlord.DatabasesCache.Any() == false, TimeSpan.FromMinutes(1)));

                    Tuple <bool, DynamicJsonValue> alert;
                    do
                    {
                        alert = await notifications.TryDequeueAsync(TimeSpan.Zero);
                    } while (alert.Item2["Type"].ToString() != NotificationType.AlertRaised.ToString());


                    Assert.Equal(AlertType.CatastrophicDatabaseFailure, alert.Item2[nameof(AlertRaised.AlertType)]);
                    Assert.Contains(database.Name, alert.Item2[nameof(AlertRaised.Title)] as string);
                }

                using (var session = store.OpenSession())
                {
                    session.Store(new User());

                    session.SaveChanges();
                }

                // db loaded again
                Assert.Equal(1, Server.ServerStore.DatabasesLandlord.DatabasesCache.Count());
            }
        }
예제 #7
0
 public override void FillJson(DynamicJsonValue json)
 {
     json[nameof(DatabaseName)] = DatabaseName;
     json[nameof(Identities)]   = new DynamicJsonArray(Identities);
 }
예제 #8
0
            public override int Execute(DocumentsOperationContext context)
            {
                Reply = new DynamicJsonArray();
                for (int i = ParsedCommands.Offset; i < ParsedCommands.Count; i++)
                {
                    var cmd = ParsedCommands.Array[ParsedCommands.Offset + i];
                    switch (cmd.Type)
                    {
                    case CommandType.PUT:
                    {
                        var putResult = Database.DocumentsStorage.Put(context, cmd.Id, cmd.ChangeVector, cmd.Document);
                        context.DocumentDatabase.HugeDocuments.AddIfDocIsHuge(cmd.Id, cmd.Document.Size);
                        LastChangeVector = putResult.ChangeVector;
                        ModifiedCollections?.Add(putResult.Collection.Name);

                        // Make sure all the metadata fields are always been add
                        var putReply = new DynamicJsonValue
                        {
                            ["Type"] = nameof(CommandType.PUT),
                            [Constants.Documents.Metadata.Id]           = putResult.Id,
                            [Constants.Documents.Metadata.Collection]   = putResult.Collection.Name,
                            [Constants.Documents.Metadata.ChangeVector] = putResult.ChangeVector,
                            [Constants.Documents.Metadata.LastModified] = putResult.LastModified
                        };

                        if (putResult.Flags != DocumentFlags.None)
                        {
                            putReply[Constants.Documents.Metadata.Flags] = putResult.Flags;
                        }

                        Reply.Add(putReply);
                    }
                    break;

                    case CommandType.PATCH:
                        cmd.PatchCommand.Execute(context);

                        var patchResult = cmd.PatchCommand.PatchResult;
                        if (patchResult.ModifiedDocument != null)
                        {
                            context.DocumentDatabase.HugeDocuments.AddIfDocIsHuge(cmd.Id, patchResult.ModifiedDocument.Size);
                        }

                        if (patchResult.ChangeVector != null)
                        {
                            LastChangeVector = patchResult.ChangeVector;
                        }

                        if (patchResult.Collection != null)
                        {
                            ModifiedCollections?.Add(patchResult.Collection);
                        }

                        Reply.Add(new DynamicJsonValue
                        {
                            [nameof(BatchRequestParser.CommandData.Id)]           = cmd.Id,
                            [nameof(BatchRequestParser.CommandData.ChangeVector)] = patchResult.ChangeVector,
                            [nameof(BatchRequestParser.CommandData.Type)]         = nameof(CommandType.PATCH),
                            ["PatchStatus"] = patchResult.Status.ToString(),
                            ["Debug"]       = patchResult.Debug
                        });
                        break;

                    case CommandType.DELETE:
                        if (cmd.IdPrefixed == false)
                        {
                            var deleted = Database.DocumentsStorage.Delete(context, cmd.Id, cmd.ChangeVector);

                            if (deleted != null)
                            {
                                LastChangeVector = deleted.Value.ChangeVector;
                                ModifiedCollections?.Add(deleted.Value.Collection.Name);
                            }

                            Reply.Add(new DynamicJsonValue
                            {
                                [nameof(BatchRequestParser.CommandData.Id)]   = cmd.Id,
                                [nameof(BatchRequestParser.CommandData.Type)] = nameof(CommandType.DELETE),
                                ["Deleted"] = deleted != null
                            });
                        }
                        else
                        {
                            var deleteResults = Database.DocumentsStorage.DeleteDocumentsStartingWith(context, cmd.Id);

                            for (var j = 0; j < deleteResults.Count; j++)
                            {
                                LastChangeVector = deleteResults[j].ChangeVector;
                                ModifiedCollections?.Add(deleteResults[j].Collection.Name);
                            }

                            Reply.Add(new DynamicJsonValue
                            {
                                [nameof(BatchRequestParser.CommandData.Id)]   = cmd.Id,
                                [nameof(BatchRequestParser.CommandData.Type)] = nameof(CommandType.DELETE),
                                ["Deleted"] = deleteResults.Count > 0
                            });
                        }
                        break;

                    case CommandType.AttachmentPUT:
                        var attachmentStream = AttachmentStreams.Dequeue();
                        using (var stream = attachmentStream.Stream)
                        {
                            var attachmentPutResult = Database.DocumentsStorage.AttachmentsStorage.PutAttachment(context, cmd.Id, cmd.Name,
                                                                                                                 cmd.ContentType, attachmentStream.Hash, cmd.ChangeVector, stream, updateDocument: false);
                            LastChangeVector = attachmentPutResult.ChangeVector;

                            if (_documentsToUpdateAfterAttachmentChange == null)
                            {
                                _documentsToUpdateAfterAttachmentChange = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
                            }
                            _documentsToUpdateAfterAttachmentChange.Add(cmd.Id);

                            Reply.Add(new DynamicJsonValue
                            {
                                [nameof(BatchRequestParser.CommandData.Id)]           = attachmentPutResult.DocumentId,
                                [nameof(BatchRequestParser.CommandData.Type)]         = nameof(CommandType.AttachmentPUT),
                                [nameof(BatchRequestParser.CommandData.Name)]         = attachmentPutResult.Name,
                                [nameof(BatchRequestParser.CommandData.ChangeVector)] = attachmentPutResult.ChangeVector,
                                [nameof(AttachmentDetails.Hash)] = attachmentPutResult.Hash,
                                [nameof(BatchRequestParser.CommandData.ContentType)] = attachmentPutResult.ContentType,
                                [nameof(AttachmentDetails.Size)] = attachmentPutResult.Size
                            });
                        }

                        break;

                    case CommandType.AttachmentDELETE:
                        Database.DocumentsStorage.AttachmentsStorage.DeleteAttachment(context, cmd.Id, cmd.Name, cmd.ChangeVector, updateDocument: false);

                        if (_documentsToUpdateAfterAttachmentChange == null)
                        {
                            _documentsToUpdateAfterAttachmentChange = new HashSet <string>(StringComparer.OrdinalIgnoreCase);
                        }
                        _documentsToUpdateAfterAttachmentChange.Add(cmd.Id);

                        Reply.Add(new DynamicJsonValue
                        {
                            ["Type"] = nameof(CommandType.AttachmentDELETE),
                            [Constants.Documents.Metadata.Id] = cmd.Id,
                            ["Name"] = cmd.Name
                        });

                        break;
                    }
                }

                if (_documentsToUpdateAfterAttachmentChange != null)
                {
                    foreach (var documentId in _documentsToUpdateAfterAttachmentChange)
                    {
                        var changeVector = Database.DocumentsStorage.AttachmentsStorage.UpdateDocumentAfterAttachmentChange(context, documentId);
                        if (changeVector != null)
                        {
                            LastChangeVector = changeVector;
                        }
                    }
                }
                return(Reply.Count);
            }
예제 #9
0
 public override void FillJson(DynamicJsonValue json)
 {
     json[nameof(Topology)]         = Topology.ToJson();
     json[nameof(RaftCommandIndex)] = RaftCommandIndex;
 }
예제 #10
0
 public override void FillJson(DynamicJsonValue json)
 {
     json[nameof(SubscriptionName)] = SubscriptionName;
 }
예제 #11
0
        public Task QueriesCacheList()
        {
            using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
                using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                {
                    var queryCache = Database.QueryMetadataCache.GetQueryCache();

                    var responseDjv = new DynamicJsonValue();
                    var queriesList = new List <DynamicJsonValue>();

                    writer.WritePropertyName("TotalCachedQueries");
                    writer.WriteInteger(queryCache.Length);
                    writer.WriteComma();

                    foreach (var item in queryCache)
                    {
                        if (item != null)
                        {
                            var curDjvItem = new DynamicJsonValue();
                            queriesList.Add(curDjvItem);

                            curDjvItem[nameof(Queries.QueryMetadata.CreatedAt)] = item.CreatedAt;

                            curDjvItem[nameof(Queries.QueryMetadata.LastQueriedAt)] = item.LastQueriedAt;
                            if (item.IsGroupBy)
                            {
                                curDjvItem[nameof(Queries.QueryMetadata.IsGroupBy)] = true;
                            }

                            if (item.IsDistinct)
                            {
                                curDjvItem[nameof(Queries.QueryMetadata.IsDistinct)] = true;
                            }

                            if (item.HasFacet)
                            {
                                curDjvItem[nameof(Queries.QueryMetadata.HasFacet)] = true;
                            }

                            if (item.HasMoreLikeThis)
                            {
                                curDjvItem[nameof(Queries.QueryMetadata.HasMoreLikeThis)] = true;
                            }

                            if (item.HasSuggest)
                            {
                                curDjvItem[nameof(Queries.QueryMetadata.HasSuggest)] = true;
                            }

                            if (item.OrderBy != null)
                            {
                                curDjvItem["Sorted"] = true;
                            }

                            if (item.IsOptimizedSortOnly)
                            {
                                curDjvItem[nameof(Queries.QueryMetadata.IsOptimizedSortOnly)] = true;
                            }

                            if (item.HasCmpXchg)
                            {
                                curDjvItem[nameof(Queries.QueryMetadata.HasCmpXchg)] = true;
                            }

                            if (item.HasExplanations)
                            {
                                curDjvItem[nameof(Queries.QueryMetadata.HasExplanations)] = true;
                            }

                            if (item.HasIntersect)
                            {
                                curDjvItem[nameof(Queries.QueryMetadata.HasIntersect)] = true;
                            }

                            if (item.IsDynamic)
                            {
                                curDjvItem[nameof(Queries.QueryMetadata.IsDynamic)] = true;
                            }

                            if (item.SelectFields.Any(x => x.Function != null))
                            {
                                curDjvItem["IsJSProjection"] = true;
                            }

                            if (string.IsNullOrEmpty(item.CollectionName) == false)
                            {
                                curDjvItem[nameof(Queries.QueryMetadata.CollectionName)] = item.CollectionName;
                            }

                            if (string.IsNullOrEmpty(item.AutoIndexName) == false)
                            {
                                curDjvItem[nameof(Queries.QueryMetadata.AutoIndexName)] = item.AutoIndexName;
                            }

                            if (string.IsNullOrEmpty(item.IndexName) == false)
                            {
                                curDjvItem[nameof(Queries.QueryMetadata.IndexName)] = item.IndexName;
                            }

                            curDjvItem[nameof(Queries.QueryMetadata.QueryText)] = item.QueryText;
                        }
                    }

                    writer.WriteArray("Results", queriesList, context);
                }

            return(Task.CompletedTask);
        }
예제 #12
0
 public override void FillJson(DynamicJsonValue json)
 {
     json[nameof(TaskId)]   = TypeConverter.ToBlittableSupportedType(TaskId);
     json[nameof(TaskType)] = TypeConverter.ToBlittableSupportedType(TaskType);
     json[nameof(Disable)]  = TypeConverter.ToBlittableSupportedType(Disable);
 }
예제 #13
0
        protected Document GetProjection(Lucene.Net.Documents.Document input, float score, string lowerId, IState state)
        {
            Document doc = null;

            if (FieldsToFetch.AnyExtractableFromIndex == false)
            {
                doc = DirectGet(input, lowerId, state);

                if (doc == null)
                {
                    return(null);
                }

                return(GetProjectionFromDocument(doc, input, score, FieldsToFetch, _context, state));
            }

            var documentLoaded = false;

            var result = new DynamicJsonValue();

            Dictionary <string, FieldsToFetch.FieldToFetch> fields = null;

            if (FieldsToFetch.ExtractAllFromIndex)
            {
                fields = input.GetFields()
                         .Where(x => x.Name != Constants.Documents.Indexing.Fields.DocumentIdFieldName &&
                                x.Name != Constants.Documents.Indexing.Fields.ReduceKeyHashFieldName &&
                                x.Name != Constants.Documents.Indexing.Fields.ReduceKeyValueFieldName &&
                                FieldUtil.GetRangeTypeFromFieldName(x.Name) == RangeType.None)
                         .Distinct(UniqueFieldNames.Instance)
                         .ToDictionary(x => x.Name, x => new FieldsToFetch.FieldToFetch(x.Name, null, null, x.IsStored, isDocumentId: false));
            }

            if (fields == null)
            {
                fields = FieldsToFetch.Fields;
            }
            else if (FieldsToFetch.Fields != null && FieldsToFetch.Fields.Count > 0)
            {
                foreach (var kvp in FieldsToFetch.Fields)
                {
                    if (fields.ContainsKey(kvp.Key))
                    {
                        continue;
                    }

                    fields[kvp.Key] = kvp.Value;
                }
            }

            foreach (var fieldToFetch in fields.Values)
            {
                if (TryExtractValueFromIndex(fieldToFetch, input, result, state))
                {
                    continue;
                }

                if (documentLoaded == false)
                {
                    doc = DirectGet(input, lowerId, state);

                    documentLoaded = true;
                }

                if (doc == null)
                {
                    continue;
                }

                if (TryGetValue(fieldToFetch, doc, input, state, out var fieldVal))
                {
                    if (FieldsToFetch.SingleBodyOrMethodWithNoAlias)
                    {
                        if (fieldVal is BlittableJsonReaderObject nested)
                        {
                            doc.Data = nested;
                        }
                        else if (fieldVal is Document d)
                        {
                            doc = d;
                        }
                        else
                        {
                            ThrowInvalidQueryBodyResponse(fieldVal);
                        }
                        doc.IndexScore = score;
                        return(doc);
                    }
                    if (fieldVal is List <object> list)
                    {
                        fieldVal = new DynamicJsonArray(list);
                    }
                    result[fieldToFetch.ProjectedName ?? fieldToFetch.Name.Value] = fieldVal;
                }
            }

            if (doc == null)
            {
                doc = new Document
                {
                    Id = _context.GetLazyString(lowerId)
                };
            }

            return(ReturnProjection(result, doc, score, _context));
        }
예제 #14
0
        private bool TryExtractValueFromIndex(FieldsToFetch.FieldToFetch fieldToFetch, Lucene.Net.Documents.Document indexDocument, DynamicJsonValue toFill, IState state)
        {
            if (fieldToFetch.CanExtractFromIndex == false)
            {
                return(false);
            }

            var name = fieldToFetch.ProjectedName ?? fieldToFetch.Name.Value;

            DynamicJsonArray array     = null;
            FieldType        fieldType = null;
            var anyExtracted           = false;

            foreach (var field in indexDocument.GetFields(fieldToFetch.Name))
            {
                if (fieldType == null)
                {
                    fieldType = GetFieldType(field.Name, indexDocument);
                }

                var fieldValue = ConvertType(_context, field, fieldType, state);

                if (fieldType.IsArray)
                {
                    if (array == null)
                    {
                        array        = new DynamicJsonArray();
                        toFill[name] = array;
                    }

                    array.Add(fieldValue);
                    anyExtracted = true;
                    continue;
                }

                toFill[name] = fieldValue;
                anyExtracted = true;
            }

            return(anyExtracted);
        }
예제 #15
0
        private void WriteDatabaseInfo(string databaseName, BlittableJsonReaderObject dbRecordBlittable,
                                       TransactionOperationContext context, AbstractBlittableJsonTextWriter writer)
        {
            try
            {
                var online = ServerStore.DatabasesLandlord.DatabasesCache.TryGetValue(databaseName, out Task <DocumentDatabase> dbTask) &&
                             dbTask != null &&
                             dbTask.IsCompleted;

                // Check for exceptions
                if (dbTask != null && dbTask.IsFaulted)
                {
                    var exception = dbTask.Exception.ExtractSingleInnerException();
                    WriteFaultedDatabaseInfo(databaseName, exception, context, writer);
                    return;
                }

                var dbRecord = JsonDeserializationCluster.DatabaseRecord(dbRecordBlittable);
                var db       = online ? dbTask.Result : null;

                var indexingStatus = db?.IndexStore?.Status;
                if (indexingStatus == null)
                {
                    // Looking for disabled indexing flag inside the database settings for offline database status
                    if (dbRecord.Settings.TryGetValue(RavenConfiguration.GetKey(x => x.Indexing.Disabled), out var val) &&
                        bool.TryParse(val, out var indexingDisabled) && indexingDisabled)
                    {
                        indexingStatus = IndexRunningStatus.Disabled;
                    }
                }

                var disabled        = dbRecord.Disabled;
                var topology        = dbRecord.Topology;
                var clusterTopology = ServerStore.GetClusterTopology(context);
                clusterTopology.ReplaceCurrentNodeUrlWithClientRequestedNodeUrlIfNecessary(ServerStore, HttpContext);

                var studioEnvironment = StudioConfiguration.StudioEnvironment.None;
                if (dbRecord.Studio != null && !dbRecord.Studio.Disabled)
                {
                    studioEnvironment = dbRecord.Studio.Environment;
                }

                var nodesTopology = new NodesTopology();

                var statuses = ServerStore.GetNodesStatuses();
                if (topology != null)
                {
                    nodesTopology.PriorityOrder = topology.PriorityOrder;

                    foreach (var member in topology.Members)
                    {
                        if (dbRecord.DeletionInProgress != null && dbRecord.DeletionInProgress.ContainsKey(member))
                        {
                            continue;
                        }

                        var url  = clusterTopology.GetUrlFromTag(member);
                        var node = new InternalReplication
                        {
                            Database = databaseName,
                            NodeTag  = member,
                            Url      = url
                        };
                        nodesTopology.Members.Add(GetNodeId(node));
                        SetNodeStatus(topology, member, nodesTopology, statuses);
                    }

                    foreach (var promotable in topology.Promotables)
                    {
                        if (dbRecord.DeletionInProgress != null && dbRecord.DeletionInProgress.ContainsKey(promotable))
                        {
                            continue;
                        }

                        topology.PredefinedMentors.TryGetValue(promotable, out var mentorCandidate);
                        var node   = GetNode(databaseName, clusterTopology, promotable, mentorCandidate, out var promotableTask);
                        var mentor = topology.WhoseTaskIsIt(ServerStore.Engine.CurrentState, promotableTask, null);
                        nodesTopology.Promotables.Add(GetNodeId(node, mentor));
                        SetNodeStatus(topology, promotable, nodesTopology, statuses);
                    }

                    foreach (var rehab in topology.Rehabs)
                    {
                        if (dbRecord.DeletionInProgress != null && dbRecord.DeletionInProgress.ContainsKey(rehab))
                        {
                            continue;
                        }

                        var node   = GetNode(databaseName, clusterTopology, rehab, null, out var promotableTask);
                        var mentor = topology.WhoseTaskIsIt(ServerStore.Engine.CurrentState, promotableTask, null);
                        nodesTopology.Rehabs.Add(GetNodeId(node, mentor));
                        SetNodeStatus(topology, rehab, nodesTopology, statuses);
                    }
                }

                if (online == false)
                {
                    // if state of database is found in the cache we can continue
                    if (ServerStore.DatabaseInfoCache.TryGet(databaseName, databaseInfoJson =>
                    {
                        databaseInfoJson.Modifications = new DynamicJsonValue(databaseInfoJson)
                        {
                            [nameof(DatabaseInfo.Disabled)] = disabled,
                            [nameof(DatabaseInfo.IndexingStatus)] = indexingStatus.ToString(),
                            [nameof(DatabaseInfo.NodesTopology)] = nodesTopology.ToJson(),
                            [nameof(DatabaseInfo.DeletionInProgress)] = DynamicJsonValue.Convert(dbRecord.DeletionInProgress),
                            [nameof(DatabaseInfo.Environment)] = studioEnvironment
                        };

                        context.Write(writer, databaseInfoJson);
                    }))
                    {
                        return;
                    }

                    // we won't find it if it is a new database or after a dirty shutdown,
                    // so just report empty values then
                }

                var size = db?.GetSizeOnDisk() ?? (new Size(0), new Size(0));

                var databaseInfo = new DatabaseInfo
                {
                    Name            = databaseName,
                    Disabled        = disabled,
                    TotalSize       = size.Data,
                    TempBuffersSize = size.TempBuffers,

                    IsAdmin     = true,
                    IsEncrypted = dbRecord.Encrypted,
                    UpTime      = online ? (TimeSpan?)GetUptime(db) : null,
                    BackupInfo  = GetBackupInfo(db),

                    Alerts           = db?.NotificationCenter.GetAlertCount() ?? 0,
                    PerformanceHints = db?.NotificationCenter.GetPerformanceHintCount() ?? 0,
                    RejectClients    = false,
                    LoadError        = null,
                    IndexingErrors   = db?.IndexStore?.GetIndexes()?.Sum(index => index.GetErrorCount()) ?? 0,

                    DocumentsCount             = db?.DocumentsStorage.GetNumberOfDocuments() ?? 0,
                    HasRevisionsConfiguration  = db?.DocumentsStorage.RevisionsStorage.Configuration != null,
                    HasExpirationConfiguration = (db?.ExpiredDocumentsCleaner?.ExpirationConfiguration?.Disabled ?? true) == false,
                    HasRefreshConfiguration    = (db?.ExpiredDocumentsCleaner?.RefreshConfiguration?.Disabled ?? true) == false,
                    IndexesCount   = db?.IndexStore?.GetIndexes()?.Count() ?? 0,
                    IndexingStatus = indexingStatus ?? IndexRunningStatus.Running,
                    Environment    = studioEnvironment,

                    NodesTopology            = nodesTopology,
                    ReplicationFactor        = topology?.ReplicationFactor ?? -1,
                    DynamicNodesDistribution = topology?.DynamicNodesDistribution ?? false,
                    DeletionInProgress       = dbRecord.DeletionInProgress
                };

                var doc = databaseInfo.ToJson();
                context.Write(writer, doc);
            }
            catch (Exception e)
            {
                if (Logger.IsInfoEnabled)
                {
                    Logger.Info($"Failed to get database info for: {databaseName}", e);
                }

                WriteFaultedDatabaseInfo(databaseName, e, context, writer);
            }
        }
예제 #16
0
        public async Task Server_store_write_should_throw_concurrency_exception_if_relevant()
        {
            using (GetDocumentStore())
            {
                var certificate = new X509Certificate2(GenerateAndSaveSelfSignedCertificate(), (string)null, X509KeyStorageFlags.MachineKeySet);

                TransactionOperationContext context;
                using (Server.ServerStore.ContextPool.AllocateOperationContext(out context))
                    using (context.OpenWriteTransaction())
                    {
                        using (Server.ServerStore.ContextPool.AllocateOperationContext(out context))
                        {
                            await Server.ServerStore.PutValueInClusterAsync(new PutCertificateCommand("foo/bar", new CertificateDefinition
                            {
                                Certificate = Convert.ToBase64String(certificate.Export(X509ContentType.Cert)),
                                Permissions = null,
                                SecurityClearance = SecurityClearance.ClusterAdmin,
                                Thumbprint = certificate.Thumbprint,
                                PublicKeyPinningHash = certificate.GetPublicKeyPinningHash(),
                                NotAfter = certificate.NotAfter
                            }, string.Empty));
                        }
                    }

                using (Server.ServerStore.ContextPool.AllocateOperationContext(out context))
                {
                    using (Server.ServerStore.ContextPool.AllocateOperationContext(out context))
                    {
                        await Server.ServerStore.PutValueInClusterAsync(new PutCertificateCommand("foo/bar", new CertificateDefinition
                        {
                            Certificate = Convert.ToBase64String(certificate.Export(X509ContentType.Cert)),
                            Permissions = null,
                            SecurityClearance = SecurityClearance.ClusterAdmin,
                            Thumbprint = certificate.Thumbprint,
                            PublicKeyPinningHash = certificate.GetPublicKeyPinningHash(),
                            NotAfter = certificate.NotAfter
                        }, string.Empty));
                    }
                }

                using (Server.ServerStore.ContextPool.AllocateOperationContext(out context))
                {
                    var foo = new DynamicJsonValue
                    {
                        ["Foo"] = "Bar3"
                    };

                    using (var blittableObj = context.ReadObject(foo, "read test stuff"))
                    {
                        //TODO: Restore this.

                        ////this shouldn't throw, since expected etag == null
                        //Server.ServerStore.PutValueInClusterAsync(context, "foo/bar", blittableObj).Wait();

                        //var lastEtag = Server.ServerStore.ReadLastEtag(context);
                        ////this shouldn't throw, since expected etag == existing etag
                        //Server.ServerStore.Write(context, "foo/bar", blittableObj, lastEtag);

                        ////this should throw because existing etag doesn't match with existing etag
                        //Assert.Throws<global::Voron.Exceptions.ConcurrencyException>(
                        //    () => Server.ServerStore.Write(context, "foo/bar", blittableObj, 1));

                        ////this should throw because it has expected etag, but there is no existing value
                        //Assert.Throws<global::Voron.Exceptions.ConcurrencyException>(
                        //    () => Server.ServerStore.Write(context, "foo/bar2", blittableObj, 1));
                    }
                }
            }
        }
예제 #17
0
 public override void FillJson(DynamicJsonValue json)
 {
     json[nameof(Definition)] = TypeConverter.ToBlittableSupportedType(Definition);
 }
예제 #18
0
        public Task MemorySmaps()
        {
            if (PlatformDetails.RunningOnLinux == false)
            {
                using (ServerStore.ContextPool.AllocateOperationContext(out JsonOperationContext context))
                    using (var process = Process.GetCurrentProcess())
                    {
                        var sharedClean = MemoryInformation.GetSharedCleanInBytes(process);
                        var rc          = Win32MemoryQueryMethods.GetMaps();
                        var djv         = new DynamicJsonValue
                        {
                            ["Totals"] = new DynamicJsonValue
                            {
                                ["WorkingSet"]          = process.WorkingSet64,
                                ["SharedClean"]         = Sizes.Humane(sharedClean),
                                ["PrivateClean"]        = "N/A",
                                ["TotalClean"]          = rc.ProcessClean,
                                ["RssHumanly"]          = Sizes.Humane(process.WorkingSet64),
                                ["SharedCleanHumanly"]  = Sizes.Humane(sharedClean),
                                ["PrivateCleanHumanly"] = "N/A",
                                ["TotalCleanHumanly"]   = Sizes.Humane(rc.ProcessClean)
                            },
                            ["Details"] = rc.Json
                        };
                        using (var write = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                        {
                            context.Write(write, djv);
                        }
                        return(Task.CompletedTask);
                    }
            }

            using (ServerStore.ContextPool.AllocateOperationContext(out JsonOperationContext context))
            {
                var buffers = new[]
                {
                    ArrayPool <byte> .Shared.Rent(SmapsReader.BufferSize),
                    ArrayPool <byte> .Shared.Rent(SmapsReader.BufferSize)
                };
                try
                {
                    var result     = new SmapsReader(buffers).CalculateMemUsageFromSmaps <SmapsReaderJsonResults>();
                    var procStatus = MemoryInformation.GetMemoryUsageFromProcStatus();
                    var djv        = new DynamicJsonValue
                    {
                        ["Totals"] = new DynamicJsonValue
                        {
                            ["WorkingSet"]            = result.Rss,
                            ["SharedClean"]           = result.SharedClean,
                            ["PrivateClean"]          = result.PrivateClean,
                            ["TotalClean"]            = result.SharedClean + result.PrivateClean,
                            ["TotalDirty"]            = result.TotalDirty, // This includes not only r-ws buffer and voron files, but also dotnet's and heap dirty memory
                            ["WorkingSetSwap"]        = result.Swap,       // Swap values sum for r-ws entries only
                            ["Swap"]                  = procStatus.Swap,
                            ["RssHumanly"]            = Sizes.Humane(result.Rss),
                            ["SwapHumanly"]           = Sizes.Humane(procStatus.Swap),
                            ["WorkingSetSwapHumanly"] = Sizes.Humane(result.Swap),
                            ["SharedCleanHumanly"]    = Sizes.Humane(result.SharedClean),
                            ["PrivateCleanHumanly"]   = Sizes.Humane(result.PrivateClean),
                            ["TotalCleanHumanly"]     = Sizes.Humane(result.SharedClean + result.PrivateClean)
                        },
                        ["Details"] = result.SmapsResults.ReturnResults()
                    };

                    using (var write = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                    {
                        context.Write(write, djv);
                    }

                    return(Task.CompletedTask);
                }
                finally
                {
                    ArrayPool <byte> .Shared.Return(buffers[0]);

                    ArrayPool <byte> .Shared.Return(buffers[1]);
                }
            }
        }
예제 #19
0
 public override void FillJson(DynamicJsonValue json)
 {
     json[nameof(TaskId)]        = TaskId;
     json[nameof(Configuration)] = TypeConverter.ToBlittableSupportedType(Configuration);
     json[nameof(EtlType)]       = EtlType;
 }
예제 #20
0
        private static DynamicJsonValue MemoryStatsInternal()
        {
            var memInfo            = MemoryInformation.GetMemoryInformationUsingOneTimeSmapsReader();
            var memoryUsageRecords = MemoryInformation.GetMemoryUsageRecords();

            long totalMapping          = 0;
            var  fileMappingByDir      = new Dictionary <string, Dictionary <string, ConcurrentDictionary <IntPtr, long> > >();
            var  fileMappingSizesByDir = new Dictionary <string, long>();

            foreach (var mapping in NativeMemory.FileMapping)
            {
                var dir = Path.GetDirectoryName(mapping.Key);

                if (fileMappingByDir.TryGetValue(dir, out Dictionary <string, ConcurrentDictionary <IntPtr, long> > value) == false)
                {
                    value = new Dictionary <string, ConcurrentDictionary <IntPtr, long> >();
                    fileMappingByDir[dir] = value;
                }

                value[mapping.Key] = mapping.Value.Value.Info;
                foreach (var singleMapping in mapping.Value.Value.Info)
                {
                    fileMappingSizesByDir.TryGetValue(dir, out long prevSize);
                    fileMappingSizesByDir[dir] = prevSize + singleMapping.Value;
                    totalMapping += singleMapping.Value;
                }
            }

            var prefixLength = LongestCommonPrefixLength(new List <string>(fileMappingSizesByDir.Keys));

            var fileMappings = new DynamicJsonArray();

            foreach (var sizes in fileMappingSizesByDir.OrderByDescending(x => x.Value))
            {
                if (fileMappingByDir.TryGetValue(sizes.Key, out Dictionary <string, ConcurrentDictionary <IntPtr, long> > value))
                {
                    var details = new DynamicJsonValue();

                    var dir = new DynamicJsonValue
                    {
                        [nameof(MemoryInfoMappingItem.Directory)]                = sizes.Key.Substring(prefixLength),
                        [nameof(MemoryInfoMappingItem.TotalDirectorySize)]       = sizes.Value,
                        [nameof(MemoryInfoMappingItem.HumaneTotalDirectorySize)] = Size.Humane(sizes.Value),
                        [nameof(MemoryInfoMappingItem.Details)] = details
                    };
                    foreach (var file in value.OrderBy(x => x.Key))
                    {
                        long totalMapped = 0;
                        var  dja         = new DynamicJsonArray();
                        var  dic         = new Dictionary <long, long>();
                        foreach (var mapping in file.Value)
                        {
                            totalMapped += mapping.Value;
                            dic.TryGetValue(mapping.Value, out long prev);
                            dic[mapping.Value] = prev + 1;
                        }

                        foreach (var maps in dic)
                        {
                            dja.Add(new DynamicJsonValue
                            {
                                [nameof(MemoryInfoMappingDetails.Size)]  = maps.Key,
                                [nameof(MemoryInfoMappingDetails.Count)] = maps.Value
                            });
                        }

                        var fileSize = GetFileSize(file.Key);
                        details[Path.GetFileName(file.Key)] = new DynamicJsonValue
                        {
                            [nameof(MemoryInfoMappingFileInfo.FileSize)]          = fileSize,
                            [nameof(MemoryInfoMappingFileInfo.HumaneFileSize)]    = Size.Humane(fileSize),
                            [nameof(MemoryInfoMappingFileInfo.TotalMapped)]       = totalMapped,
                            [nameof(MemoryInfoMappingFileInfo.HumaneTotalMapped)] = Size.Humane(totalMapped),
                            [nameof(MemoryInfoMappingFileInfo.Mappings)]          = dja
                        };
                    }

                    fileMappings.Add(dir);
                }
            }

            long totalUnmanagedAllocations = NativeMemory.TotalAllocatedMemory;
            var  threads = new DynamicJsonArray();

            foreach (var stats in NativeMemory.AllThreadStats
                     .Where(x => x.IsThreadAlive())
                     .GroupBy(x => x.Name)
                     .OrderByDescending(x => x.Sum(y => y.TotalAllocated)))
            {
                var unmanagedAllocations = stats.Sum(x => x.TotalAllocated);
                var ids = new DynamicJsonArray(stats.OrderByDescending(x => x.TotalAllocated).Select(x => new DynamicJsonValue
                {
                    ["Id"] = x.UnmanagedThreadId,
                    ["ManagedThreadId"]   = x.ManagedThreadId,
                    ["Allocations"]       = x.TotalAllocated,
                    ["HumaneAllocations"] = Size.Humane(x.TotalAllocated)
                }));
                var groupStats = new DynamicJsonValue
                {
                    ["Name"]              = stats.Key,
                    ["Allocations"]       = unmanagedAllocations,
                    ["HumaneAllocations"] = Size.Humane(unmanagedAllocations)
                };
                if (ids.Count == 1)
                {
                    var threadStats = stats.First();
                    groupStats["Id"] = threadStats.UnmanagedThreadId;
                    groupStats["ManagedThreadId"] = threadStats.ManagedThreadId;
                }
                else
                {
                    groupStats["Ids"] = ids;
                }

                threads.Add(groupStats);
            }

            long managedMemoryInBytes = AbstractLowMemoryMonitor.GetManagedMemoryInBytes();
            long workingSetInBytes    = memInfo.WorkingSet.GetValue(SizeUnit.Bytes);
            var  dirtyMemoryState     = MemoryInformation.GetDirtyMemoryState();
            var  encryptionBuffers    = EncryptionBuffersPool.Instance.GetStats();

            var djv = new DynamicJsonValue
            {
                [nameof(MemoryInfo.WorkingSet)] = workingSetInBytes,
                [nameof(MemoryInfo.TotalUnmanagedAllocations)] = totalUnmanagedAllocations,
                [nameof(MemoryInfo.ManagedAllocations)]        = managedMemoryInBytes,
                [nameof(MemoryInfo.TotalMemoryMapped)]         = totalMapping,
                [nameof(MemoryInfo.TotalScratchDirtyMemory)]   = Size.Humane(memInfo.TotalScratchDirtyMemory.GetValue(SizeUnit.Bytes)),
                [nameof(MemoryInfo.PhysicalMem)]       = Size.Humane(memInfo.TotalPhysicalMemory.GetValue(SizeUnit.Bytes)),
                [nameof(DirtyMemoryState.IsHighDirty)] = dirtyMemoryState.IsHighDirty,
                ["DirtyMemory"] = Size.Humane(dirtyMemoryState.TotalDirtyInBytes),
                [nameof(MemoryInfo.AvailableMemory)] = Size.Humane(memInfo.AvailableMemory.GetValue(SizeUnit.Bytes)),
                [nameof(MemoryInfo.AvailableMemoryForProcessing)] = Size.Humane(memInfo.AvailableMemoryForProcessing.GetValue(SizeUnit.Bytes)),
                [nameof(MemoryInfo.HighMemLastOneMinute)]         = Size.Humane(memoryUsageRecords.High.LastOneMinute.GetValue(SizeUnit.Bytes)),
                [nameof(MemoryInfo.LowMemLastOneMinute)]          = Size.Humane(memoryUsageRecords.Low.LastOneMinute.GetValue(SizeUnit.Bytes)),
                [nameof(MemoryInfo.HighMemLastFiveMinute)]        = Size.Humane(memoryUsageRecords.High.LastFiveMinutes.GetValue(SizeUnit.Bytes)),
                [nameof(MemoryInfo.LowMemLastFiveMinute)]         = Size.Humane(memoryUsageRecords.Low.LastFiveMinutes.GetValue(SizeUnit.Bytes)),
                [nameof(MemoryInfo.HighMemSinceStartup)]          = Size.Humane(memoryUsageRecords.High.SinceStartup.GetValue(SizeUnit.Bytes)),
                [nameof(MemoryInfo.LowMemSinceStartup)]           = Size.Humane(memoryUsageRecords.Low.SinceStartup.GetValue(SizeUnit.Bytes)),

                [nameof(MemoryInfo.Humane)] = new DynamicJsonValue
                {
                    [nameof(MemoryInfoHumane.WorkingSet)] = Size.Humane(workingSetInBytes),
                    [nameof(MemoryInfoHumane.TotalUnmanagedAllocations)] = Size.Humane(totalUnmanagedAllocations),
                    ["EncryptionBuffers"] = Size.Humane(encryptionBuffers.TotalSize),
                    [nameof(MemoryInfoHumane.ManagedAllocations)] = Size.Humane(managedMemoryInBytes),
                    [nameof(MemoryInfoHumane.TotalMemoryMapped)]  = Size.Humane(totalMapping)
                },

                ["Threads"] = threads,

                [nameof(MemoryInfo.Mappings)] = fileMappings
            };

            return(djv);
        }
예제 #21
0
        internal Document ProjectFromMatch(Match match, JsonOperationContext context)
        {
            var result = new DynamicJsonValue();

            result[Constants.Documents.Metadata.Key] = new DynamicJsonValue
            {
                [Constants.Documents.Metadata.Projection] = true
            };

            var item = new Document();

            foreach (var fieldToFetch in FieldsToFetch.Fields.Values)
            {
                object fieldVal;
                string key;
                if (fieldToFetch.QueryField?.ExpressionField?.Compound?.Contains("[]") ?? false)
                {
                    key = fieldToFetch.QueryField.ExpressionField.Compound.LastOrDefault().Value;
                }
                else
                {
                    key = fieldToFetch.ProjectedName ?? fieldToFetch.Name.Value;
                }

                if (fieldToFetch.QueryField.Function != null)
                {
                    var args = new object[fieldToFetch.FunctionArgs.Length + 1];
                    for (int i = 0; i < fieldToFetch.FunctionArgs.Length; i++)
                    {
                        var val = match.GetResult(fieldToFetch.FunctionArgs[i].ProjectedName);
                        switch (val)
                        {
                        case Document doc:
                            doc.EnsureMetadata();
                            args[i] = doc;
                            break;

                        case BlittableJsonReaderObject bjro:
                            args[i] = bjro;
                            break;

                        case List <Match> matchList:
                            CreateArgsFromMatchList(matchList, args, i);
                            break;

                        case MatchCollection matchCollection:
                            CreateArgsFromMatchList(matchCollection, args, i);
                            break;

                        case string s:
                            args[i] = s;
                            break;

                        default:
                            args[i] = null;
                            break;
                        }
                    }

                    key      = fieldToFetch.ProjectedName ?? (fieldToFetch.ProjectedName ?? fieldToFetch.Name.Value);
                    fieldVal = GetFunctionValue(fieldToFetch, null, args);

                    var immediateResult = AddProjectionToResult(item, 1f, FieldsToFetch, result, key, fieldVal);
                    if (immediateResult != null)
                    {
                        return(immediateResult);
                    }
                }
                else
                {
                    var val = match.GetResult(fieldToFetch.QueryField.ExpressionField.Compound[0].Value);

                    switch (val)
                    {
                    case Document d:
                    {
                        if (TryGetValue(fieldToFetch, d, null, null, out key, out fieldVal) == false)
                        {
                            continue;
                        }
                        d.EnsureMetadata();
                        var immediateResult = AddProjectionToResult(d, 1f, FieldsToFetch, result, key, fieldVal);
                        if (immediateResult != null)
                        {
                            return(immediateResult);
                        }
                        break;
                    }

                    case BlittableJsonReaderObject bjro:
                    {
                        var doc = new Document {
                            Data = bjro
                        };
                        if (TryGetValue(fieldToFetch, doc, null, null, out key, out fieldVal) == false)
                        {
                            continue;
                        }
                        doc.EnsureMetadata();
                        var immediateResult = AddProjectionToResult(doc, 1f, FieldsToFetch, result, key, fieldVal);
                        if (immediateResult != null)
                        {
                            return(immediateResult);
                        }
                        break;
                    }

                    case MatchCollection matches:
                        var array = new DynamicJsonArray();
                        foreach (var m in matches)
                        {
                            var djv = new DynamicJsonValue();
                            m.PopulateVertices(djv);

                            if (djv.Properties.Count == 0)
                            {
                                continue;
                            }

                            var matchJson = _context.ReadObject(djv, "graph/arg");

                            var doc = new Document {
                                Data = matchJson
                            };

                            if (TryGetValue(fieldToFetch, doc, null, null, out key, out fieldVal) == false)
                            {
                                continue;
                            }
                            doc.EnsureMetadata();
                            if (ReferenceEquals(doc, fieldVal))
                            {
                                fieldVal = doc.Data;
                            }

                            array.Add(fieldVal);
                        }
                        result[key] = array;
                        break;

                    case string s:
                        result[fieldToFetch.ProjectedName ?? fieldToFetch.Name.Value] = s;
                        break;

                    default:
                        result[fieldToFetch.ProjectedName ?? fieldToFetch.Name.Value] = null;
                        continue;
                    }
                }
            }

            return(new Document
            {
                Data = context.ReadObject(result, "projection result")
            });
        }
        public static DynamicJsonValue ToJson(this IndexDefinition definition)
        {
            var result = new DynamicJsonValue();

#if FEATURE_TEST_INDEX
            result[nameof(IndexDefinition.IsTestIndex)] = definition.IsTestIndex;
#endif
            result[nameof(IndexDefinition.LockMode)] = definition.LockMode?.ToString();
            result[nameof(IndexDefinition.Priority)] = definition.Priority?.ToString();
            result[nameof(IndexDefinition.OutputReduceToCollection)] = definition.OutputReduceToCollection;
            result[nameof(IndexDefinition.Name)]   = definition.Name;
            result[nameof(IndexDefinition.Reduce)] = definition.Reduce;
            result[nameof(IndexDefinition.Type)]   = definition.Type.ToString();
            result[nameof(IndexDefinition.Maps)]   = new DynamicJsonArray(definition.Maps);

            var fields = new DynamicJsonValue();
            foreach (var kvp in definition.Fields)
            {
                DynamicJsonValue spatial = null;
                if (kvp.Value.Spatial != null)
                {
                    spatial = new DynamicJsonValue();
                    spatial[nameof(SpatialOptions.MaxTreeLevel)] = kvp.Value.Spatial.MaxTreeLevel;
                    spatial[nameof(SpatialOptions.MaxX)]         = kvp.Value.Spatial.MaxX;
                    spatial[nameof(SpatialOptions.MaxY)]         = kvp.Value.Spatial.MaxY;
                    spatial[nameof(SpatialOptions.MinX)]         = kvp.Value.Spatial.MinX;
                    spatial[nameof(SpatialOptions.MinY)]         = kvp.Value.Spatial.MinY;
                    spatial[nameof(SpatialOptions.Strategy)]     = kvp.Value.Spatial.Strategy.ToString();
                    spatial[nameof(SpatialOptions.Type)]         = kvp.Value.Spatial.Type.ToString();
                    spatial[nameof(SpatialOptions.Units)]        = kvp.Value.Spatial.Units.ToString();
                }

                var field = new DynamicJsonValue();
                field[nameof(IndexFieldOptions.Analyzer)]    = kvp.Value.Analyzer;
                field[nameof(IndexFieldOptions.Indexing)]    = kvp.Value.Indexing?.ToString();
                field[nameof(IndexFieldOptions.Spatial)]     = spatial;
                field[nameof(IndexFieldOptions.Storage)]     = kvp.Value.Storage?.ToString();
                field[nameof(IndexFieldOptions.Suggestions)] = kvp.Value.Suggestions;
                field[nameof(IndexFieldOptions.TermVector)]  = kvp.Value.TermVector?.ToString();

                fields[kvp.Key] = field;
            }

            result[nameof(IndexDefinition.Fields)] = fields;

            var settings = new DynamicJsonValue();
            foreach (var kvp in definition.Configuration)
            {
                settings[kvp.Key] = kvp.Value;
            }

            result[nameof(IndexDefinition.Configuration)] = settings;

            var additionalSources = new DynamicJsonValue();
            foreach (var kvp in definition.AdditionalSources)
            {
                additionalSources[kvp.Key] = kvp.Value;
            }

            result[nameof(IndexDefinition.AdditionalSources)] = additionalSources;

            return(result);
        }
예제 #23
0
        public static object ToBlittableSupportedType(object value, DocumentConventions conventions, JsonOperationContext context)
        {
            if (value == null)
            {
                return(null);
            }

            var type           = value.GetType();
            var underlyingType = Nullable.GetUnderlyingType(type);

            if (underlyingType != null)
            {
                type = underlyingType;
            }

            if (type == typeof(string))
            {
                return(value);
            }

            if (type == typeof(LazyStringValue) || type == typeof(LazyCompressedStringValue))
            {
                return(value);
            }

            if (type == typeof(bool))
            {
                return(value);
            }

            if (type == typeof(int) || type == typeof(long) || type == typeof(double) || type == typeof(decimal) || type == typeof(float))
            {
                return(value);
            }

            if (type == typeof(LazyNumberValue))
            {
                return(value);
            }

            if (type == typeof(DateTime) || type == typeof(DateTimeOffset) || type == typeof(TimeSpan))
            {
                return(value);
            }

            if (type == typeof(Guid))
            {
                return(((Guid)value).ToString("D"));
            }

            if (type.GetTypeInfo().IsSubclassOf(typeof(Enum)))
            {
                return(value.ToString());
            }

            var dictionary = value as IDictionary;

            if (dictionary != null)
            {
                var @object = new DynamicJsonValue();
                foreach (var key in dictionary.Keys)
                {
                    @object[key.ToString()] = ToBlittableSupportedType(dictionary[key], conventions, context);
                }

                return(@object);
            }

            var enumerable = value as IEnumerable;

            if (enumerable != null)
            {
                var objectEnumerable = value as IEnumerable <object>;
                var items            = objectEnumerable != null
                    ? objectEnumerable.Select(x => ToBlittableSupportedType(x, conventions, context))
                    : enumerable.Cast <object>().Select(x => ToBlittableSupportedType(x, conventions, context));

                return(new DynamicJsonArray(items));
            }

            using (var writer = new BlittableJsonWriter(context))
            {
                var serializer = conventions.CreateSerializer();

                serializer.Serialize(writer, value);
                writer.FinalizeDocument();

                return(writer.CreateReader());
            }
        }
예제 #24
0
 public override void FillJson(DynamicJsonValue json)
 {
     json[nameof(SorterName)] = SorterName;
 }
 public override void FillJson(DynamicJsonValue json)
 {
     json[nameof(PeriodicBackupStatus)] = PeriodicBackupStatus.ToJson();
 }
 public override void FillJson(DynamicJsonValue json)
 {
     json[nameof(DatabaseName)] = DatabaseName;
     json[nameof(Prefix)]       = Prefix;
 }
예제 #27
0
        public Task GetClusterTopology()
        {
            using (ServerStore.ContextPool.AllocateOperationContext(out TransactionOperationContext context))
                using (context.OpenReadTransaction())
                {
                    var topology = ServerStore.GetClusterTopology(context);
                    var nodeTag  = ServerStore.NodeTag;

                    if (topology.AllNodes.Count == 0)
                    {
                        var tag       = ServerStore.NodeTag ?? "A";
                        var serverUrl = ServerStore.GetNodeHttpServerUrl(HttpContext.Request.GetClientRequestedNodeUrl());

                        topology = new ClusterTopology(
                            topology.TopologyId ?? "dummy",
                            new Dictionary <string, string>
                        {
                            [tag] = serverUrl
                        },
                            new Dictionary <string, string>(),
                            new Dictionary <string, string>(),
                            tag,
                            -1L
                            );
                        nodeTag = tag;
                    }
                    else
                    {
                        var isClientIndependent = GetBoolValueQueryString("clientIndependent", false) ?? false;
                        if (isClientIndependent == false && HttpContext.Items.TryGetValue(nameof(LocalEndpointClient.DebugPackage), out var _) == false)
                        {
                            topology.ReplaceCurrentNodeUrlWithClientRequestedNodeUrlIfNecessary(ServerStore, HttpContext);
                        }
                    }

                    HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;

                    using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                    {
                        var loadLicenseLimits  = ServerStore.LoadLicenseLimits();
                        var nodeLicenseDetails = loadLicenseLimits == null ?
                                                 null : DynamicJsonValue.Convert(loadLicenseLimits.NodeLicenseDetails);
                        var json = new DynamicJsonValue
                        {
                            [nameof(ClusterTopologyResponse.Topology)] = topology.ToSortedJson(),
                            [nameof(ClusterTopologyResponse.Etag)]     = topology.Etag,
                            [nameof(ClusterTopologyResponse.Leader)]   = ServerStore.LeaderTag,
                            ["LeaderShipDuration"] = ServerStore.Engine.CurrentLeader?.LeaderShipDuration,
                            ["CurrentState"]       = ServerStore.CurrentRachisState,
                            [nameof(ClusterTopologyResponse.NodeTag)] = nodeTag,
                            ["CurrentTerm"]        = ServerStore.Engine.CurrentTerm,
                            ["NodeLicenseDetails"] = nodeLicenseDetails,
                            [nameof(ServerStore.Engine.LastStateChangeReason)] = ServerStore.LastStateChangeReason()
                        };
                        var clusterErrors = ServerStore.GetClusterErrors();
                        if (clusterErrors.Count > 0)
                        {
                            json["Errors"] = clusterErrors;
                        }

                        var nodesStatues = ServerStore.GetNodesStatuses();
                        json["Status"] = DynamicJsonValue.Convert(nodesStatues);

                        context.Write(writer, json);
                        writer.Flush();
                    }
                }

            return(Task.CompletedTask);
        }
 public override void FillJson(DynamicJsonValue json)
 {
     json[nameof(Watcher)] = Watcher.ToJson();
 }
예제 #29
0
 public static void SetMinimalMeterData(this MeterMetric self, string name, DynamicJsonValue obj)
 {
     obj["Total" + name] = self.Count;
     obj[name + "Rate"]  = Math.Round(self.OneMinuteRate, 2);
 }
예제 #30
0
 public override void FillJson(DynamicJsonValue json)
 {
     json[nameof(NodeTag)] = NodeTag;
 }