Exemple #1
0
        protected override BlittableJsonReaderObject GetUpdatedValue(long index, RawDatabaseRecord record, JsonOperationContext context, BlittableJsonReaderObject previousValue)
        {
            if (previousValue != null)
            {
                if (previousValue.Modifications == null)
                {
                    previousValue.Modifications = new DynamicJsonValue();
                }

                AddIndexesIfNecessary(previousValue.Modifications, previousValue, Indexes);

                if (previousValue.Modifications.Properties.Count == 0)
                {
                    return(previousValue);
                }

                return(context.ReadObject(previousValue, GetItemId()));
            }

            var djv = new DynamicJsonValue();

            AddIndexesIfNecessary(djv, null, Indexes);

            return(context.ReadObject(djv, GetItemId()));
        }
        protected override BlittableJsonReaderObject GetUpdatedValue(long index, RawDatabaseRecord record, JsonOperationContext context, BlittableJsonReaderObject existingValue)
        {
            var itemId = GetItemId();

            if (existingValue == null)
            {
                throw new SubscriptionDoesNotExistException($"Subscription with id '{itemId}' does not exist");
            }

            var subscription = JsonDeserializationCluster.SubscriptionState(existingValue);

            var topology            = record.Topology;
            var lastResponsibleNode = AcknowledgeSubscriptionBatchCommand.GetLastResponsibleNode(HasHighlyAvailableTasks, topology, NodeTag);
            var appropriateNode     = topology.WhoseTaskIsIt(RachisState.Follower, subscription, lastResponsibleNode);

            if (appropriateNode == null && record.DeletionInProgress.ContainsKey(NodeTag))
            {
                throw new DatabaseDoesNotExistException(
                          $"Stopping subscription '{SubscriptionName}' on node {NodeTag}, because database '{DatabaseName}' is being deleted.");
            }

            if (appropriateNode != NodeTag)
            {
                throw new SubscriptionDoesNotBelongToNodeException(
                          $"Can't update subscription with name {itemId} by node {NodeTag}, because it's not its task to update this subscription");
            }

            subscription.LastClientConnectionTime = LastClientConnectionTime;
            subscription.NodeTag = NodeTag;

            return(context.ReadObject(subscription.ToJson(), itemId));
        }
        private IDatabaseTask GetMatchingConfiguration(RawDatabaseRecord record)
        {
            var ravenEtls = record.RavenEtls;

            if (ravenEtls != null)
            {
                for (var i = 0; i < ravenEtls.Count; i++)
                {
                    if (ravenEtls[i].Name == ConfigurationName)
                    {
                        return(ravenEtls[i]);
                    }
                }
            }

            var sqlEtls = record.SqlEtls;

            if (sqlEtls != null)
            {
                for (var i = 0; i < sqlEtls.Count; i++)
                {
                    if (sqlEtls[i].Name == ConfigurationName)
                    {
                        return(sqlEtls[i]);
                    }
                }
            }

            return(null);
        }
Exemple #4
0
        private IDatabaseTask GetMatchingConfiguration(RawDatabaseRecord record)
        {
            var ravenEtls = record.RavenEtls;

            if (ravenEtls != null)
            {
                for (var i = 0; i < ravenEtls.Count; i++)
                {
                    if (ravenEtls[i].Name == ConfigurationName)
                    {
                        return(ravenEtls[i]);
                    }
                }
            }

            var sqlEtls = record.SqlEtls;

            if (sqlEtls != null)
            {
                for (var i = 0; i < sqlEtls.Count; i++)
                {
                    if (sqlEtls[i].Name == ConfigurationName)
                    {
                        return(sqlEtls[i]);
                    }
                }
            }

            var parquetEtls = record.OlapEtls;

            if (parquetEtls != null)
            {
                for (var i = 0; i < parquetEtls.Count; i++)
                {
                    if (parquetEtls[i].Name == ConfigurationName)
                    {
                        return(parquetEtls[i]);
                    }
                }
            }

            var elasticEtls = record.ElasticSearchEtls;

            if (elasticEtls != null)
            {
                for (var i = 0; i < elasticEtls.Count; i++)
                {
                    if (elasticEtls[i].Name == ConfigurationName)
                    {
                        return(elasticEtls[i]);
                    }
                }
            }

            return(null);
        }
Exemple #5
0
        protected override BlittableJsonReaderObject GetUpdatedValue(long index, RawDatabaseRecord record, JsonOperationContext context, BlittableJsonReaderObject existingValue)
        {
            var subscriptionName = SubscriptionName;

            if (string.IsNullOrEmpty(subscriptionName))
            {
                subscriptionName = SubscriptionId.ToString();
            }

            if (existingValue == null)
            {
                throw new SubscriptionDoesNotExistException($"Subscription with name '{subscriptionName}' does not exist");
            }

            var subscription        = JsonDeserializationCluster.SubscriptionState(existingValue);
            var topology            = record.Topology;
            var lastResponsibleNode = GetLastResponsibleNode(HasHighlyAvailableTasks, topology, NodeTag);
            var appropriateNode     = topology.WhoseTaskIsIt(RachisState.Follower, subscription, lastResponsibleNode);

            if (appropriateNode == null && record.DeletionInProgress.ContainsKey(NodeTag))
            {
                throw new DatabaseDoesNotExistException($"Stopping subscription '{subscriptionName}' on node {NodeTag}, because database '{DatabaseName}' is being deleted.");
            }

            if (appropriateNode != NodeTag)
            {
                throw new SubscriptionDoesNotBelongToNodeException(
                          $"Cannot apply {nameof(AcknowledgeSubscriptionBatchCommand)} for subscription '{subscriptionName}' with id '{SubscriptionId}', on database '{DatabaseName}', on node '{NodeTag}'," +
                          $" because the subscription task belongs to '{appropriateNode ?? "N/A"}'.")
                      {
                          AppropriateNode = appropriateNode
                      };
            }

            if (ChangeVector == nameof(Constants.Documents.SubscriptionChangeVectorSpecialStates.DoNotChange))
            {
                return(context.ReadObject(existingValue, SubscriptionName));
            }

            if (IsLegacyCommand())
            {
                if (LastKnownSubscriptionChangeVector != subscription.ChangeVectorForNextBatchStartingPoint)
                {
                    throw new SubscriptionChangeVectorUpdateConcurrencyException($"Can't acknowledge subscription with name {subscriptionName} due to inconsistency in change vector progress. Probably there was an admin intervention that changed the change vector value. Stored value: {subscription.ChangeVectorForNextBatchStartingPoint}, received value: {LastKnownSubscriptionChangeVector}");
                }

                subscription.ChangeVectorForNextBatchStartingPoint = ChangeVector;
            }

            subscription.NodeTag          = NodeTag;
            subscription.LastBatchAckTime = LastTimeServerMadeProgressWithDocuments;

            return(context.ReadObject(subscription.ToJson(), subscriptionName));
        }
        private static bool IsDatabaseBeingDeleted(string tag, RawDatabaseRecord databaseRecord)
        {
            if (databaseRecord == null)
            {
                return(false);
            }

            var deletionInProgress = databaseRecord.DeletionInProgress;

            return(deletionInProgress != null && deletionInProgress.TryGetValue(tag, out var delInProgress) && delInProgress != DeletionInProgressStatus.No);
        }
Exemple #7
0
        private static void UpdateDatabaseInfo(RawDatabaseRecord databaseRecord, ServerStore serverStore, string databaseName, DrivesUsage existingDrivesUsage,
                                               DatabaseInfoItem databaseInfoItem)
        {
            DatabaseInfo databaseInfo = null;

            if (serverStore.DatabaseInfoCache.TryGet(databaseName, databaseInfoJson =>
            {
                databaseInfo = JsonDeserializationServer.DatabaseInfo(databaseInfoJson);
            }) == false)
            {
                return;
            }

            Debug.Assert(databaseInfo != null);
            var databaseTopology = databaseRecord.Topology;
            var indexesCount     = databaseRecord.CountOfIndexes;

            databaseInfoItem.DocumentsCount      = databaseInfo.DocumentsCount ?? 0;
            databaseInfoItem.IndexesCount        = databaseInfo.IndexesCount ?? indexesCount;
            databaseInfoItem.ReplicationFactor   = databaseTopology?.ReplicationFactor ?? databaseInfo.ReplicationFactor;
            databaseInfoItem.ErroredIndexesCount = databaseInfo.IndexingErrors ?? 0;

            if (databaseInfo.MountPointsUsage == null)
            {
                return;
            }

            foreach (var mountPointUsage in databaseInfo.MountPointsUsage)
            {
                var driveName       = mountPointUsage.DiskSpaceResult.DriveName;
                var diskSpaceResult = DiskSpaceChecker.GetDiskSpaceInfo(
                    mountPointUsage.DiskSpaceResult.DriveName,
                    new DriveInfoBase
                {
                    DriveName = driveName
                });

                if (diskSpaceResult != null)
                {
                    // update the latest drive info
                    mountPointUsage.DiskSpaceResult = new Client.ServerWide.Operations.DiskSpaceResult
                    {
                        DriveName             = diskSpaceResult.DriveName,
                        VolumeLabel           = diskSpaceResult.VolumeLabel,
                        TotalFreeSpaceInBytes = diskSpaceResult.TotalFreeSpace.GetValue(SizeUnit.Bytes),
                        TotalSizeInBytes      = diskSpaceResult.TotalSize.GetValue(SizeUnit.Bytes)
                    };
                }

                UpdateMountPoint(serverStore.Configuration.Storage, mountPointUsage, databaseName, existingDrivesUsage);
            }
        }
Exemple #8
0
        protected override BlittableJsonReaderObject GetUpdatedValue(long index, RawDatabaseRecord record, JsonOperationContext context, BlittableJsonReaderObject existingValue)
        {
            EtlProcessState etlState;

            if (existingValue != null)
            {
                etlState = JsonDeserializationClient.EtlProcessState(existingValue);

                var databaseTask = GetMatchingConfiguration(record);

                if (databaseTask == null)
                {
                    throw new RachisApplyException($"Can't update progress of ETL {ConfigurationName} by node {NodeTag}, because it's configuration can't be found");
                }

                var topology            = record.Topology;
                var lastResponsibleNode = GetLastResponsibleNode(HasHighlyAvailableTasks, topology, NodeTag);
                if (topology.WhoseTaskIsIt(RachisState.Follower, databaseTask, lastResponsibleNode) != NodeTag)
                {
                    throw new RachisApplyException($"Can't update progress of ETL {ConfigurationName} by node {NodeTag}, because it's not its task to update this ETL");
                }
            }
            else
            {
                etlState = new EtlProcessState
                {
                    ConfigurationName  = ConfigurationName,
                    TransformationName = TransformationName
                };
            }

            if (DbId != null)
            {
                etlState.LastProcessedEtagPerDbId[DbId] = LastProcessedEtag;
            }

#pragma warning disable 618
            if (etlState.LastProcessedEtagPerNode?.Count > 0)
            {
                etlState.LastProcessedEtagPerNode[NodeTag] = LastProcessedEtag;
            }
#pragma warning restore 618

            etlState.ChangeVector          = ChangeVector;
            etlState.NodeTag               = NodeTag;
            etlState.SkippedTimeSeriesDocs = SkippedTimeSeriesDocs;
            etlState.LastBatchTime         = LastBatchTime;


            return(context.ReadObject(etlState.ToJson(), GetItemId()));
        }
Exemple #9
0
        protected override BlittableJsonReaderObject GetUpdatedValue(long index, RawDatabaseRecord record, JsonOperationContext context, BlittableJsonReaderObject existingValue)
        {
            var subscriptionName = SubscriptionName;

            if (string.IsNullOrEmpty(subscriptionName))
            {
                subscriptionName = SubscriptionId.ToString();
            }

            if (existingValue == null)
            {
                throw new SubscriptionDoesNotExistException($"Subscription with name {subscriptionName} does not exist");
            }

            var subscription = JsonDeserializationCluster.SubscriptionState(existingValue);

            var topology            = record.Topology;
            var lastResponsibleNode = GetLastResponsibleNode(HasHighlyAvailableTasks, topology, NodeTag);

            if (topology.WhoseTaskIsIt(RachisState.Follower, subscription, lastResponsibleNode) != NodeTag)
            {
                throw new SubscriptionDoesNotBelongToNodeException($"Can't update subscription with name {subscriptionName} by node {NodeTag}, because it's not its task to update this subscription");
            }

            if (ChangeVector == nameof(Constants.Documents.SubscriptionChangeVectorSpecialStates.DoNotChange))
            {
                return(context.ReadObject(existingValue, SubscriptionName));
            }

            if (LastKnownSubscriptionChangeVector != subscription.ChangeVectorForNextBatchStartingPoint)
            {
                throw new SubscriptionChangeVectorUpdateConcurrencyException($"Can't acknowledge subscription with name {subscriptionName} due to inconsistency in change vector progress. Probably there was an admin intervention that changed the change vector value. Stored value: {subscription.ChangeVectorForNextBatchStartingPoint}, received value: {LastKnownSubscriptionChangeVector}");
            }

            subscription.ChangeVectorForNextBatchStartingPoint = ChangeVector;
            subscription.NodeTag          = NodeTag;
            subscription.LastBatchAckTime = LastTimeServerMadeProgressWithDocuments;

            return(context.ReadObject(subscription.ToJson(), subscriptionName));
        }
        protected override BlittableJsonReaderObject GetUpdatedValue(long index, RawDatabaseRecord record, JsonOperationContext context, BlittableJsonReaderObject existingValue)
        {
            var itemId = GetItemId();

            if (existingValue == null)
            {
                throw new RachisApplyException($"Subscription with id '{itemId}' does not exist");
            }

            var subscription = JsonDeserializationCluster.SubscriptionState(existingValue);

            var topology            = record.Topology;
            var lastResponsibleNode = AcknowledgeSubscriptionBatchCommand.GetLastResponsibleNode(HasHighlyAvailableTasks, topology, NodeTag);

            if (topology.WhoseTaskIsIt(RachisState.Follower, subscription, lastResponsibleNode) != NodeTag)
            {
                throw new RachisApplyException($"Can't update subscription with name '{itemId}' by node {NodeTag}, because it's not it's task to update this subscription");
            }

            subscription.LastClientConnectionTime = LastClientConnectionTime;
            subscription.NodeTag = NodeTag;

            return(context.ReadObject(subscription.ToJson(), itemId));
        }
Exemple #11
0
                public static DynamicJsonValue ToJson(ServerStore serverStore, TransactionOperationContext context, RawDatabaseRecord record, long databaseIndex)
                {
                    var mapping = SnmpDatabase.GetIndexMapping(context, serverStore, record.DatabaseName);

                    var djv = new DynamicJsonValue();

                    if (mapping.Count == 0)
                    {
                        return(djv);
                    }

                    foreach (var indexName in record.Indexes.Keys)
                    {
                        if (mapping.TryGetValue(indexName, out var index) == false)
                        {
                            continue;
                        }

                        var array = new DynamicJsonArray();
                        foreach (var field in typeof(Indexes).GetFields())
                        {
                            var fieldValue  = GetFieldValue(field);
                            var databaseOid = string.Format(fieldValue.Oid, databaseIndex);
                            var indexOid    = string.Format(databaseOid, index);
                            array.Add(CreateJsonItem(Root + indexOid, fieldValue.Description));
                        }

                        djv[indexName] = array;
                    }

                    return(djv);
                }
 protected override BlittableJsonReaderObject GetUpdatedValue(long index, RawDatabaseRecord record, JsonOperationContext context,
                                                              BlittableJsonReaderObject existingValue)
 {
     return(null); // it's going to delete the value
 }
        public override unsafe void Execute(ClusterOperationContext context, Table items, long index, RawDatabaseRecord record, RachisState state, out object result)
        {
            var resultDict = new Dictionary<string, long>();
            var identitiesItems = context.Transaction.InnerTransaction.OpenTable(ClusterStateMachine.IdentitiesSchema, ClusterStateMachine.Identities);

            foreach (var kvp in Identities)
            {
                CompareExchangeCommandBase.GetKeyAndPrefixIndexSlices(context.Allocator, DatabaseName, kvp.Key, index, out var keyTuple, out var indexTuple);

                using (keyTuple.Scope)
                using (indexTuple.Scope)
                using (Slice.External(context.Allocator, keyTuple.Buffer.Ptr, keyTuple.Buffer.Length, out var keySlice))
                using (Slice.External(context.Allocator, indexTuple.Buffer.Ptr, indexTuple.Buffer.Length, out var prefixIndexSlice))
                {
                    bool isSet;
                    if (Force == false)
                    {
                        isSet = false;
                        if (identitiesItems.SeekOnePrimaryKeyPrefix(keySlice, out var tvr))
                        {
                            var value = GetValue(tvr);
                            if (value < kvp.Value)
                                isSet = true;
                        }
                        else
                        {
                            using (identitiesItems.Allocate(out var tvb))
                            {
                                tvb.Add(keySlice);
                                tvb.Add(kvp.Value);
                                tvb.Add(index);
                                tvb.Add(prefixIndexSlice);

                                identitiesItems.Set(tvb);
                            }
                        }

                    }
                    else
                        isSet = true;

                    var keyString = keySlice.ToString().ToLowerInvariant();
                    resultDict.TryGetValue(keyString, out var oldVal);
                    long newVar;

                    if (isSet)
                    {
                        UpdateTableRow(index, identitiesItems, kvp.Value, keySlice, prefixIndexSlice);
                        newVar = kvp.Value;
                    }
                    else
                    {
                        identitiesItems.SeekOnePrimaryKeyPrefix(keySlice, out var tvr);
                        newVar = GetValue(tvr);
                    }

                    resultDict[keyString] = Math.Max(oldVal, newVar);
                }
            }

            result = resultDict;
        }
 protected override BlittableJsonReaderObject GetUpdatedValue(long index, RawDatabaseRecord record, JsonOperationContext context, BlittableJsonReaderObject existingValue)
 {
     throw new NotSupportedException();
 }
Exemple #15
0
        public override unsafe void Execute(ClusterOperationContext context, Table items, long index, RawDatabaseRecord record, RachisState state, out object result)
        {
            long i            = 1;
            var  originalName = SubscriptionName;
            var  tryToSetName = true;

            result = null;
            var subscriptionId = SubscriptionId ?? index;

            SubscriptionName = string.IsNullOrEmpty(SubscriptionName) ? subscriptionId.ToString() : SubscriptionName;
            var baseName = SubscriptionName;

            if (SubscriptionName.Length > DocumentIdWorker.MaxIdSize)
            {
                throw new SubscriptionNameException($"Subscription Name is too long, must be at most {DocumentIdWorker.MaxIdSize} bytes");
            }

            while (tryToSetName)
            {
                var subscriptionItemName = SubscriptionState.GenerateSubscriptionItemKeyName(DatabaseName, SubscriptionName);
                using (Slice.From(context.Allocator, subscriptionItemName, out Slice valueName))
                    using (Slice.From(context.Allocator, subscriptionItemName.ToLowerInvariant(), out Slice valueNameLowered))
                    {
                        if (items.ReadByKey(valueNameLowered, out TableValueReader tvr))
                        {
                            var ptr = tvr.Read(2, out int size);
                            var doc = new BlittableJsonReaderObject(ptr, size, context);

                            var existingSubscriptionState = JsonDeserializationClient.SubscriptionState(doc);
                            if (SubscriptionId != existingSubscriptionState.SubscriptionId)
                            {
                                if (string.IsNullOrEmpty(originalName))
                                {
                                    SubscriptionName = $"{baseName}.{i}";
                                    i++;
                                    continue;
                                }
                                throw new RachisApplyException("A subscription could not be modified because the name '" + subscriptionItemName +
                                                               "' is already in use in a subscription with different Id.");
                            }

                            if (string.IsNullOrEmpty(InitialChangeVector) == false && InitialChangeVector == nameof(Constants.Documents.SubscriptionChangeVectorSpecialStates.DoNotChange))
                            {
                                InitialChangeVector = existingSubscriptionState.ChangeVectorForNextBatchStartingPoint;
                            }
                            else
                            {
                                AssertValidChangeVector();
                                if (InitialChangeVector != existingSubscriptionState.ChangeVectorForNextBatchStartingPoint)
                                {
                                    // modified by the admin
                                    var subscriptionStateTable = context.Transaction.InnerTransaction.OpenTable(ClusterStateMachine.SubscriptionStateSchema, ClusterStateMachine.SubscriptionState);
                                    using (SubscriptionConnectionsState.GetDatabaseAndSubscriptionPrefix(context, DatabaseName, subscriptionId, out var prefix))
                                    {
                                        using var _ = Slice.External(context.Allocator, prefix, out var prefixSlice);
                                        subscriptionStateTable.DeleteByPrimaryKeyPrefix(prefixSlice);
                                    }
                                }
                            }
                        }
                        else
                        {
                            AssertValidChangeVector();
                        }

                        using (var receivedSubscriptionState = context.ReadObject(new SubscriptionState
                        {
                            Query = Query,
                            ChangeVectorForNextBatchStartingPoint = InitialChangeVector,
                            SubscriptionId = subscriptionId,
                            SubscriptionName = SubscriptionName,
                            LastBatchAckTime = null,
                            Disabled = Disabled,
                            MentorNode = MentorNode,
                            LastClientConnectionTime = null
                        }.ToJson(), SubscriptionName))
                        {
                            ClusterStateMachine.UpdateValue(index, items, valueNameLowered, valueName, receivedSubscriptionState);
                        }

                        tryToSetName = false;
                    }
            }
        }
Exemple #16
0
        public override unsafe void Execute(ClusterOperationContext context, Table items, long index, RawDatabaseRecord record, RachisState state, out object result)
        {
            result = null;
            var itemKey = SubscriptionState.GenerateSubscriptionItemKeyName(DatabaseName, SubscriptionName);

            using (Slice.From(context.Allocator, itemKey.ToLowerInvariant(), out Slice valueNameLowered))
            {
                if (items.ReadByKey(valueNameLowered, out TableValueReader tvr) == false)
                {
                    return; // nothing to do
                }

                var ptr = tvr.Read(2, out int size);
                var doc = new BlittableJsonReaderObject(ptr, size, context);

                var subscriptionState = JsonDeserializationClient.SubscriptionState(doc);
                items.DeleteByKey(valueNameLowered);

                if (string.IsNullOrEmpty(subscriptionState.SubscriptionName) == false)
                {
                    itemKey = SubscriptionState.GenerateSubscriptionItemKeyName(DatabaseName, subscriptionState.SubscriptionName);
                    using (Slice.From(context.Allocator, itemKey.ToLowerInvariant(), out valueNameLowered))
                    {
                        items.DeleteByKey(valueNameLowered);
                    }

                    using (SubscriptionConnectionsState.GetDatabaseAndSubscriptionPrefix(context, DatabaseName, subscriptionState.SubscriptionId, out var prefix))
                    {
                        var subscriptionStateTable = context.Transaction.InnerTransaction.OpenTable(ClusterStateMachine.SubscriptionStateSchema, ClusterStateMachine.SubscriptionState);
                        using var _ = Slice.External(context.Allocator, prefix, out var prefixSlice);
                        subscriptionStateTable.DeleteByPrimaryKeyPrefix(prefixSlice);
                    }
                }
            }
        }
        public virtual unsafe void Execute(ClusterOperationContext context, Table items, long index, RawDatabaseRecord record, RachisState state, out object result)
        {
            BlittableJsonReaderObject itemBlittable = null;
            var itemKey = GetItemId();

            using (Slice.From(context.Allocator, itemKey.ToLowerInvariant(), out Slice valueNameLowered))
            {
                if (items.ReadByKey(valueNameLowered, out TableValueReader reader))
                {
                    var ptr = reader.Read(2, out int size);
                    itemBlittable = new BlittableJsonReaderObject(ptr, size, context);
                }

                itemBlittable = GetUpdatedValue(index, record, context, itemBlittable);

                // if returned null, means, there is nothing to update and we just wanted to delete the value
                if (itemBlittable == null)
                {
                    items.DeleteByKey(valueNameLowered);
                    result = GetResult();
                    return;
                }

                // here we get the item key again, in case it was changed (a new entity, etc)
                itemKey = GetItemId();
            }

            using (Slice.From(context.Allocator, itemKey, out Slice valueName))
                using (Slice.From(context.Allocator, itemKey.ToLowerInvariant(), out Slice valueNameLowered))
                {
                    ClusterStateMachine.UpdateValue(index, items, valueNameLowered, valueName, itemBlittable);
                    result = GetResult();
                }
        }
        public bool ShouldDeleteDatabase(TransactionOperationContext context, string dbName, RawDatabaseRecord rawRecord)
        {
            var deletionInProgress = DeletionInProgressStatus.No;
            var directDelete       = rawRecord.DeletionInProgress?.TryGetValue(_serverStore.NodeTag, out deletionInProgress) == true &&
                                     deletionInProgress != DeletionInProgressStatus.No;

            if (directDelete == false)
            {
                return(false);
            }

            if (rawRecord.Topology.Rehabs.Contains(_serverStore.NodeTag))
            {
                // If the deletion was issued form the cluster observer to maintain the replication factor we need to make sure
                // that all the documents were replicated from this node, therefor the deletion will be called from the replication code.
                return(false);
            }

            var record = rawRecord.MaterializedRecord;

            context.CloseTransaction();

            DeleteDatabase(dbName, deletionInProgress, record);
            return(true);
        }
        public override unsafe void Execute(ClusterOperationContext context, Table items, long index, RawDatabaseRecord record, RachisState state, out object result)
        {
            result = null;
            var itemKey = SubscriptionState.GenerateSubscriptionItemKeyName(DatabaseName, SubscriptionName);

            using (Slice.From(context.Allocator, itemKey.ToLowerInvariant(), out Slice valueNameLowered))
            {
                if (items.ReadByKey(valueNameLowered, out TableValueReader tvr) == false)
                {
                    return; // nothing to do
                }

                var ptr = tvr.Read(2, out int size);
                var doc = new BlittableJsonReaderObject(ptr, size, context);

                var subscriptionState = JsonDeserializationClient.SubscriptionState(doc);

                items.DeleteByKey(valueNameLowered);

                if (string.IsNullOrEmpty(subscriptionState.SubscriptionName) == false)
                {
                    itemKey = SubscriptionState.GenerateSubscriptionItemKeyName(DatabaseName, subscriptionState.SubscriptionName);
                    using (Slice.From(context.Allocator, itemKey.ToLowerInvariant(), out valueNameLowered))
                    {
                        items.DeleteByKey(valueNameLowered);
                    }
                }
            }
        }
Exemple #20
0
        public override unsafe void Execute(ClusterOperationContext context, Table items, long index, RawDatabaseRecord record, RachisState state, out object result)
        {
            result = null;

            var itemKey = SubscriptionState.GenerateSubscriptionItemKeyName(DatabaseName, SubscriptionName);

            using (Slice.From(context.Allocator, itemKey.ToLowerInvariant(), out Slice valueNameLowered))
                using (Slice.From(context.Allocator, itemKey, out Slice valueName))
                {
                    if (items.ReadByKey(valueNameLowered, out var tvr) == false)
                    {
                        throw new SubscriptionDoesNotExistException($"Cannot find subscription {SubscriptionName} @ {DatabaseName}");
                    }

                    var ptr = tvr.Read(2, out int size);
                    var doc = new BlittableJsonReaderObject(ptr, size, context);

                    var subscriptionState = JsonDeserializationClient.SubscriptionState(doc);
                    subscriptionState.Disabled = Disable;
                    using (var obj = context.ReadObject(subscriptionState.ToJson(), "subscription"))
                    {
                        ClusterStateMachine.UpdateValue(index, items, valueNameLowered, valueName, obj);
                    }
                }
        }
Exemple #21
0
        public override void Execute(ClusterOperationContext context, Table items, long index, RawDatabaseRecord record, RachisState state, out object result)
        {
            base.Execute(context, items, index, record, state, out result);

            if (IsLegacyCommand())
            {
                return;
            }

            ExecuteAcknowledgeSubscriptionBatch(context, index);
        }
        public override unsafe void Execute(ClusterOperationContext context, Table items, long index, RawDatabaseRecord record, RachisState state, out object result)
        {
            result = null;
            var shouldUpdateChangeVector = true;
            var subscriptionName         = SubscriptionName;

            if (string.IsNullOrEmpty(subscriptionName))
            {
                subscriptionName = SubscriptionId.ToString();
            }

            //insert all docs to voron table. If exists, then batchId will be replaced
            var subscriptionStateTable = context.Transaction.InnerTransaction.OpenTable(ClusterStateMachine.SubscriptionStateSchema, ClusterStateMachine.SubscriptionState);

            var itemKey = SubscriptionState.GenerateSubscriptionItemKeyName(DatabaseName, subscriptionName);

            using (Slice.From(context.Allocator, itemKey.ToLowerInvariant(), out Slice valueNameLowered))
                using (Slice.From(context.Allocator, itemKey, out Slice valueName))
                {
                    if (items.ReadByKey(valueNameLowered, out var tvr) == false)
                    {
                        throw new RachisApplyException($"Cannot find subscription {subscriptionName} @ {DatabaseName}");
                    }

                    var ptr           = tvr.Read(2, out int size);
                    var existingValue = new BlittableJsonReaderObject(ptr, size, context);

                    if (existingValue == null)
                    {
                        throw new SubscriptionDoesNotExistException($"Subscription with name '{subscriptionName}' does not exist in database '{DatabaseName}'");
                    }

                    var subscriptionState = JsonDeserializationClient.SubscriptionState(existingValue);

                    var topology            = record.Topology;
                    var lastResponsibleNode = AcknowledgeSubscriptionBatchCommand.GetLastResponsibleNode(HasHighlyAvailableTasks, topology, NodeTag);
                    var appropriateNode     = topology.WhoseTaskIsIt(RachisState.Follower, subscriptionState, lastResponsibleNode);
                    if (appropriateNode == null && record.DeletionInProgress.ContainsKey(NodeTag))
                    {
                        throw new DatabaseDoesNotExistException($"Stopping subscription '{subscriptionName}' on node {NodeTag}, because database '{DatabaseName}' is being deleted.");
                    }

                    if (appropriateNode != NodeTag)
                    {
                        throw new SubscriptionDoesNotBelongToNodeException(
                                  $"Cannot apply {nameof(AcknowledgeSubscriptionBatchCommand)} for subscription '{subscriptionName}' with id '{SubscriptionId}', on database '{DatabaseName}', on node '{NodeTag}'," +
                                  $" because the subscription task belongs to '{appropriateNode ?? "N/A"}'.")
                              {
                                  AppropriateNode = appropriateNode
                              };
                    }

                    if (CurrentChangeVector == nameof(Constants.Documents.SubscriptionChangeVectorSpecialStates.DoNotChange))
                    {
                        context.ReadObject(existingValue, subscriptionName);
                        shouldUpdateChangeVector = false;
                    }

                    if (subscriptionState.ChangeVectorForNextBatchStartingPoint != PreviouslyRecordedChangeVector)
                    {
                        throw new SubscriptionChangeVectorUpdateConcurrencyException($"Can't record subscription with name '{subscriptionName}' due to inconsistency in change vector progress. Probably there was an admin intervention that changed the change vector value. Stored value: {subscriptionState.ChangeVectorForNextBatchStartingPoint}, received value: {PreviouslyRecordedChangeVector}");
                    }

                    if (shouldUpdateChangeVector)
                    {
                        subscriptionState.ChangeVectorForNextBatchStartingPoint =
                            ChangeVectorUtils.MergeVectors(CurrentChangeVector, subscriptionState.ChangeVectorForNextBatchStartingPoint);
                        subscriptionState.NodeTag = NodeTag;
                        using (var obj = context.ReadObject(subscriptionState.ToJson(), "subscription"))
                        {
                            ClusterStateMachine.UpdateValue(index, items, valueNameLowered, valueName, obj);
                        }
                    }
                }

            foreach (var deletedId in Deleted)
            {
                using (SubscriptionConnectionsState.GetDatabaseAndSubscriptionAndDocumentKey(context, DatabaseName, SubscriptionId, deletedId, out var key))
                {
                    using var _ = Slice.External(context.Allocator, key, out var keySlice);
                    subscriptionStateTable.DeleteByKey(keySlice);
                }
            }

            foreach (var documentRecord in Documents)
            {
                using (SubscriptionConnectionsState.GetDatabaseAndSubscriptionAndDocumentKey(context, DatabaseName, SubscriptionId, documentRecord.DocumentId, out var key))
                    using (subscriptionStateTable.Allocate(out var tvb))
                    {
                        using var _  = Slice.External(context.Allocator, key, out var keySlice);
                        using var __ = Slice.From(context.Allocator, documentRecord.ChangeVector, out var changeVectorSlice);

                        tvb.Add(keySlice);
                        tvb.Add(changeVectorSlice);
                        tvb.Add(Bits.SwapBytes(index)); // batch id

                        subscriptionStateTable.Set(tvb);
                    }
            }
            foreach (var revisionRecord in Revisions)
            {
                using (SubscriptionConnectionsState.GetDatabaseAndSubscriptionAndRevisionKey(context, DatabaseName, SubscriptionId, revisionRecord.Current, out var key))
                    using (subscriptionStateTable.Allocate(out var tvb))
                    {
                        using var _  = Slice.External(context.Allocator, key, out var keySlice);
                        using var __ = Slice.From(context.Allocator, revisionRecord.Previous ?? string.Empty, out var changeVectorSlice);

                        tvb.Add(keySlice);
                        tvb.Add(changeVectorSlice);     //prev change vector
                        tvb.Add(Bits.SwapBytes(index)); // batch id

                        subscriptionStateTable.Set(tvb);
                    }
            }
        }
 protected override BlittableJsonReaderObject GetUpdatedValue(long index, RawDatabaseRecord record, JsonOperationContext context, BlittableJsonReaderObject existingValue)
 {
     return(context.ReadObject(PeriodicBackupStatus.ToJson(), GetItemId()));
 }
Exemple #24
0
 protected override BlittableJsonReaderObject GetUpdatedValue(long index, RawDatabaseRecord record, JsonOperationContext context, BlittableJsonReaderObject existingValue)
 {
     return(context.ReadObject(ExternalReplicationState.ToJson(), GetItemId()));
 }
        public override unsafe void Execute(ClusterOperationContext context, Table items, long index, RawDatabaseRecord record, RachisState state, out object result)
        {
            var identitiesItems = context.Transaction.InnerTransaction.OpenTable(ClusterStateMachine.IdentitiesSchema, ClusterStateMachine.Identities);
            var listResult      = new List <long>();

            foreach (var identity in Identities)
            {
                CompareExchangeCommandBase.GetKeyAndPrefixIndexSlices(context.Allocator, DatabaseName, identity, index, out var keyTuple, out var indexTuple);

                using (keyTuple.Scope)
                    using (indexTuple.Scope)
                        using (Slice.External(context.Allocator, keyTuple.Buffer.Ptr, keyTuple.Buffer.Length, out var keySlice))
                            using (Slice.External(context.Allocator, indexTuple.Buffer.Ptr, indexTuple.Buffer.Length, out var prefixIndexSlice))
                            {
                                long value;
                                if (identitiesItems.ReadByKey(keySlice, out var reader))
                                {
                                    value  = GetValue(reader);
                                    value += 1;
                                }
                                else
                                {
                                    value = 1;
                                }

                                UpdateTableRow(index, identitiesItems, value, keySlice, prefixIndexSlice);

                                listResult.Add(value);
                            }
            }

            result = listResult;
        }
Exemple #26
0
        public override unsafe void Execute(ClusterOperationContext context, Table items, long index, RawDatabaseRecord record, RachisState state, out object result)
        {
            var identitiesItems = context.Transaction.InnerTransaction.OpenTable(ClusterStateMachine.IdentitiesSchema, ClusterStateMachine.Identities);

            CompareExchangeCommandBase.GetKeyAndPrefixIndexSlices(context.Allocator, DatabaseName, Prefix, index, out var keyTuple, out var indexTuple);

            using (keyTuple.Scope)
                using (indexTuple.Scope)
                    using (Slice.External(context.Allocator, keyTuple.Buffer.Ptr, keyTuple.Buffer.Length, out var keySlice))
                        using (Slice.External(context.Allocator, indexTuple.Buffer.Ptr, indexTuple.Buffer.Length, out var prefixIndexSlice))
                        {
                            long value;
                            if (identitiesItems.SeekOnePrimaryKeyPrefix(keySlice, out var entry))
                            {
                                value = GetValue(entry);
                                value++;
                            }
                            else
                            {
                                value = 1;
                            }

                            UpdateTableRow(index, identitiesItems, value, keySlice, prefixIndexSlice);
                            result = value;
                        }
        }
 protected abstract BlittableJsonReaderObject GetUpdatedValue(long index, RawDatabaseRecord record, JsonOperationContext context,
                                                              BlittableJsonReaderObject existingValue);