private void EnsurePreviousValueMatchCurrentValue(PatchRequest patchCmd, RavenJToken property) { var prevVal = patchCmd.PrevVal; if (prevVal == null) { return; } switch (prevVal.Type) { case JTokenType.Undefined: if (property != null) { throw new ConcurrencyException(); } break; default: if (property == null) { throw new ConcurrencyException(); } var equalityComparer = new RavenJTokenEqualityComparer(); if (equalityComparer.Equals(property, prevVal) == false) { throw new ConcurrencyException(); } break; } }
/// <summary> /// Uses an encrypted document to verify that the encryption key is correct and decodes it to the right value. /// </summary> public static void VerifyEncryptionKey(DocumentDatabase database, EncryptionSettings settings) { JsonDocument doc; try { doc = database.Documents.Get(Constants.InResourceKeyVerificationDocumentName, null); } catch (CryptographicException e) { throw new ConfigurationErrorsException("The database is encrypted with a different key and/or algorithm than the ones " + "currently in the configuration file.", e); } if (doc != null) { var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer(); if (!ravenJTokenEqualityComparer.Equals(doc.DataAsJson, Constants.InResourceKeyVerificationDocumentContents)) { throw new ConfigurationErrorsException("The database is encrypted with a different key and/or algorithm than the ones " + "currently in the configuration file."); } } else { // This is the first time the database is loaded. if (EncryptedDocumentsExist(database)) { throw new InvalidOperationException("The database already has existing documents, you cannot start using encryption now."); } var clonedDoc = (RavenJObject)Constants.InResourceKeyVerificationDocumentContents.CreateSnapshot(); database.Documents.Put(Constants.InResourceKeyVerificationDocumentName, null, clonedDoc, new RavenJObject(), null); } }
public override void OnPut(string key, Stream data, RavenJObject metadata) { using (Database.DisableAllTriggersForCurrentThread()) { metadata.Remove(Constants.RavenReplicationConflict); // you can't put conflicts var oldVersion = Database.Attachments.GetStatic(key); if (oldVersion == null) { return; } if (oldVersion.Metadata[Constants.RavenReplicationConflict] == null) { return; } var history = new RavenJArray(ReplicationData.GetHistory(metadata)); metadata[Constants.RavenReplicationHistory] = history; var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer(); // this is a conflict document, holding document keys in the // values of the properties var conflictData = oldVersion.Data().ToJObject(); var conflicts = conflictData.Value <RavenJArray>("Conflicts"); if (conflicts == null) { return; } foreach (var prop in conflicts) { var id = prop.Value <string>(); Attachment attachment = Database.Attachments.GetStatic(id); if (attachment == null) { continue; } Database.Attachments.DeleteStatic(id, null); // add the conflict history to the mix, so we make sure that we mark that we resolved the conflict var conflictHistory = new RavenJArray(ReplicationData.GetHistory(attachment.Metadata)); conflictHistory.Add(new RavenJObject { { Constants.RavenReplicationVersion, attachment.Metadata[Constants.RavenReplicationVersion] }, { Constants.RavenReplicationSource, attachment.Metadata[Constants.RavenReplicationSource] } }); foreach (var item in conflictHistory) { if (history.Any(x => ravenJTokenEqualityComparer.Equals(x, item))) { continue; } history.Add(item); } } } }
/// <summary> /// Determines if the entity have changed. /// </summary> /// <param name="entity">The entity.</param> /// <param name="documentMetadata">The document metadata.</param> /// <returns></returns> protected bool EntityChanged(object entity, DocumentMetadata documentMetadata) { if (documentMetadata == null) { return(true); } var newObj = ConvertEntityToJson(entity, documentMetadata.Metadata); var equalityComparer = new RavenJTokenEqualityComparer(); return(equalityComparer.Equals(newObj, documentMetadata.OriginalValue) == false || equalityComparer.Equals(documentMetadata.Metadata, documentMetadata.OriginalMetadata) == false); }
public override void OnPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation) { using (Database.DisableAllTriggersForCurrentThread()) { metadata.Remove(Constants.RavenReplicationConflict); // you can't put conflicts var oldVersion = Database.Get(key, transactionInformation); if (oldVersion == null) { return; } if (oldVersion.Metadata[Constants.RavenReplicationConflict] == null) { return; } RavenJArray history = new RavenJArray(ReplicationData.GetHistory(metadata)); metadata[Constants.RavenReplicationHistory] = history; var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer(); // this is a conflict document, holding document keys in the // values of the properties var conflicts = oldVersion.DataAsJson.Value <RavenJArray>("Conflicts"); if (conflicts == null) { return; } foreach (var prop in conflicts) { RavenJObject deletedMetadata; Database.Delete(prop.Value <string>(), null, transactionInformation, out deletedMetadata); // add the conflict history to the mix, so we make sure that we mark that we resolved the conflict var conflictHistory = new RavenJArray(ReplicationData.GetHistory(deletedMetadata)); conflictHistory.Add(new RavenJObject { { Constants.RavenReplicationVersion, deletedMetadata[Constants.RavenReplicationVersion] }, { Constants.RavenReplicationSource, deletedMetadata[Constants.RavenReplicationSource] } }); foreach (var item in conflictHistory) { if (history.Any(x => ravenJTokenEqualityComparer.Equals(x, item))) { continue; } history.Add(item); } } } }
public override void OnPut(string key, Stream data, RavenJObject metadata) { using (Database.DisableAllTriggersForCurrentThread()) { metadata.Remove(Constants.RavenReplicationConflict);// you can't put conflicts var oldVersion = Database.GetStatic(key); if (oldVersion == null) return; if (oldVersion.Metadata[Constants.RavenReplicationConflict] == null) return; RavenJArray history = metadata.Value<RavenJArray>(Constants.RavenReplicationHistory) ?? new RavenJArray(); metadata[Constants.RavenReplicationHistory] = history; var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer(); // this is a conflict document, holding document keys in the // values of the properties var conflictData = oldVersion.Data().ToJObject(); var conflicts = conflictData.Value<RavenJArray>("Conflicts"); if (conflicts == null) return; foreach (var prop in conflicts) { var id = prop.Value<string>(); Attachment attachment = Database.GetStatic(id); if(attachment == null) continue; Database.DeleteStatic(id, null); // add the conflict history to the mix, so we make sure that we mark that we resolved the conflict var conflictHistory = attachment.Metadata.Value<RavenJArray>(Constants.RavenReplicationHistory) ?? new RavenJArray(); conflictHistory.Add(new RavenJObject { {Constants.RavenReplicationVersion, attachment.Metadata[Constants.RavenReplicationVersion]}, {Constants.RavenReplicationSource, attachment.Metadata[Constants.RavenReplicationSource]} }); foreach (var item in conflictHistory) { if (history.Any(x => ravenJTokenEqualityComparer.Equals(x, item))) continue; history.Add(item); } } } }
private void RemoveValue(PatchRequest patchCmd, string propName, RavenJToken token) { EnsurePreviousValueMatchCurrentValue(patchCmd, token); if (token == null) { token = new RavenJArray(); document[propName] = token; } var array = GetArray(token, propName); var position = patchCmd.Position; var value = patchCmd.Value; if (position == null && (value == null || value.Type == JTokenType.Null)) { throw new InvalidOperationException("Cannot remove value from '" + propName + "' because position element does not exists or not an integer and no value was present"); } if (position != null && value != null && value.Type != JTokenType.Null) { throw new InvalidOperationException("Cannot remove value from '" + propName + "' because both a position and a value are set"); } if (position != null && (position.Value < 0 || position.Value >= array.Length)) { throw new IndexOutOfRangeException("Cannot remove value from '" + propName + "' because position element is out of bound bounds"); } if (value != null && value.Type != JTokenType.Null) { var equalityComparer = new RavenJTokenEqualityComparer(); var singleOrDefault = array.FirstOrDefault(x => equalityComparer.Equals(x, value)); if (singleOrDefault == null) { return; } array.Remove(singleOrDefault); return; } if (position != null) { array.RemoveAt(position.Value); } }
/// <summary> /// Uses an encrypted document to verify that the encryption key is correct and decodes it to the right value. /// </summary> public static void VerifyEncryptionKey(RavenFileSystem fileSystem, EncryptionSettings settings) { RavenJObject config = null; try { fileSystem.Storage.Batch(accessor => { try { config = accessor.GetConfig(Constants.InResourceKeyVerificationDocumentName); } catch (FileNotFoundException) { } }); } catch (CryptographicException e) { throw new ConfigurationErrorsException("The file system is encrypted with a different key and/or algorithm than the ones " + "currently in the configuration file.", e); } if (config != null) { var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer(); if (!ravenJTokenEqualityComparer.Equals(config, Constants.InResourceKeyVerificationDocumentContents)) { throw new ConfigurationErrorsException("The file system is encrypted with a different key and/or algorithm than the ones is currently configured"); } } else { // This is the first time the file system is loaded. if (EncryptedFileExist(fileSystem)) { throw new InvalidOperationException("The file system already has existing files, you cannot start using encryption now."); } var clonedDoc = (RavenJObject)Constants.InResourceKeyVerificationDocumentContents.CreateSnapshot(); fileSystem.Storage.Batch(accessor => accessor.SetConfig(Constants.InResourceKeyVerificationDocumentName, clonedDoc)); } }
public override void OnPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation) { using (Database.DisableAllTriggersForCurrentThread()) { metadata.Remove(ReplicationConstants.RavenReplicationConflict);// you can't put conflicts var oldVersion = Database.Get(key, transactionInformation); if (oldVersion == null) return; if (oldVersion.Metadata[ReplicationConstants.RavenReplicationConflict] == null) return; RavenJArray history = metadata.Value<RavenJArray>(ReplicationConstants.RavenReplicationHistory) ?? new RavenJArray(); metadata[ReplicationConstants.RavenReplicationHistory] = history; var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer(); // this is a conflict document, holding document keys in the // values of the properties var conflicts = oldVersion.DataAsJson.Value<RavenJArray>("Conflicts"); if (conflicts == null) return; foreach (var prop in conflicts) { RavenJObject deletedMetadata; Database.Delete(prop.Value<string>(), null, transactionInformation, out deletedMetadata); // add the conflict history to the mix, so we make sure that we mark that we resolved the conflict var conflictHistory = deletedMetadata.Value<RavenJArray>(ReplicationConstants.RavenReplicationHistory) ?? new RavenJArray(); conflictHistory.Add(new RavenJObject { {ReplicationConstants.RavenReplicationVersion, deletedMetadata[ReplicationConstants.RavenReplicationVersion]}, {ReplicationConstants.RavenReplicationSource, deletedMetadata[ReplicationConstants.RavenReplicationSource]} }); foreach (var item in conflictHistory) { if(history.Any(x=>ravenJTokenEqualityComparer.Equals(x, item))) continue; history.Add(item); } } } }
/// <summary> /// Determines if the entity have changed. /// </summary> /// <param name="entity">The entity.</param> /// <param name="documentMetadata">The document metadata.</param> /// <returns></returns> protected bool EntityChanged(object entity, DocumentMetadata documentMetadata) { if (documentMetadata == null) { return(true); } // prevent saves of a modified read only entity if (documentMetadata.OriginalMetadata.ContainsKey(Constants.RavenReadOnly) && documentMetadata.OriginalMetadata.Value <bool>(Constants.RavenReadOnly) && documentMetadata.Metadata.ContainsKey(Constants.RavenReadOnly) && documentMetadata.Metadata.Value <bool>(Constants.RavenReadOnly)) { return(false); } var newObj = ConvertEntityToJson(entity, documentMetadata.Metadata); var equalityComparer = new RavenJTokenEqualityComparer(); return(equalityComparer.Equals(newObj, documentMetadata.OriginalValue) == false || equalityComparer.Equals(documentMetadata.Metadata, documentMetadata.OriginalMetadata) == false); }
/// <summary> /// Uses an encrypted document to verify that the encryption key is correct and decodes it to the right value. /// </summary> public static void VerifyEncryptionKey(DocumentDatabase database, EncryptionSettings settings) { JsonDocument doc; try { doc = database.Documents.Get(Constants.InDatabaseKeyVerificationDocumentName, null); } catch (CryptographicException e) { throw new ConfigurationErrorsException("The database is encrypted with a different key and/or algorithm than the ones " + "currently in the configuration file.", e); } if (doc != null) { var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer(); if (!ravenJTokenEqualityComparer.Equals(doc.DataAsJson,Constants.InDatabaseKeyVerificationDocumentContents)) throw new ConfigurationErrorsException("The database is encrypted with a different key and/or algorithm than the ones " + "currently in the configuration file."); } else { // This is the first time the database is loaded. if (EncryptedDocumentsExist(database)) throw new InvalidOperationException("The database already has existing documents, you cannot start using encryption now."); var clonedDoc = (RavenJObject)Constants.InDatabaseKeyVerificationDocumentContents.CreateSnapshot(); database.Documents.Put(Constants.InDatabaseKeyVerificationDocumentName, null, clonedDoc, new RavenJObject(), null); } }
public override void OnPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation) { using (Database.DisableAllTriggersForCurrentThread()) { metadata.Remove(Constants.RavenReplicationConflict); // you can't put conflicts var oldVersion = Database.Get(key, transactionInformation); if (oldVersion == null) { return; } if (oldVersion.Metadata[Constants.RavenReplicationConflict] == null) { return; } var history = new RavenJArray(); metadata[Constants.RavenReplicationHistory] = history; var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer(); // this is a conflict document, holding document keys in the // values of the properties var conflicts = oldVersion.DataAsJson.Value <RavenJArray>("Conflicts"); if (conflicts == null) { return; } var list = new List <RavenJArray> { new RavenJArray(ReplicationData.GetHistory(metadata)) // first item to interleave }; foreach (var prop in conflicts) { RavenJObject deletedMetadata; Database.Delete(prop.Value <string>(), null, transactionInformation, out deletedMetadata); if (deletedMetadata != null) { var conflictHistory = new RavenJArray(ReplicationData.GetHistory(deletedMetadata)); conflictHistory.Add(new RavenJObject { { Constants.RavenReplicationVersion, deletedMetadata[Constants.RavenReplicationVersion] }, { Constants.RavenReplicationSource, deletedMetadata[Constants.RavenReplicationSource] } }); list.Add(conflictHistory); } } int index = 0; bool added = true; while (added) // interleave the history from all conflicts { added = false; foreach (var deletedMetadata in list) { // add the conflict history to the mix, so we make sure that we mark that we resolved the conflict if (index < deletedMetadata.Length) { history.Add(deletedMetadata[index]); added = true; } } index++; } while (history.Length > Constants.ChangeHistoryLength) { history.RemoveAt(0); } } }
private void EnsurePreviousValueMatchCurrentValue(PatchRequest patchCmd, RavenJToken property) { var prevVal = patchCmd.PrevVal; if (prevVal == null) return; switch (prevVal.Type) { case JTokenType.Undefined: if (property != null) throw new ConcurrencyException(); break; default: if (property == null) throw new ConcurrencyException(); var equalityComparer = new RavenJTokenEqualityComparer(); if (equalityComparer.Equals(property, prevVal) == false) throw new ConcurrencyException(); break; } }
private void RemoveValue(PatchRequest patchCmd, string propName, RavenJToken token) { EnsurePreviousValueMatchCurrentValue(patchCmd, token); if (token == null) { token = new RavenJArray(); document[propName] = token; } var array = GetArray(token, propName); var position = patchCmd.Position; var value = patchCmd.Value; if (position == null && value == null) throw new InvalidOperationException("Cannot remove value from '" + propName + "' because position element does not exists or not an integer and no value was present"); if (position != null && value != null) throw new InvalidOperationException("Cannot remove value from '" + propName + "' because both a position and a value are set"); if (position < 0 || position >= array.Length) throw new IndexOutOfRangeException("Cannot remove value from '" + propName + "' because position element is out of bound bounds"); if (value != null) { var equalityComparer = new RavenJTokenEqualityComparer(); var singleOrDefault = array.FirstOrDefault(x => equalityComparer.Equals(x, value)); if (singleOrDefault == null) return; array.Remove(singleOrDefault); return; } array.RemoveAt(position.Value); }
public override void OnPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation) { using (Database.DisableAllTriggersForCurrentThread()) { metadata.Remove(Constants.RavenReplicationConflict);// you can't put conflicts var oldVersion = Database.Get(key, transactionInformation); if (oldVersion == null) return; if (oldVersion.Metadata[Constants.RavenReplicationConflict] == null) return; var history = new RavenJArray(); metadata[Constants.RavenReplicationHistory] = history; var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer(); // this is a conflict document, holding document keys in the // values of the properties var conflicts = oldVersion.DataAsJson.Value<RavenJArray>("Conflicts"); if(conflicts == null) return; var list = new List<RavenJArray> { new RavenJArray(ReplicationData.GetHistory(metadata)) // first item to interleave }; foreach (var prop in conflicts) { RavenJObject deletedMetadata; Database.Delete(prop.Value<string>(), null, transactionInformation, out deletedMetadata); if (deletedMetadata != null) { var conflictHistory = new RavenJArray(ReplicationData.GetHistory(deletedMetadata)); conflictHistory.Add(new RavenJObject { {Constants.RavenReplicationVersion, deletedMetadata[Constants.RavenReplicationVersion]}, {Constants.RavenReplicationSource, deletedMetadata[Constants.RavenReplicationSource]} }); list.Add(conflictHistory); } } int index = 0; bool added = true; while (added) // interleave the history from all conflicts { added = false; foreach (var deletedMetadata in list) { // add the conflict history to the mix, so we make sure that we mark that we resolved the conflict if (index < deletedMetadata.Length) { history.Add(deletedMetadata[index]); added = true; } } index++; } while (history.Length > Constants.ChangeHistoryLength) { history.RemoveAt(0); } } }
/// <summary> /// Uses an encrypted document to verify that the encryption key is correct and decodes it to the right value. /// </summary> public static void VerifyEncryptionKey(RavenFileSystem fileSystem, EncryptionSettings settings) { RavenJObject config = null; try { fileSystem.Storage.Batch(accessor => { try { config = accessor.GetConfig(Constants.InResourceKeyVerificationDocumentName); } catch (FileNotFoundException) { } }); } catch (CryptographicException e) { throw new ConfigurationErrorsException("The file system is encrypted with a different key and/or algorithm than the ones " + "currently in the configuration file.", e); } if (config != null) { var ravenJTokenEqualityComparer = new RavenJTokenEqualityComparer(); if (!ravenJTokenEqualityComparer.Equals(config, Constants.InResourceKeyVerificationDocumentContents)) throw new ConfigurationErrorsException("The file system is encrypted with a different key and/or algorithm than the ones is currently configured"); } else { // This is the first time the file system is loaded. if (EncryptedFileExist(fileSystem)) throw new InvalidOperationException("The file system already has existing files, you cannot start using encryption now."); var clonedDoc = (RavenJObject)Constants.InResourceKeyVerificationDocumentContents.CreateSnapshot(); fileSystem.Storage.Batch(accessor => accessor.SetConfig(Constants.InResourceKeyVerificationDocumentName, clonedDoc)); } }