public override bool TryResolve( string id, RavenJObject metadata, RavenJObject document, JsonDocument existingDoc) { if (id.StartsWith("Raven/", StringComparison.OrdinalIgnoreCase) && !id.StartsWith("Raven/Hilo/", StringComparison.OrdinalIgnoreCase)) { return false; } try { this.ResolveConflict(id, metadata, document, existingDoc); } catch (Exception exception) { this.log.ErrorException( string.Format( "An exception occured while attempting to resolve a replication conflict for document '{0}'. The incoming document will be saved.", id), exception); } return true; }
private void HandleConflictedDocument(JsonDocument document, TransactionInformation transactionInformation) { var conflicts = document.DataAsJson.Value<RavenJArray>("Conflicts"); var currentSource = Database.TransactionalStorage.Id.ToString(); var historySet = false; foreach (var c in conflicts) { RavenJObject conflict; if (Database.Documents.Delete(c.Value<string>(), null, transactionInformation, out conflict) == false) continue; if (historySet) continue; var conflictSource = conflict.Value<RavenJValue>(Constants.RavenReplicationSource).Value<string>(); if (conflictSource != currentSource) continue; deletedHistory.Value = new RavenJArray { new RavenJObject { { Constants.RavenReplicationVersion, conflict[Constants.RavenReplicationVersion] }, { Constants.RavenReplicationSource, conflict[Constants.RavenReplicationSource] } } }; historySet = true; } }
protected void AddToContext(string key, JsonDocument document) { if(string.IsNullOrEmpty(key) || key.EndsWith("/")) incompleteDocumentKeyContext.Add(document); else documentKeyContext[key] = document; }
private IList<ColumnDefinition> PickLikelyColumns(JsonDocument[] sampleDocuments, string context, IList<PriorityColumn> priorityColumns) { if (priorityColumns == null || priorityColumns.Count == 0) { priorityColumns = DefaultPriorityColumns; } // only consider nested properties if any of the priority columns refers to a nested property var includeNestedProperties = priorityColumns.Any(c => c.PropertyNamePattern.Contains("\\.")); var columns = DocumentHelpers.GetPropertiesFromDocuments(sampleDocuments, includeNestedProperties) .GroupBy(p => p) .Select(g => new { Property = g.Key, Occurence = g.Count() / (double)sampleDocuments.Length }) .Select(p => new { p.Property, Importance = p.Occurence + ImportanceBoost(p.Property, context, priorityColumns) }) .OrderByDescending(p => p.Importance) .ThenBy(p => p.Property) .Select(p => new ColumnDefinition { Binding = p.Property, Header = p.Property, DefaultWidth = GetDefaultColumnWidth(p.Property, priorityColumns) }) .Take(6) .ToList(); return columns; }
private bool CanBeConsideredAsDuplicate(JsonDocument document) { if (document.Metadata[Constants.RavenReplicationConflict] != null) return false; return true; }
public void AfterStorageCommitBeforeWorkNotifications(PrefetchingUser user, JsonDocument[] documents) { foreach (var prefetcher in prefetchingBehaviors.Where(x => x.PrefetchingUser == user)) { prefetcher.AfterStorageCommitBeforeWorkNotifications(documents); } }
public override bool TryResolve(string id, RavenJObject metadata, RavenJObject document, JsonDocument existingDoc, Func<string, JsonDocument> getDocument, out RavenJObject metadataToSave, out RavenJObject documentToSave) { var existingDocumentIsInConflict = existingDoc.Metadata[Constants.RavenReplicationConflict] != null; var existingDocumentIsDeleted = existingDoc.Metadata[Constants.RavenDeleteMarker] != null && existingDoc.Metadata[Constants.RavenDeleteMarker].Value<bool>(); metadataToSave = null; documentToSave = null; if (existingDocumentIsInConflict && existingDocumentIsDeleted == false) { var conflictIds = existingDoc.DataAsJson.Value<RavenJArray>("Conflicts") .Select(x => x.Value<string>()) .ToArray(); if (conflictIds.Length == 0) return false; if (conflictIds .Select(getDocument) .Where(x => x != null) .All(doc => Historian.IsDirectChildOfCurrent(metadata, doc.Metadata)) == false) return false; metadataToSave = metadata; documentToSave = document; return true; } return false; }
public bool TryResolveConflict(string key, JsonDocument[] conflictedDocs, out JsonDocument resolvedDocument) { if (conflictedDocs == null || !conflictedDocs.Any()) { resolvedDocument = null; return false; } if (key.StartsWith("Raven/")) { resolvedDocument = null; return false; } var maxDate = conflictedDocs.Max(x => x.Metadata.Value<DateTimeOffset>(Constants.RavenLastModified)); resolvedDocument = conflictedDocs.FirstOrDefault(x => x.Metadata.Value<DateTimeOffset>(Constants.RavenLastModified) == maxDate); if (resolvedDocument != null) { // Do the logging before we override the metadata resolvedDocument.Metadata.Remove("@id"); resolvedDocument.Metadata.Remove("@etag"); resolvedDocument.Metadata.Remove(Constants.RavenReplicationConflict); resolvedDocument.Metadata.Remove(Constants.RavenReplicationConflictDocument); } return resolvedDocument != null; }
public bool TryResolveConflict(string key, JsonDocument[] conflictedDocs, out JsonDocument resolvedDocument) { var maxDate = conflictedDocs.Max(x => x.LastModified); resolvedDocument = conflictedDocs.FirstOrDefault(x => x.LastModified == maxDate); return resolvedDocument != null; }
public void AfterStorageCommitBeforeWorkNotifications(PrefetchingUser user, JsonDocument[] documents) { PrefetchingBehavior value; if (prefetchingBehaviors.TryGetValue(user, out value) == false) return; value.AfterStorageCommitBeforeWorkNotifications(documents); }
private void HandleConflictedDocument(JsonDocument document, TransactionInformation transactionInformation) { var conflicts = document.DataAsJson.Value<RavenJArray>("Conflicts"); var currentSource = Database.TransactionalStorage.Id.ToString(); foreach (var c in conflicts) { var conflict = Database.Get(c.Value<string>(), transactionInformation); var conflictSource = conflict.Metadata.Value<RavenJValue>(Constants.RavenReplicationSource).Value<string>(); if (conflictSource != currentSource) continue; this.deletedHistory.Value = new RavenJArray { new RavenJObject { { Constants.RavenReplicationVersion, conflict.Metadata[Constants.RavenReplicationVersion] }, { Constants.RavenReplicationSource, conflict.Metadata[Constants.RavenReplicationSource] } } }; return; } }
public void Add(JsonDocument value) { Debug.Assert(slim.IsWriteLockHeld); var index = CalculateEtagIndex(value.Etag); innerList.Insert(index, value); loadedSize += value.SerializedSizeOnDisk; }
public void Add(JsonDocument value) { Debug.Assert(slim.IsWriteLockHeld); innerList[value.Etag] = value; loadedSize += value.SerializedSizeOnDisk; }
public static IEnumerable<string> GetMetadataFromDocuments(JsonDocument[] jsonDocuments, bool includeNestedPropeties) { return jsonDocuments.SelectMany( doc => GetPropertiesFromJObject(doc.Metadata, parentPropertyPath: "", includeNestedProperties: includeNestedPropeties)); }
public override bool TryResolve(string id, RavenJObject metadata, RavenJObject document, JsonDocument existingDoc, Func<string, JsonDocument> getDocument, out RavenJObject metadataToSave, out RavenJObject documentToSave) { metadataToSave = existingDoc.Metadata; documentToSave = existingDoc.DataAsJson; return true; }
private IList<string> CreateSuggestedBindingsFromDocuments(JsonDocument[] jsonDocuments) { var bindings = DocumentHelpers.GetPropertiesFromDocuments(jsonDocuments, true).Distinct() .Concat(DocumentHelpers.GetMetadataFromDocuments(jsonDocuments, true).Distinct().Select(b => "$Meta:" + b)) .Concat(new[] {"$JsonDocument:Etag", "$JsonDocument:LastModified", "$Temp:Score"}) .ToArray(); return bindings; }
protected override bool TryResolve(string id, RavenJObject metadata, RavenJObject document, JsonDocument existingDoc, Func<string, JsonDocument> getDocument, out RavenJObject metadataToSave, out RavenJObject documentToSave) { metadataToSave = metadata; documentToSave = document; return true; }
private static async Task Save(string serverHash, JsonDocument document) { var path = "RavenDB Replication Information For - " + serverHash; var file = await folder.CreateFileAsync(path, CreationCollisionOption.ReplaceExisting); using (var stream = await file.OpenStreamForWriteAsync()) { document.ToJson().WriteTo(stream); } }
public ViewableDocument(JsonDocument inner) { this.inner = inner; Id = inner.Metadata.IfPresent<string>("@id"); LastModified = inner.LastModified ?? DateTime.MinValue; ClrType = inner.Metadata.IfPresent<string>(Constants.RavenClrType); CollectionType = DetermineCollectionType(inner.Metadata); }
private Guid GetFacetsEtag(JsonDocument jsonDocument, string index) { Guid etag; using(var md5 = MD5.Create()) { var etagBytes = md5.ComputeHash(Database.GetIndexEtag(index, null).ToByteArray().Concat(jsonDocument.Etag.Value.ToByteArray()).ToArray()); etag = new Guid(etagBytes); } return etag; }
private bool ExistingDocShouldWin(RavenJObject newMetadata, JsonDocument existingDoc) { if (existingDoc == null || ExistingDocHasConflict(existingDoc) || ExistingDocIsOlder(newMetadata, existingDoc)) { return false; } return true; }
public static void TrySavingReplicationInformationToLocalCache(string serverHash, JsonDocument document) { try { Save(serverHash, document).Wait(); } catch (Exception e) { log.ErrorException("Could not persist the replication information", e); } }
public bool TryResolveConflict(string key, JsonDocument[] conflictedDocs, out JsonDocument resolvedDocument) { resolvedDocument = new JsonDocument { DataAsJson = new RavenJObject { {"Name", string.Join(" ", conflictedDocs.Select(x => x.DataAsJson.Value<string>("Name")).OrderBy(x=>x))} }, Metadata = new RavenJObject() }; return true; }
public void UpdateSynchronizationState(JsonDocument[] docs) { if (docs == null) return; var lowestEtag = GetLowestEtag(docs); foreach (var key in etagSynchronizers) { key.Value.UpdateSynchronizationState(lowestEtag); } }
public override void PutDocument(string key, object documentAsObject, object metadataAsObject, Engine engine) { if (documentAsObject == null) { throw new InvalidOperationException( string.Format("Created document cannot be null or empty. Document key: '{0}'", key)); } var newDocument = new JsonDocument { Key = key, //DataAsJson = ToRavenJObject(doc) DataAsJson = RavenJObject.FromObject(documentAsObject) }; if (metadataAsObject == null) { RavenJToken value; if (newDocument.DataAsJson.TryGetValue("@metadata", out value)) { newDocument.DataAsJson.Remove("@metadata"); newDocument.Metadata = (RavenJObject)value; } } else { var metadata = RavenJObject.FromObject(metadataAsObject); foreach (var etagKeyName in EtagKeyNames) { RavenJToken etagValue; if (!metadata.TryGetValue(etagKeyName, out etagValue)) continue; metadata.Remove(etagKeyName); var etag = etagValue.Value<string>(); if (string.IsNullOrEmpty(etag)) continue; Etag newDocumentEtag; if (Etag.TryParse(etag, out newDocumentEtag) == false) throw new InvalidOperationException(string.Format("Invalid ETag value '{0}' for document '{1}'", etag, key)); newDocument.Etag = newDocumentEtag; } newDocument.Metadata = metadata; } ValidateDocument(newDocument); AddToContext(key, newDocument); }
private int? HandleIndexReplaceDocument(JsonDocument document) { if (document == null) return null; var id = document.Key; var replaceIndexName = id.Substring(Constants.IndexReplacePrefix.Length); var replaceIndex = Database.IndexStorage.GetIndexInstance(replaceIndexName); if (replaceIndex == null) { DeleteIndexReplaceDocument(id); return null; } var replaceIndexId = replaceIndex.IndexId; var indexDefinition = Database.IndexDefinitionStorage.GetIndexDefinition(replaceIndexId); if (!indexDefinition.IsSideBySideIndex) { indexDefinition.IsSideBySideIndex = true; Database.IndexDefinitionStorage.UpdateIndexDefinitionWithoutUpdatingCompiledIndex(indexDefinition); } var indexReplaceInformation = document.DataAsJson.JsonDeserialization<IndexReplaceInformation>(); indexReplaceInformation.ReplaceIndex = replaceIndexName; if (string.Equals(replaceIndexName, indexReplaceInformation.IndexToReplace, StringComparison.OrdinalIgnoreCase)) { DeleteIndexReplaceDocument(id); return null; } if (indexReplaceInformation.ReplaceTimeUtc.HasValue) { var dueTime = indexReplaceInformation.ReplaceTimeUtc.Value - SystemTime.UtcNow; if (dueTime.TotalSeconds < 0) dueTime = TimeSpan.Zero; indexReplaceInformation.ReplaceTimer = Database.TimerManager.NewTimer(state => InternalReplaceIndexes(new Dictionary<int, IndexReplaceInformation> { { replaceIndexId, indexReplaceInformation } }), dueTime, TimeSpan.FromDays(7)); } indexesToReplace.AddOrUpdate(replaceIndexId, s => indexReplaceInformation, (s, old) => { if (old.ReplaceTimer != null) Database.TimerManager.ReleaseTimer(old.ReplaceTimer); return indexReplaceInformation; }); return replaceIndexId; }
public void Add(JsonDocument value) { try { slim.EnterWriteLock(); var index = CalculateEtagIndex(value.Etag); innerList.Insert(index, value); } finally { slim.ExitWriteLock(); } }
private bool ExistingDocIsOlder(RavenJObject newMetadata, JsonDocument existingDoc) { var newLastModified = GetLastModified(newMetadata); if (!existingDoc.LastModified.HasValue || newLastModified.HasValue && existingDoc.LastModified <= newLastModified) { return true; } return false; }
protected long GetMaxFromDocument(JsonDocument document, long minMax) { long max; if (document.DataAsJson.ContainsKey("ServerHi")) // convert from hi to max { var hi = document.DataAsJson.Value<long>("ServerHi"); max = ((hi - 1) * capacity); document.DataAsJson.Remove("ServerHi"); document.DataAsJson["Max"] = max; } max = document.DataAsJson.Value<long>("Max"); return Math.Max(max, minMax); }
public void ConcurrentJsonDocumentSortedListShouldSortByEtag() { var list = new ConcurrentJsonDocumentSortedList(); var etag1 = EtagUtil.Increment(Etag.Empty, 1); var etag2 = EtagUtil.Increment(Etag.Empty, 2); var etag3 = EtagUtil.Increment(Etag.Empty, 3); var etag4 = EtagUtil.Increment(Etag.Empty, 4); var doc1 = new JsonDocument { Etag = etag1 }; var doc2 = new JsonDocument { Etag = etag2 }; var doc3 = new JsonDocument { Etag = etag3 }; var doc4 = new JsonDocument { Etag = etag4 }; using (list.EnterWriteLock()) { list.Add(doc4); list.Add(doc2); list.Add(doc1); list.Add(doc3); } JsonDocument result; Assert.True(list.TryDequeue(out result)); Assert.Equal(doc1.Etag, result.Etag); Assert.True(list.TryDequeue(out result)); Assert.Equal(doc2.Etag, result.Etag); Assert.True(list.TryDequeue(out result)); Assert.Equal(doc3.Etag, result.Etag); Assert.True(list.TryDequeue(out result)); Assert.Equal(doc4.Etag, result.Etag); }
public override bool TryResolve(string id, Raven.Json.Linq.RavenJObject metadata, Raven.Json.Linq.RavenJObject document, Raven.Abstractions.Data.JsonDocument existingDoc, Func <string, Raven.Abstractions.Data.JsonDocument> getDocument) { if (Enabled) { if (metadata.ContainsKey(Constants.RavenDeleteMarker)) { ReplaceValues(document, existingDoc.DataAsJson); ReplaceValues(document, existingDoc.Metadata); } } return(Enabled); }
public override bool TryResolve(string id, Raven.Json.Linq.RavenJObject metadata, Raven.Json.Linq.RavenJObject document, Raven.Abstractions.Data.JsonDocument existingDoc, Func <string, Raven.Abstractions.Data.JsonDocument> getDocument) { if (Enabled) { metadata.Add("Raven-Remove-Document-Marker", true); } return(Enabled); }