예제 #1
0
        public static async Task <ReplicationMetadata> GetPreviousReplicationMetadata(IClusterFactory clusterFactory,
                                                                                      string jobId)
        {
            try
            {
                var bucket = await clusterFactory.GetBucketAsync(Constants.ReplicationMetadataBucket);

                // check if metadata exists
                if (!await bucket.ExistsAsync(jobId))
                {
                    // no metadata
                    return(null);
                }

                // metadata exists
                var result = await bucket.GetAsync <ReplicationMetadata>(jobId);

                result.EnsureSuccess();

                return(result.Value);
            }
            catch (Exception e)
            {
                Logger.Error(e, e.Message);
                throw;
            }
        }
예제 #2
0
        public static async Task <ReplicationMetadata> UpsertReplicationMetadata(IClusterFactory clusterFactory, string jobId, ReplicationMetadata metadata)
        {
            try
            {
                var bucket = await clusterFactory.GetBucketAsync(Constants.ReplicationMetadataBucket);

                var result = await bucket.UpsertAsync(jobId, metadata);

                result.EnsureSuccess();

                return(result.Value);
            }
            catch (Exception e)
            {
                Logger.Error(e, e.Message);
                throw;
            }
        }
예제 #3
0
        /// <summary>
        /// Adds and removes records to local replication db
        /// Adds and updates available shapes
        /// </summary>
        /// <param name="clusterFactory"></param>
        /// <param name="schema"></param>
        /// <param name="record"></param>
        /// <param name="config"></param>
        /// <param name="responseStream"></param>
        /// <returns>Error message string</returns>
        public static async Task <string> WriteRecord(IClusterFactory clusterFactory, Schema schema, Record record,
                                                      ConfigureReplicationFormData config, IServerStreamWriter <RecordAck> responseStream)
        {
            // debug
            Logger.Debug($"Starting timer for {record.RecordId}");
            var timer = Stopwatch.StartNew();

            try
            {
                // debug
                Logger.Debug(JsonConvert.SerializeObject(record, Formatting.Indented));

                // semaphore
                await ReplicationSemaphoreSlim.WaitAsync();

                // setup
                var safeShapeName        = schema.Name;
                var safeGoldenBucketName =
                    string.Concat(config.GoldenBucketName.Where(c => !char.IsWhiteSpace(c)));
                var safeVersionBucketName =
                    string.Concat(config.VersionBucketName.Where(c => !char.IsWhiteSpace(c)));

                var goldenBucket = await clusterFactory.GetBucketAsync(safeGoldenBucketName);

                var versionBucket = await clusterFactory.GetBucketAsync(safeVersionBucketName);

                // transform data
                var recordVersionIds = record.Versions.Select(v => v.RecordId).ToList();
                var recordData       = GetNamedRecordData(schema, record.DataJson);
                recordData[Constants.NaveegoVersionIds] = recordVersionIds;

                // get previous golden record
                List <string> previousRecordVersionIds;
                if (await goldenBucket.ExistsAsync(record.RecordId))
                {
                    var result = await goldenBucket.GetAsync <Dictionary <string, object> >(record.RecordId);

                    if (result.Value.ContainsKey(Constants.NaveegoVersionIds))
                    {
                        previousRecordVersionIds =
                            JsonConvert.DeserializeObject <List <string> >(
                                JsonConvert.SerializeObject(result.Value[Constants.NaveegoVersionIds]));
                    }
                    else
                    {
                        previousRecordVersionIds = recordVersionIds;
                    }
                }
                else
                {
                    previousRecordVersionIds = recordVersionIds;
                }

                // write data
                if (recordData.Count == 0)
                {
                    // delete everything for this record
                    Logger.Debug($"shapeId: {safeShapeName} | recordId: {record.RecordId} - DELETE");
                    var result = await goldenBucket.RemoveAsync(record.RecordId);

                    result.EnsureSuccess();

                    foreach (var versionId in previousRecordVersionIds)
                    {
                        Logger.Debug(
                            $"shapeId: {safeShapeName} | recordId: {record.RecordId} | versionId: {versionId} - DELETE");
                        result = await versionBucket.RemoveAsync(versionId);

                        result.EnsureSuccess();
                    }
                }
                else
                {
                    // update record and remove/add versions
                    Logger.Debug($"shapeId: {safeShapeName} | recordId: {record.RecordId} - UPSERT");
                    var result = await goldenBucket.UpsertAsync(record.RecordId, recordData);

                    result.EnsureSuccess();

                    // delete missing versions
                    var missingVersions = previousRecordVersionIds.Except(recordVersionIds);
                    foreach (var versionId in missingVersions)
                    {
                        Logger.Debug(
                            $"shapeId: {safeShapeName} | recordId: {record.RecordId} | versionId: {versionId} - DELETE");
                        var versionDeleteResult = await versionBucket.RemoveAsync(versionId);

                        versionDeleteResult.EnsureSuccess();
                    }

                    // upsert other versions
                    foreach (var version in record.Versions)
                    {
                        Logger.Debug(
                            $"shapeId: {safeShapeName} | recordId: {record.RecordId} | versionId: {version.RecordId} - UPSERT");
                        var versionData         = GetNamedRecordData(schema, version.DataJson);
                        var versionUpsertResult = await versionBucket.UpsertAsync(version.RecordId, versionData);

                        versionUpsertResult.EnsureSuccess();
                    }
                }

                var ack = new RecordAck
                {
                    CorrelationId = record.CorrelationId,
                    Error         = ""
                };
                await responseStream.WriteAsync(ack);

                timer.Stop();
                Logger.Debug($"Acknowledged Record {record.RecordId} time: {timer.ElapsedMilliseconds}");

                return("");
            }
            catch (Exception e)
            {
                Logger.Error(e, $"Error replicating records {e.Message}");
                // send ack
                var ack = new RecordAck
                {
                    CorrelationId = record.CorrelationId,
                    Error         = e.Message
                };
                await responseStream.WriteAsync(ack);

                timer.Stop();
                Logger.Debug($"Failed Record {record.RecordId} time: {timer.ElapsedMilliseconds}");

                return(e.Message);
            }
            finally
            {
                ReplicationSemaphoreSlim.Release();
            }
        }