Exemplo n.º 1
0
        public void FromRecord_Result()
        {
            TrackedChangeRecord record = new TrackedChangeRecord()
            {
                Id                  = Guid.NewGuid(),
                ActorName           = "actor",
                AggregateId         = Guid.NewGuid(),
                AggregateClassId    = Guid.NewGuid(),
                EntityId            = Guid.NewGuid(),
                EntityClassId       = Guid.NewGuid(),
                ChangeDataClassName = "TestChangeData",
                ChangeDataJson      = "{\"Foo\":\"bar\"}",
                ChangeTime          = DateTime.Now
            };

            TrackedChange change = sut.FromRecord(record);

            Assert.Equal(record.Id, change.Id);
            Assert.Equal(record.ActorName, change.ActorName);
            Assert.Equal(record.AggregateId, change.AggregateId);
            Assert.Equal(record.AggregateClassId, change.AggregateClassId);
            Assert.Equal(record.EntityId, change.EntityId);
            Assert.Equal(record.EntityClassId, change.EntityClassId);
            Assert.Equal(typeof(TestChangeData), change.ChangeData.GetType());
            Assert.Equal("bar", ((TestChangeData)change.ChangeData).Foo);
            Assert.Equal(record.ChangeTime, change.ChangeTime);
        }
Exemplo n.º 2
0
        public async Task AddChange_And_SaveChanges_PublishesEvents()
        {
            TestChangeData changeData = new TestChangeData();

            trackedChangeRecordConverter.ToRecord(null).ReturnsForAnyArgs(ci =>
            {
                TrackedChange x = ci.ArgAt <TrackedChange>(0);
                return(new TrackedChangeRecord()
                {
                    Id = x.Id,
                    AggregateId = x.AggregateId,
                    AggregateClassId = x.AggregateClassId,
                    EntityId = x.EntityId,
                    EntityClassId = x.EntityClassId
                });
            });

            TrackedChange tc = sut.AddChange(changeData, aggregateId, aggregateClassId,
                                             entityId, entityClassId);
            await sut.SaveChangesAsync();

            eventBus.Received(1).PublishAsync(Arg.Is <IEventMessage <TrackedChangeAdded> >(
                                                  x => x.Event.AggregateId == aggregateId &&
                                                  x.Event.EntityClassId == entityClassId &&
                                                  x.Event.EntityId == entityId &&
                                                  x.Event.TrackedChangeId == tc.Id));
        }
Exemplo n.º 3
0
        public void FindChanges_ReturnsChanges()
        {
            TrackedChangeRecord record = new TrackedChangeRecord();
            TrackedChange       change = new TrackedChange(Guid.NewGuid(), new TestChangeData(),
                                                           "", null, null, null, null, null, DateTimeOffset.Now);

            trackedChangeRecordConverter.FromRecord(record).Returns(change);
            crudRepository.Attach(record);
            List <TrackedChange> changes = sut.FindChanges().ToList();

            Assert.Equal(1, changes.Count);
            Assert.Contains(change, changes);
        }
Exemplo n.º 4
0
        public async Task CommitChangesAsync(TrackedChange trackedChange)
        {
            if (this.Config.LatestDeltaToken == trackedChange.State)
            {
                Logger.Debug("Delta token is already up to date");
                return;
            }

            Logger.Debug("OneDriveAdapter committing tracked change " + trackedChange.State);
            this.Config.LatestDeltaToken = trackedChange.State;

            await this.Relationship.SaveAsync().ConfigureAwait(false);
        }
Exemplo n.º 5
0
        public async Task GetChangeAsync_ReturnsChange()
        {
            TrackedChangeRecord record = new TrackedChangeRecord()
            {
                Id = Guid.NewGuid()
            };
            TrackedChange change = new TrackedChange(record.Id, new TestChangeData(),
                                                     "", null, null, null, null, null, DateTimeOffset.Now);

            trackedChangeRecordConverter.FromRecord(record).Returns(change);
            crudRepository.Attach(record);
            TrackedChange change2 = await sut.GetChangeAsync(change.Id);

            Assert.Equal(change, change2);
        }
Exemplo n.º 6
0
        public void AddChange_ReturnsChange()
        {
            TestChangeData changeData = new TestChangeData();

            TrackedChange change = sut.AddChange(changeData, aggregateId, aggregateClassId,
                                                 entityId, entityClassId);

            trackedChangeRecordConverter.ToRecord(null).ReturnsForAnyArgs(
                new TrackedChangeRecord());

            Assert.Equal(aggregateId, change.AggregateId);
            Assert.Equal(aggregateClassId, change.AggregateClassId);
            Assert.Equal(entityId, change.EntityId);
            Assert.Equal(entityClassId, change.EntityClassId);
            Assert.Equal(changeData, change.ChangeData);
            Assert.Equal(actorContext.CurrentActorName, change.ActorName);
            Assert.Equal(FakeClock.Now, change.ChangeTime);
        }
Exemplo n.º 7
0
        private async Task ChangeNotificationThreadMain()
        {
            while (!this.changeNotificationCancellationTokenSource.IsCancellationRequested)
            {
                TrackedChange changes = null;
                try
                {
                    changes = await this.GetChangesAsync().ConfigureAwait(false);
                }
                catch (Exception exception)
                {
                    Logger.LogException(exception, "Failed to pull changes from OneDrive");
                }

                if (changes != null &&
                    changes.Changes.Any() &&
                    !string.Equals(changes.State, this.Config.LatestDeltaToken, StringComparison.Ordinal))
                {
                    ItemsChangedEventArgs eventArgs = new ItemsChangedEventArgs();

                    foreach (IChangeTrackedAdapterItem change in changes.Changes)
                    {
                        eventArgs.Changes.Add(
                            new ItemChange(
                                change.FullName,
                                ItemChangeType.None));
                    }

                    this.ItemChanged?.Invoke(this, eventArgs);
                }

                Logger.Debug("OneDriveAdapter.ChangeNotificationThreadMain delay for " + OneDriveChangeNotificationPollingInterval);

                this.nextNotificationPollTime = DateTime.Now.Add(
                    OneDriveChangeNotificationPollingInterval);

                await Task.Delay(
                    OneDriveChangeNotificationPollingInterval,
                    this.changeNotificationCancellationTokenSource.Token)
                .ConfigureAwait(false);
            }
        }
Exemplo n.º 8
0
        public void ToRecord_Result()
        {
            TrackedChange change = new TrackedChange(Guid.NewGuid(),
                                                     new TestChangeData()
            {
                Foo = "bar"
            }, "actor", Guid.NewGuid(), Guid.NewGuid(),
                                                     Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid(), DateTimeOffset.Now);

            TrackedChangeRecord record = sut.ToRecord(change);

            Assert.Equal(change.Id, record.Id);
            Assert.Equal(change.ActorName, record.ActorName);
            Assert.Equal(change.UserId, record.UserId);
            Assert.Equal(change.AggregateId, record.AggregateId);
            Assert.Equal(change.AggregateClassId, record.AggregateClassId);
            Assert.Equal(change.EntityId, record.EntityId);
            Assert.Equal(change.EntityClassId, record.EntityClassId);
            Assert.Equal("TestChangeData", record.ChangeDataClassName);
            Assert.Equal("bar", JObject.Parse(record.ChangeDataJson)["Foo"]);
            Assert.Equal(change.ChangeTime, record.ChangeTime);
        }
Exemplo n.º 9
0
        public async Task <TrackedChange> GetChangesAsync()
        {
            if (!this.Config.TargetPath.StartsWith("OneDrive", StringComparison.OrdinalIgnoreCase))
            {
                throw new InvalidOperationException("Expected TargetPath to start with 'OneDrive/'");
            }

            // TargetPath has the form OneDrive/path/to/folder. We need the actual path /path/to/folder, so strip off the
            // first 8 characters of the path.
            string rootPath = this.Config.TargetPath.Substring(8);

            OneDriveDeltaView deltaView;

            try
            {
                deltaView = await this.oneDriveClient.GetDeltaView(rootPath, this.Config.LatestDeltaToken).ConfigureAwait(false);
            }
            catch (OneDriveHttpException httpException)
                when(httpException.ErrorResponse != null && httpException.ErrorResponse.Code == "resyncRequired")
                {
                    Logger.Warning("Change tracking for adapter {0} failed and a full resync is required.", this.Configuration.Id);

                    // If the delta token is stale (or possibly some other condition), the service may reject the delta token and
                    // require that a resync be performed using a new delta view. When this occurs, the Location header of the
                    // response will contain the new link for acquiring the new delta view.
                    KeyValuePair <string, IList <string> > locationHeader = httpException.ResponseHeaders.FirstOrDefault(
                        h => string.Equals(h.Key, "Location", StringComparison.OrdinalIgnoreCase));

                    // Verify that the location header is present
                    if (string.IsNullOrEmpty(locationHeader.Key) || !locationHeader.Value.Any())
                    {
                        throw new OneDriveHttpException("A location was not provided by the service during a delta token refresh.",
                                                        httpException);
                    }

                    // Get the new delta view
                    try
                    {
                        deltaView = await this.oneDriveClient.GetDeltaView(locationHeader.Value.First()).ConfigureAwait(false);
                    }
                    catch (Exception exception)
                    {
                        throw new OneDriveHttpException("Exception thrown during a delta token refresh.", exception);
                    }
                }

            Logger.Debug(
                "OneDriveAdapter successfully retrieved tracked change {0} with {1} changes.",
                deltaView.Token,
                deltaView.Items.Count);

            TrackedChange trackedChange = new TrackedChange(deltaView.Token);

            // Per https://dev.onedrive.com/items/view_delta.htm
            // The same item may appear more than once in a delta feed, for various reasons. You should use the last
            // occurrence you see.
            foreach (Item item in deltaView.Items)
            {
                var existingItemIndex = trackedChange.Changes.FindIndex(c => c.UniqueId == item.Id);
                if (existingItemIndex > -1)
                {
                    trackedChange.Changes[existingItemIndex] = new OneDriveAdapterItem(item, null, this);
                }
                else
                {
                    trackedChange.Changes.Add(new OneDriveAdapterItem(item, null, this));
                }
            }

            return(trackedChange);
        }