Ejemplo n.º 1
0
        public void Sync()
        {
            using (var store = new DocumentStore())
            {
                #region open_cluster_session_sync

                using (var session = store.OpenSession(new SessionOptions
                {
                    TransactionMode = TransactionMode.ClusterWide
                }))

                #endregion

                {
                    #region new_compare_exchange_sync
                    // occupy "Best NoSQL Transactional Database" to be "RavenDB"
                    session.Advanced.ClusterTransaction.CreateCompareExchangeValue(key: "Best NoSQL Transactional Database", value: "RavenDB");
                    session.SaveChanges();
                    #endregion

                    #region update_compare_exchange_sync
                    // load the existing dns record of ravendb.net
                    CompareExchangeValue <DNS> result = session.Advanced.ClusterTransaction.GetCompareExchangeValue <DNS>(key: "ravendb.net");

                    // change the ip
                    result.Value.IpAddress = "52.32.173.150";
                    session.Advanced.ClusterTransaction.UpdateCompareExchangeValue(result);

                    // save the changes
                    session.SaveChanges();
                    #endregion


                    var key   = "key";
                    var keys  = new[] { "key" };
                    var index = 0L;
                    var value = default(T);

                    #region methods_1_sync
                    session.Advanced.ClusterTransaction.GetCompareExchangeValue <T>(key);
                    #endregion

                    #region methods_2_sync
                    session.Advanced.ClusterTransaction.GetCompareExchangeValues <T>(keys);
                    #endregion

                    #region methods_3_sync
                    session.Advanced.ClusterTransaction.CreateCompareExchangeValue(key, value);
                    #endregion

                    #region methods_4_sync
                    session.Advanced.ClusterTransaction.DeleteCompareExchangeValue(key, index);
                    #endregion

                    #region methods_5_sync
                    session.Advanced.ClusterTransaction.UpdateCompareExchangeValue(new CompareExchangeValue <T>(key, index, value));
                    #endregion
                }
            }
        }
Ejemplo n.º 2
0
 public CompareExchangeSessionValue(CompareExchangeValue <BlittableJsonReaderObject> value)
     : this(value.Key, value.Index, value.Index >= 0 ? CompareExchangeValueState.None : CompareExchangeValueState.Missing)
 {
     if (value.Index > 0)
     {
         _originalValue = value;
     }
 }
Ejemplo n.º 3
0
        public void DeleteCompareExchangeValue <T>(CompareExchangeValue <T> item)
        {
            EnsureNotStored(item.Key);

            if (_deleteCompareExchange == null)
            {
                _deleteCompareExchange = new Dictionary <string, long>();
            }

            _deleteCompareExchange[item.Key] = item.Index;
        }
Ejemplo n.º 4
0
        public void UpdateCompareExchangeValue <T>(CompareExchangeValue <T> item)
        {
            EnsureNotDeleted(item.Key);

            if (_storeCompareExchange == null)
            {
                _storeCompareExchange = new Dictionary <string, StoredCompareExchange>();
            }

            _storeCompareExchange[item.Key] = new StoredCompareExchange(item.Index, item.Value);
        }
Ejemplo n.º 5
0
            internal CompareExchangeValue <T> Create <T>(T item)
            {
                AssertState();

                if (_value != null)
                {
                    throw new InvalidOperationException($"The compare exchange value with key '{_key}' is already tracked.");
                }

                _index = 0;
                var value = new CompareExchangeValue <T>(_key, _index, item);

                _value = value;
                _state = CompareExchangeValueState.Created;
                return(value);
            }
        public IActionResult Run(RunParams runParams)
        {
            string cmpXchgKey   = runParams.CmpXchgKey ?? "*****@*****.**";
            string cmpXchgValue = runParams.CmpXchgValue ?? "employee/1-A";

            string result = null;

            #region Demo
            #region Step_1
            var putCmpXchgOperation =
                new PutCompareExchangeValueOperation <string>(cmpXchgKey, cmpXchgValue, 0);

            CompareExchangeResult <string> putCmpXchgResult =
                DocumentStoreHolder.Store.Operations.Send(putCmpXchgOperation);
            #endregion

            #region Step_2
            var success    = putCmpXchgResult.Successful;
            var putValue   = putCmpXchgResult.Value;
            var putVersion = putCmpXchgResult.Index;

            if (success == false)
            {
                result = "Key already exists";
            }
            #endregion

            #region Step_3
            var getCmpXchgOperation =
                new GetCompareExchangeValueOperation <string>(cmpXchgKey);

            CompareExchangeValue <string> getCmpXchgResult =
                DocumentStoreHolder.Store.Operations.Send(getCmpXchgOperation);
            #endregion

            #region Step_4
            var key                 = getCmpXchgResult.Key;
            var currentValue        = getCmpXchgResult.Value;
            var currentValueVersion = getCmpXchgResult.Index;
            var currentMetadata     = getCmpXchgResult.Metadata;
            #endregion
            #endregion

            result = result ?? $"Created a new Compare-Exchange Key: {key}, Value: {currentValue}, Value Version: {currentValueVersion}";
            return(Ok(result));
        }
Ejemplo n.º 7
0
            internal void UpdateValue(CompareExchangeValue <BlittableJsonReaderObject> value, InMemoryDocumentSessionOperations session)
            {
                _index = value.Index;
                _state = value.Index >= 0 ? CompareExchangeValueState.None : CompareExchangeValueState.Missing;

                _originalValue = value;

                if (_value != null)
                {
                    _value.Index = _index;

                    if (_value.Value != null)
                    {
                        session.JsonConverter.PopulateEntity(_value.Value, value.Value, session.JsonSerializer);
                    }
                }
            }
Ejemplo n.º 8
0
            internal CompareExchangeValue <T> GetValue <T>(DocumentConventions conventions)
            {
                switch (_state)
                {
                case CompareExchangeValueState.None:
                case CompareExchangeValueState.Created:
                {
                    if (_value is CompareExchangeValue <T> v)
                    {
                        return(v);
                    }

                    if (_value != null)
                    {
                        throw new InvalidOperationException("Value cannot be null.");
                    }

                    T entity = default;
                    if (_originalValue != null && _originalValue.Value != null)
                    {
                        var type = typeof(T);
                        if (type.IsPrimitive || type == typeof(string))
                        {
                            _originalValue.Value.TryGet(Constants.CompareExchange.ObjectFieldName, out entity);
                        }
                        else
                        {
                            entity = conventions.Serialization.DefaultConverter.FromBlittable <T>(_originalValue.Value, _key);
                        }
                    }

                    var value = new CompareExchangeValue <T>(_key, _index, entity);
                    _value = value;

                    return(value);
                }

                case CompareExchangeValueState.Missing:
                case CompareExchangeValueState.Deleted:
                    return(null);

                default:
                    throw new NotSupportedException($"Not supported state: '{_state}'");
                }
            }
Ejemplo n.º 9
0
        public override async Task <IEnumerable <AggregateEventEnvelope <TAggregate> > > LoadHistory(long maxVersion, CancellationToken ctk = default)
        {
            var aggrname  = AggregateHelper <TAggregate> .Name;
            var envelopes = new List <AggregateEventStore>();

            _chex = await _session.Advanced.ClusterTransaction.GetCompareExchangeValueAsync <long>(_chexKey, ctk);

            if (_chex == null)
            {
                return(new AggregateEventEnvelope <TAggregate> [0]);
            }

            maxVersion = Math.Min(_chex.Value, maxVersion);

            string lastId = null;

            while (envelopes.Count != maxVersion)
            {
                var results = await _session.Advanced.StreamAsync <AggregateEventStore>(
                    $"{aggrname}/{Identifier}/",
                    startAfter : lastId,
                    pageSize : (int)maxVersion - envelopes.Count,
                    token : ctk);

                while (envelopes.Count != maxVersion && await results.MoveNextAsync())
                {
                    var envelope = results.Current;
                    if (envelope.Document.AggregateVersion != envelopes.Count + 1)
                    {
                        break;
                    }

                    envelopes.Add(envelope.Document);
                    lastId = envelope.Id;
                }
            }

            return(envelopes.Select(x => x.FromStore <TAggregate>()));
        }
Ejemplo n.º 10
0
        public override async Task SaveChangesAsync(CancellationToken ctk = default)
        {
            if (Aggregate.UncommittedAggregateEvents.Any())
            {
                if (_chex == null)
                {
                    _chex = _session.Advanced.ClusterTransaction.CreateCompareExchangeValue <long>(_chexKey, Aggregate.Version);
                }
                else
                {
                    _chex.Value = Aggregate.Version;
                }

                foreach (var e in Aggregate.UncommittedDomainEvents)
                {
                    var eventType  = e.Event.GetType();
                    var outboxType = typeof(OutboxEvent <>).MakeGenericType(eventType);

                    var evt = (OutboxEvent)Activator.CreateInstance(outboxType);

                    evt.Id       = e.Metadata.EventId;
                    evt.Metadata = e.Metadata.Values.ToDictionary(x => x.Key, x => x.Value);
                    evt.SetEvent(e.Event);

                    await _session.StoreAsync(evt, ctk);
                }

                foreach (var e in Aggregate.UncommittedAggregateEvents)
                {
                    await _session.StoreAsync(e.ToStore(), ctk);
                }

                await _session.StoreAsync(Aggregate.State, AggregateHelper <TAggregate> .Name + "/" + Aggregate.Identifier, ctk);

                await _session.SaveChangesAsync(ctk);
            }

            Aggregate.Commit();
        }
Ejemplo n.º 11
0
            internal bool HasChanged(CompareExchangeValue <BlittableJsonReaderObject> originalValue, CompareExchangeValue <BlittableJsonReaderObject> newValue)
            {
                if (ReferenceEquals(originalValue, newValue))
                {
                    return(false);
                }

                if (string.Equals(originalValue.Key, newValue.Key, StringComparison.OrdinalIgnoreCase) == false)
                {
                    throw new InvalidOperationException($"Keys do not match. Expected '{originalValue.Key}' but was '{newValue.Key}'.");
                }

                if (originalValue.Index != newValue.Index)
                {
                    return(true);
                }

                if (originalValue.Value == null)
                {
                    return(true);
                }

                return(originalValue.Value.Equals(newValue.Value) == false);
            }
Ejemplo n.º 12
0
        public async Task CreateFullAndIncrementalBackupWithCompareExchangeInTheMiddle()
        {
            var backupPath = NewDataPath(suffix: "BackupFolder");

            using (var store = GetDocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    session.Store(new User
                    {
                        Name = "Toli"
                    }, "users/1");
                    session.SaveChanges();
                }

                var config = new PeriodicBackupConfiguration
                {
                    LocalSettings = new LocalSettings
                    {
                        FolderPath = backupPath
                    },
                    Name = "full",
                    FullBackupFrequency = "* */6 * * *",
                    BackupType          = BackupType.Backup
                };

                var result = await store.Maintenance.SendAsync(new UpdatePeriodicBackupOperation(config));

                var documentDatabase = (await GetDocumentDatabaseInstanceFor(store));
                RunBackup(result.TaskId, documentDatabase, true, store);


                CompareExchangeResult <string> compareExchangeResult
                    = store.Operations.Send(
                          new PutCompareExchangeValueOperation <string>("users/1", "Mitzi", 0));

                config.IncrementalBackupFrequency = "* */2 * * *";
                config.TaskId = result.TaskId;
                result        = await store.Maintenance.SendAsync(new UpdatePeriodicBackupOperation(config));

                RunBackup(result.TaskId, documentDatabase, false, store);

                var backupDirectory = Directory.GetDirectories(backupPath).First();

                var databaseName = GetDatabaseName() + "restore";

                RestoreBackupConfiguration config2 = new RestoreBackupConfiguration()
                {
                    BackupLocation        = backupDirectory,
                    DatabaseName          = databaseName,
                    LastFileNameToRestore = Directory.GetFiles(backupDirectory).Last()
                };

                RestoreBackupOperation restoreOperation = new RestoreBackupOperation(config2);
                store.Maintenance.Server.Send(restoreOperation)
                .WaitForCompletion();

                using (var store2 = GetDocumentStore(new Options()
                {
                    CreateDatabase = false,
                    ModifyDatabaseName = s => databaseName
                }))
                {
                    using (var session = store2.OpenSession())
                    {
                        var doc = session.Load <User>("users/1");
                        Assert.NotNull(doc);
                    };
                    CompareExchangeValue <string> readResult =
                        store2.Operations.Send(new GetCompareExchangeValueOperation <string>("users/1"));

                    Assert.Equal("Mitzi", readResult.Value);
                };
            }
        }
Ejemplo n.º 13
0
        public CompareExchange()
        {
            using (var store = new DocumentStore())
            {
                {
                    #region get_1
                    CompareExchangeValue <long> readResult =
                        store.Operations.Send(new GetCompareExchangeValueOperation <long>("NextClientId"));

                    long value = readResult.Value;
                    #endregion
                }

                {
                    #region get_2
                    CompareExchangeValue <User> readResult =
                        store.Operations.Send(new GetCompareExchangeValueOperation <User>("AdminUser"));

                    User admin = readResult.Value;
                    #endregion
                }

                {
                    #region get_list_2
                    Dictionary <string, CompareExchangeValue <string> > compareExchangeValues
                        = store.Operations.Send(
                              new GetCompareExchangeValuesOperation <string>(new[] { "Key-1", "Key-2" }));
                    #endregion
                }

                {
                    #region get_list_3
                    // Get values for keys that have the common prefix 'users'
                    // Retrieve maximum 20 entries
                    Dictionary <string, CompareExchangeValue <User> > compareExchangeValues
                        = store.Operations.Send(new GetCompareExchangeValuesOperation <User>("users", 0, 20));
                    #endregion
                }

                {
                    #region put_1
                    CompareExchangeResult <string> compareExchangeResult
                        = store.Operations.Send(
                              new PutCompareExchangeValueOperation <string>("Emails/[email protected]", "users/123", 0));

                    bool successful = compareExchangeResult.Successful;
                    // If successfull is true: then Key '*****@*****.**' now has the value of "users/123"
                    #endregion
                }

                {
                    #region put_2
                    // Get existing value
                    CompareExchangeValue <User> readResult =
                        store.Operations.Send(
                            new GetCompareExchangeValueOperation <User>("AdminUser"));

                    readResult.Value.Age++;

                    // Update value
                    CompareExchangeResult <User> saveResult
                        = store.Operations.Send(
                              new PutCompareExchangeValueOperation <User>("AdminUser", readResult.Value, readResult.Index));

                    // The save result is successful only if 'index' wasn't changed between the read and write operations
                    bool saveResultSuccessful = saveResult.Successful;
                    #endregion
                }

                {
                    #region delete_1
                    // First, get existing value
                    CompareExchangeValue <User> readResult =
                        store.Operations.Send(
                            new GetCompareExchangeValueOperation <User>("AdminUser"));

                    // Delete the key - use the index received from the 'Get' operation
                    CompareExchangeResult <User> deleteResult
                        = store.Operations.Send(
                              new DeleteCompareExchangeValueOperation <User>("AdminUser", readResult.Index));

                    // The delete result is successful only if the index has not changed between the read and delete operations
                    bool deleteResultSuccessful = deleteResult.Successful;
                    #endregion
                }
            }
        }
Ejemplo n.º 14
0
        public CompareExchange()
        {
            using (var store = new DocumentStore())
            {
                {
                    #region get_1
                    CompareExchangeValue <long> readResult =
                        store.Operations.Send(new GetCompareExchangeValueOperation <long>("NextClientId"));

                    long value = readResult.Value;
                    #endregion
                }

                {
                    #region get_2
                    CompareExchangeValue <User> readResult =
                        store.Operations.Send(new GetCompareExchangeValueOperation <User>("AdminUser"));

                    User admin = readResult.Value;
                    #endregion
                }

                /*{ This overload is no longer available
                 #region get_list_2
                 *  Dictionary<string, CompareExchangeValue<string>> compareExchangeValues
                 *      = store.Operations.Send(
                 *          new GetCompareExchangeValuesOperation<string>(new[] { "Key-1", "Key-2" }));
                 #endregion
                 * }*/

                {
                    #region get_list_3
                    // Get values for keys that have the common prefix 'users'
                    // Retrieve maximum 20 entries
                    Dictionary <string, CompareExchangeValue <User> > compareExchangeValues
                        = store.Operations.Send(new GetCompareExchangeValuesOperation <User>("users", 0, 20));
                    #endregion
                }

                {
                    #region put_1
                    CompareExchangeResult <string> compareExchangeResult
                        = store.Operations.Send(
                              new PutCompareExchangeValueOperation <string>("Emails/[email protected]", "users/123", 0));

                    bool successful = compareExchangeResult.Successful;
                    // If successfull is true: then Key '*****@*****.**' now has the value of "users/123"
                    #endregion
                }

                {
                    #region put_2
                    // Get existing value
                    CompareExchangeValue <User> readResult =
                        store.Operations.Send(
                            new GetCompareExchangeValueOperation <User>("AdminUser"));

                    readResult.Value.Age++;

                    // Update value
                    CompareExchangeResult <User> saveResult
                        = store.Operations.Send(
                              new PutCompareExchangeValueOperation <User>("AdminUser", readResult.Value, readResult.Index));

                    // The save result is successful only if 'index' wasn't changed between the read and write operations
                    bool saveResultSuccessful = saveResult.Successful;
                    #endregion
                }

                {
                    #region delete_1
                    // First, get existing value
                    CompareExchangeValue <User> readResult =
                        store.Operations.Send(
                            new GetCompareExchangeValueOperation <User>("AdminUser"));

                    // Delete the key - use the index received from the 'Get' operation
                    CompareExchangeResult <User> deleteResult
                        = store.Operations.Send(
                              new DeleteCompareExchangeValueOperation <User>("AdminUser", readResult.Index));

                    // The delete result is successful only if the index has not changed between the read and delete operations
                    bool deleteResultSuccessful = deleteResult.Successful;
                    #endregion
                }

                #region expiration_0
                using (IAsyncDocumentSession session = store.OpenAsyncSession())
                {
                    // Set a time exactly one week from now
                    DateTime expirationTime = DateTime.UtcNow.AddDays(7);

                    // Create a new compare exchange value
                    var cmpxchgValue = session.Advanced.ClusterTransaction.CreateCompareExchangeValue("key", "value");

                    // Edit Metadata
                    cmpxchgValue.Metadata[Constants.Documents.Metadata.Expires] = expirationTime;

                    // Send to server
                    session.SaveChangesAsync();
                }
                #endregion

                using (IAsyncDocumentSession session = store.OpenAsyncSession())
                {
                    #region expiration_1
                    // Retrieve an existing key
                    CompareExchangeValue <string> cmpxchgValue = store.Operations.Send(
                        new GetCompareExchangeValueOperation <string>("key"));

                    // Set time
                    DateTime expirationTime = DateTime.UtcNow.AddDays(7);

                    // Edit Metadata
                    cmpxchgValue.Metadata[Constants.Documents.Metadata.Expires] = expirationTime;

                    // Update value. Index must match the index on the server side,
                    // or the operation will fail.
                    CompareExchangeResult <string> result = store.Operations.Send(
                        new PutCompareExchangeValueOperation <string>(
                            cmpxchgValue.Key,
                            cmpxchgValue.Value,
                            cmpxchgValue.Index));
                    #endregion
                }

                #region metadata_0
                using (IAsyncDocumentSession session = store.OpenAsyncSession(
                           new SessionOptions {
                    TransactionMode = TransactionMode.ClusterWide
                }))
                {
                    // Create a new compare exchange value
                    var cmpxchgValue = session.Advanced.ClusterTransaction.CreateCompareExchangeValue("key", "value");

                    // Add a field to the metadata
                    // with a value of type string
                    cmpxchgValue.Metadata["Field name"] = "some value";

                    // Retrieve metadata as a dictionary
                    IDictionary <string, object> cmpxchgMetadata = cmpxchgValue.Metadata;
                }
                #endregion
            }
        }
Ejemplo n.º 15
0
        public async Task CreateFullAndIncrementalBackupWithCompareExchangeInTheMiddle()
        {
            var backupPath = NewDataPath(suffix: "BackupFolder");

            using (var store = GetDocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    session.Store(new User
                    {
                        Name = "Toli"
                    }, "users/1");
                    session.SaveChanges();
                }

                var config       = Backup.CreateBackupConfiguration(backupPath);
                var backupTaskId = await Backup.UpdateConfigAndRunBackupAsync(Server, config, store);

                CompareExchangeResult <string> compareExchangeResult
                    = store.Operations.Send(
                          new PutCompareExchangeValueOperation <string>("users/1", "Mitzi", 0));

                WaitForValue(() => compareExchangeResult.Successful, true);

                await Backup.RunBackupAsync(Server, backupTaskId, store, isFullBackup : false);

                compareExchangeResult
                    = store.Operations.Send(
                          new PutCompareExchangeValueOperation <string>("users/1", "Mitzi2", compareExchangeResult.Index));

                WaitForValue(() => compareExchangeResult.Successful, true);

                await Backup.RunBackupAsync(Server, backupTaskId, store, isFullBackup : false);

                var backupDirectory = Directory.GetDirectories(backupPath).First();

                var databaseName = GetDatabaseName() + "restore";

                var files = Directory.GetFiles(backupDirectory)
                            .Where(BackupUtils.IsBackupFile)
                            .OrderBackups()
                            .ToArray();

                RestoreBackupConfiguration config2 = new RestoreBackupConfiguration()
                {
                    BackupLocation        = backupDirectory,
                    DatabaseName          = databaseName,
                    LastFileNameToRestore = files.Last()
                };

                RestoreBackupOperation restoreOperation = new RestoreBackupOperation(config2);
                store.Maintenance.Server.Send(restoreOperation)
                .WaitForCompletion();

                using (var store2 = GetDocumentStore(new Options()
                {
                    CreateDatabase = false,
                    ModifyDatabaseName = s => databaseName
                }))
                {
                    using (var session = store2.OpenSession())
                    {
                        var doc = session.Load <User>("users/1");
                        Assert.NotNull(doc);
                    };
                    CompareExchangeValue <string> readResult =
                        store2.Operations.Send(new GetCompareExchangeValueOperation <string>("users/1"));

                    Assert.Equal("Mitzi2", readResult.Value);
                };
            }
        }
Ejemplo n.º 16
0
            internal ICommandData GetCommand(DocumentConventions conventions, JsonOperationContext context, IJsonSerializer jsonSerializer)
            {
                switch (_state)
                {
                case CompareExchangeValueState.None:
                case CompareExchangeValueState.Created:
                    if (_value == null)
                    {
                        return(null);
                    }

                    var entity     = CompareExchangeValueBlittableJsonConverter.ConvertToBlittable(_value.Value, conventions, context, jsonSerializer);
                    var entityJson = entity as BlittableJsonReaderObject;
                    BlittableJsonReaderObject metadata = null;
                    if (_value.HasMetadata && _value.Metadata.Count != 0)
                    {
                        metadata = PrepareMetadataForPut(_key, _value.Metadata, conventions, context);
                    }

                    BlittableJsonReaderObject entityToInsert = null;

                    if (entityJson == null)
                    {
                        entityJson = entityToInsert = ConvertEntity(_key, entity, metadata);
                    }

                    var newValue = new CompareExchangeValue <BlittableJsonReaderObject>(_key, _index, entityJson);

                    var hasChanged = _originalValue == null || HasChanged(_originalValue, newValue);
                    _originalValue = newValue;

                    if (hasChanged == false)
                    {
                        return(null);
                    }

                    if (entityToInsert == null)
                    {
                        entityToInsert = ConvertEntity(_key, entity, metadata);
                    }

                    return(new PutCompareExchangeCommandData(newValue.Key, entityToInsert, newValue.Index));

                case CompareExchangeValueState.Deleted:
                    return(new DeleteCompareExchangeCommandData(_key, _index));

                case CompareExchangeValueState.Missing:
                    return(null);

                default:
                    throw new NotSupportedException($"Not supported state: '{_state}'");
                }

                BlittableJsonReaderObject ConvertEntity(string key, object entity, BlittableJsonReaderObject metadata = null)
                {
                    var djv = new DynamicJsonValue
                    {
                        [Constants.CompareExchange.ObjectFieldName] = entity
                    };

                    if (metadata == null)
                    {
                        return(context.ReadObject(djv, key));
                    }

                    djv[Constants.Documents.Metadata.Key] = metadata;
                    return(context.ReadObject(djv, key));
                }
            }