Пример #1
0
        private static IEnumerable <ValidityPeriod> GetPreviousContiguousValidPeriods(List <ValidityPeriod> allPeriods,
                                                                                      ValidityPeriod period)
        {
            while (period != null)
            {
                yield return(period);

                ValidityPeriod previousPeriod =
                    allPeriods.SingleOrDefault(p => p.Status == "Valid" && p.To.Equals(period.From) && p.Sequence != period.Sequence);

                period = previousPeriod;
            }
        }
        public ValidityPeriod GetOrAddPeriod(int sequence)
        {
            var period = Periods.FirstOrDefault(p => p.Sequence == sequence);

            if (period == null)
            {
                period = new ValidityPeriod
                {
                    Sequence = sequence
                };

                Periods.Add(period);
            }

            return(period);
        }
Пример #3
0
        private void BuildDocumentProjector()
        {
            var documentMapBuilder = new EventMapBuilder <DocumentCountProjection, string, RavenProjectionContext>();

            documentMapBuilder
            .Map <WarrantAssignedEvent>()
            .AsCreateOf(anEvent => anEvent.Number)
            .Using((document, anEvent) =>
            {
                document.Type    = "Warrant";
                document.Kind    = anEvent.Kind;
                document.Country = anEvent.Country;
                document.State   = anEvent.InitialState;
            });

            documentMapBuilder
            .Map <CertificateIssuedEvent>()
            .AsCreateOf(anEvent => anEvent.Number)
            .Using((document, anEvent) =>
            {
                document.Type    = "Certificate";
                document.Kind    = anEvent.Kind;
                document.Country = anEvent.Country;
                document.State   = anEvent.InitialState;
            });

            documentMapBuilder
            .Map <ConstitutionEstablishedEvent>()
            .AsUpdateOf(anEvent => anEvent.Number)
            .Using((document, anEvent) =>
            {
                document.Type    = "Constitution";
                document.Kind    = anEvent.Kind;
                document.Country = anEvent.Country;
                document.State   = anEvent.InitialState;
            });

            documentMapBuilder
            .Map <LicenseGrantedEvent>()
            .AsCreateOf(anEvent => anEvent.Number)
            .Using((document, anEvent) =>
            {
                document.Type    = "Audit";
                document.Kind    = anEvent.Kind;
                document.Country = anEvent.Country;
                document.State   = anEvent.InitialState;
            });

            documentMapBuilder
            .Map <ContractNegotiatedEvent>()
            .AsCreateOf(anEvent => anEvent.Number)
            .Using((document, anEvent) =>
            {
                document.Type    = "Task";
                document.Kind    = anEvent.Kind;
                document.Country = anEvent.Country;
                document.State   = anEvent.InitialState;
            });

            documentMapBuilder
            .Map <BondIssuedEvent>()
            .AsCreateOf(anEvent => anEvent.Number)
            .Using((document, anEvent) =>
            {
                document.Type    = "IsolationCertificate";
                document.Kind    = anEvent.Kind;
                document.Country = anEvent.Country;
                document.State   = anEvent.InitialState;
            });

            documentMapBuilder
            .Map <AreaRestrictedEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) => document.RestrictedArea = anEvent.Area);

            documentMapBuilder
            .Map <AreaRestrictionCancelledEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) => document.RestrictedArea = null);

            documentMapBuilder
            .Map <StateTransitionedEvent>()
            .When(anEvent => anEvent.State != "Closed")
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) => document.State = anEvent.State);

            documentMapBuilder
            .Map <StateRevertedEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) => document.State = anEvent.State);

            documentMapBuilder
            .Map <DocumentArchivedEvent>()
            .AsDeleteOf(anEvent => anEvent.DocumentNumber);

            documentMapBuilder
            .Map <CountryCorrectedEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) => document.Country = anEvent.Country);

            documentMapBuilder
            .Map <NextReviewScheduledEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) => document.NextReviewAt = anEvent.NextReviewAt);

            documentMapBuilder
            .Map <LifetimeRestrictedEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) => document.LifetimePeriodEnd = anEvent.PeriodEnd);

            documentMapBuilder
            .Map <LifetimeRestrictionRemovedEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) => document.LifetimePeriodEnd = null);

            documentMapBuilder
            .Map <ValidityPeriodPlannedEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) =>
            {
                ValidityPeriod period = document.GetOrAddPeriod(anEvent.Sequence);
                period.From           = anEvent.From;
                period.To             = anEvent.To;
            });

            documentMapBuilder
            .Map <ValidityPeriodResetEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) =>
            {
                ValidityPeriod period = document.GetOrAddPeriod(anEvent.Sequence);
                period.From           = null;
                period.To             = null;
            });

            documentMapBuilder
            .Map <ValidityPeriodApprovedEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) =>
            {
                ValidityPeriod period = document.GetOrAddPeriod(anEvent.Sequence);
                period.Status         = "Valid";

                ValidityPeriod lastValidPeriod = document.Periods.LastOrDefault(aPeriod => aPeriod.Status == "Valid");

                ValidityPeriod[] contiguousPeriods = GetPreviousContiguousValidPeriods(document.Periods, lastValidPeriod)
                                                     .OrderBy(x => x.Sequence).ToArray();

                document.StartDateTime = contiguousPeriods.Any() ? contiguousPeriods.First().From : DateTime.MinValue;
                document.EndDateTime   = contiguousPeriods.Any() ? contiguousPeriods.Last().To : DateTime.MaxValue;
            });

            documentMapBuilder
            .Map <ValidityPeriodClosedEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) =>
            {
                ValidityPeriod period = document.GetOrAddPeriod(anEvent.Sequence);
                period.Status         = "Closed";
                period.To             = anEvent.ClosedAt;
            });

            documentMapBuilder
            .Map <ValidityPeriodCanceledEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) =>
            {
                ValidityPeriod period = document.GetOrAddPeriod(anEvent.Sequence);
                period.Status         = "Canceled";
            });

            documentProjector = new RavenProjector <DocumentCountProjection>(
                sessionFactory,
                documentMapBuilder,
                (projection, identity) => projection.Id = identity,
                new[] { countryProjector })
            {
                BatchSize = 20,
                Cache     = cache
            };
        }
        private void BuildDocumentProjector()
        {
            var documentMapBuilder = new EventMapBuilder <DocumentCountProjection, string, NHibernateProjectionContext>();

            documentMapBuilder
            .Map <WarrantAssignedEvent>()
            .AsCreateOf(anEvent => anEvent.Number)
            .Using((document, anEvent) =>
            {
                document.Type    = "Warrant";
                document.Kind    = anEvent.Kind;
                document.Country = anEvent.Country;
                document.State   = anEvent.InitialState;
            });

            documentMapBuilder
            .Map <CertificateIssuedEvent>()
            .AsCreateOf(anEvent => anEvent.Number)
            .Using((document, anEvent) =>
            {
                document.Type    = "Certificate";
                document.Kind    = anEvent.Kind;
                document.Country = anEvent.Country;
                document.State   = anEvent.InitialState;
            });

            documentMapBuilder
            .Map <ConstitutionEstablishedEvent>()
            .AsUpdateOf(anEvent => anEvent.Number)
            .Using((document, anEvent) =>
            {
                document.Type    = "Constitution";
                document.Kind    = anEvent.Kind;
                document.Country = anEvent.Country;
                document.State   = anEvent.InitialState;
            });

            documentMapBuilder
            .Map <LicenseGrantedEvent>()
            .AsCreateOf(anEvent => anEvent.Number)
            .Using((document, anEvent) =>
            {
                document.Type    = "Audit";
                document.Kind    = anEvent.Kind;
                document.Country = anEvent.Country;
                document.State   = anEvent.InitialState;
            });

            documentMapBuilder
            .Map <ContractNegotiatedEvent>()
            .AsCreateOf(anEvent => anEvent.Number)
            .Using((document, anEvent) =>
            {
                document.Type    = "Task";
                document.Kind    = anEvent.Kind;
                document.Country = anEvent.Country;
                document.State   = anEvent.InitialState;
            });

            documentMapBuilder
            .Map <BondIssuedEvent>()
            .AsCreateOf(anEvent => anEvent.Number)
            .Using((document, anEvent) =>
            {
                document.Type    = "IsolationCertificate";
                document.Kind    = anEvent.Kind;
                document.Country = anEvent.Country;
                document.State   = anEvent.InitialState;
            });

            documentMapBuilder
            .Map <AreaRestrictedEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) => document.RestrictedArea = anEvent.Area);

            documentMapBuilder
            .Map <AreaRestrictionCancelledEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) => document.RestrictedArea = null);

            documentMapBuilder
            .Map <StateTransitionedEvent>()
            .When(anEvent => anEvent.State != "Closed")
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) => document.State = anEvent.State);

            documentMapBuilder
            .Map <StateRevertedEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) => document.State = anEvent.State);

            documentMapBuilder
            .Map <DocumentArchivedEvent>()
            .AsDeleteOf(anEvent => anEvent.DocumentNumber);

            documentMapBuilder
            .Map <CountryCorrectedEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) => document.Country = anEvent.Country);

            documentMapBuilder
            .Map <NextReviewScheduledEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) => document.NextReviewAt = anEvent.NextReviewAt);

            documentMapBuilder
            .Map <LifetimeRestrictedEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) =>
            {
                // For this particular document, we're throwing an exception to simulate the effect of the exception policy
                // set-up in the OnException method.
                if (document.Id == "0000000047")
                {
                    throw new InvalidOperationException("Simulating an exception");
                }

                document.LifetimePeriodEnd = anEvent.PeriodEnd;
            });

            documentMapBuilder
            .Map <LifetimeRestrictionRemovedEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) => document.LifetimePeriodEnd = null);

            documentMapBuilder
            .Map <ValidityPeriodPlannedEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) =>
            {
                ValidityPeriod period = document.GetOrAddPeriod(anEvent.Sequence);
                period.From           = anEvent.From;
                period.To             = anEvent.To;
            });

            documentMapBuilder
            .Map <ValidityPeriodResetEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) =>
            {
                ValidityPeriod period = document.GetOrAddPeriod(anEvent.Sequence);
                period.From           = null;
                period.To             = null;
            });

            documentMapBuilder
            .Map <ValidityPeriodApprovedEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) =>
            {
                ValidityPeriod period = document.GetOrAddPeriod(anEvent.Sequence);
                period.Status         = "Valid";

                ValidityPeriod lastValidPeriod = document.Periods.LastOrDefault(aPeriod => aPeriod.Status == "Valid");

                ValidityPeriod[] contiguousPeriods = GetPreviousContiguousValidPeriods(document.Periods, lastValidPeriod)
                                                     .OrderBy(x => x.Sequence).ToArray();

                document.StartDateTime = contiguousPeriods.Any() ? contiguousPeriods.First().From : DateTime.MinValue;
                document.EndDateTime   = contiguousPeriods.Any() ? contiguousPeriods.Last().To : DateTime.MaxValue;
            });

            documentMapBuilder
            .Map <ValidityPeriodClosedEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) =>
            {
                ValidityPeriod period = document.GetOrAddPeriod(anEvent.Sequence);
                period.Status         = "Closed";
                period.To             = anEvent.ClosedAt;
            });

            documentMapBuilder
            .Map <ValidityPeriodCanceledEvent>()
            .AsUpdateOf(anEvent => anEvent.DocumentNumber)
            .Using((document, anEvent) =>
            {
                ValidityPeriod period = document.GetOrAddPeriod(anEvent.Sequence);
                period.Status         = "Canceled";
            });

            documentProjector = new NHibernateProjector <DocumentCountProjection, string, ProjectorState>(
                sessionFactory,
                documentMapBuilder,
                (projection, identity) => projection.Id = identity,
                new[] { countryProjector })
            {
                BatchSize        = 20,
                Cache            = cache,
                ExceptionHandler = OnException,

                // Make sure that we no longer process corrupted projections.
                Filter = p => !p.Corrupt
            };
        }