예제 #1
0
        public void CreateConference(ConferenceInfo conference)
        {
            using (var context = new ConferenceContext()) {
                var existingSlug =
                    context.Conferences
                    .Where(c => c.Slug == conference.Slug)
                    .Select(c => c.Slug)
                    .Any();

                if (existingSlug)
                {
                    throw new DuplicateNameException("The chosen conference slug is already taken.");
                }

                // Conference publishing is explicit.
                if (conference.IsPublished)
                {
                    conference.IsPublished = false;
                }

                context.Conferences.Add(conference);
                context.SaveChanges();

                PublishConferenceEvent <ConferenceCreated>(conference);
            }
        }
예제 #2
0
 public SeatType FindSeatType(Guid seatTypeId)
 {
     using (var context = new ConferenceContext(this.nameOrConnectionString))
     {
         return(this.retryPolicy.ExecuteAction(() => context.Seats.Find(seatTypeId)));
     }
 }
예제 #3
0
        public void UpdateSeat(Guid conferenceId, SeatType seat)
        {
            using (var context = new ConferenceContext()) {
                var existing = context.Seats.Find(seat.Id);
                if (existing == null)
                {
                    throw new ObjectNotFoundException();
                }

                context.Entry(existing).CurrentValues.SetValues(seat);
                context.SaveChanges();

                // Don't publish seat updates if the conference was never published
                // (and therefore is not published either).
                if (context.Conferences.Where(x => x.Id == conferenceId).Select(x => x.WasEverPublished).FirstOrDefault())
                {
                    eventBus.Publish(new SeatUpdated {
                        ConferenceId = conferenceId,
                        SourceId     = seat.Id,
                        Name         = seat.Name,
                        Description  = seat.Description,
                        Price        = seat.Price,
                        Quantity     = seat.Quantity
                    });
                }
            }
        }
        public void UpdateSeat(Guid conferenceId, SeatType seat)
        {
            using (ConferenceContext context = new ConferenceContext(this._nameOrConnectionString)) {
                SeatType existing = context.Seats.Find(seat.Id);

                if (existing == null)
                {
                    throw new ObjectNotFoundException();
                }

                context.Entry(existing).CurrentValues.SetValues(seat);

                context.SaveChanges();

                if (context.Conferences.Where(x => x.Id == conferenceId).Select(x => x.WasEverPublished).FirstOrDefault())
                {
                    this._eventBus.Publish(new SeatUpdated()
                    {
                        ConferenceId = conferenceId,
                        SourceId     = seat.Id,
                        Name         = seat.Name,
                        Description  = seat.Description,
                        Price        = seat.Price,
                        Quantity     = seat.Quantity
                    });
                }
            }
        }
예제 #5
0
 public ConferenceInfo FindConference(string email, string accessCode)
 {
     using (var context = new ConferenceContext(this.nameOrConnectionString))
     {
         return(this.retryPolicy.ExecuteAction(() => context.Conferences.FirstOrDefault(x => x.OwnerEmail == email && x.AccessCode == accessCode)));
     }
 }
예제 #6
0
 public ConferenceInfo FindConference(string slug)
 {
     using (var context = new ConferenceContext(this.nameOrConnectionString))
     {
         return(this.retryPolicy.ExecuteAction(() => context.Conferences.FirstOrDefault(x => x.Slug == slug)));
     }
 }
예제 #7
0
 public IEnumerable <Order> FindOrders(Guid conferenceId)
 {
     using (var context = new ConferenceContext()) {
         return(context.Orders.Include("Seats.SeatInfo")
                .Where(x => x.ConferenceId == conferenceId)
                .ToList());
     }
 }
 public IEnumerable <SeatType> FindSeatTypes(Guid conferenceId)
 {
     using (ConferenceContext context = new ConferenceContext(this._nameOrConnectionString)) {
         return(context.Conferences.Include(x => x.Seats)
                .Where(x => x.Id == conferenceId)
                .Select(x => x.Seats)
                .FirstOrDefault() ?? Enumerable.Empty <SeatType>());
     }
 }
예제 #9
0
 public IEnumerable <Order> FindOrders(Guid conferenceId)
 {
     using (var context = new ConferenceContext(this.nameOrConnectionString))
     {
         return(this.retryPolicy.ExecuteAction(() => context.Orders.Include("Seats.SeatInfo")
                                               .Where(x => x.ConferenceId == conferenceId)
                                               .ToList()));
     }
 }
예제 #10
0
        static void Main(string[] args)
        {
            var connectionString = ConfigurationManager.AppSettings["defaultConnection"];
            if (args.Length > 0)
            {
                connectionString = args[0];
            }

            // Use ConferenceContext as entry point for dropping and recreating DB
            using (var context = new ConferenceContext(connectionString))
            {
                if (context.Database.Exists())
                    context.Database.Delete();

                context.Database.Create();
            }

            Database.SetInitializer<EventStoreDbContext>(null);
            Database.SetInitializer<MessageLogDbContext>(null);
            Database.SetInitializer<BlobStorageDbContext>(null);
            Database.SetInitializer<ConferenceRegistrationDbContext>(null);
            Database.SetInitializer<RegistrationProcessDbContext>(null);
            Database.SetInitializer<PaymentsDbContext>(null);

            DbContext[] contexts =
                new DbContext[] 
                { 
                    new EventStoreDbContext(connectionString),
                    new MessageLogDbContext(connectionString),
                    new BlobStorageDbContext(connectionString),
                    new PaymentsDbContext(connectionString),
                    new RegistrationProcessDbContext(connectionString),
                    new ConferenceRegistrationDbContext(connectionString),
                };

            foreach (DbContext context in contexts)
            {
                var adapter = (IObjectContextAdapter)context;

                var script = adapter.ObjectContext.CreateDatabaseScript();

                context.Database.ExecuteSqlCommand(script);

                context.Dispose();
            }

            using (var context = new PaymentsDbContext(connectionString))
            {
                PaymentsReadDbContextInitializer.CreateViews(context);
            }

            MessagingDbInitializer.CreateDatabaseObjects(connectionString, "SqlBus");
        }
예제 #11
0
 public IEnumerable <SeatType> FindSeatTypes(Guid conferenceId)
 {
     using (var context = new ConferenceContext(this.nameOrConnectionString))
     {
         return(this.retryPolicy.ExecuteAction(() =>
                                               context.Conferences
                                               .Include(x => x.Seats)
                                               .Where(x => x.Id == conferenceId)
                                               .Select(x => x.Seats)
                                               .FirstOrDefault()) ??
                Enumerable.Empty <SeatType>());
     }
 }
예제 #12
0
        public void UpdateConference(ConferenceInfo conference)
        {
            using (var context = new ConferenceContext()) {
                var existing = context.Conferences.Find(conference.Id);
                if (existing == null)
                {
                    throw new ObjectNotFoundException();
                }

                context.Entry(existing).CurrentValues.SetValues(conference);
                context.SaveChanges();

                PublishConferenceEvent <ConferenceUpdated>(conference);
            }
        }
예제 #13
0
        public void UpdateConference(ConferenceInfo conference)
        {
            using (var context = new ConferenceContext(this.nameOrConnectionString))
            {
                var existing = this.retryPolicy.ExecuteAction(() => context.Conferences.Find(conference.Id));
                if (existing == null)
                {
                    throw new ObjectNotFoundException();
                }

                context.Entry(existing).CurrentValues.SetValues(conference);
                this.retryPolicy.ExecuteAction(() => context.SaveChanges());

                this.PublishConferenceEvent <ConferenceUpdated>(conference);
            }
        }
예제 #14
0
        private void UpdatePublished(Guid conferenceId, bool isPublished)
        {
            using (var context = new ConferenceContext(this.nameOrConnectionString))
            {
                var conference = this.retryPolicy.ExecuteAction(() => context.Conferences.Find(conferenceId));
                if (conference == null)
                {
                    throw new ObjectNotFoundException();
                }

                conference.IsPublished = isPublished;
                if (isPublished && !conference.WasEverPublished)
                {
                    // This flags prevents any further seat type deletions.
                    conference.WasEverPublished = true;
                    this.retryPolicy.ExecuteAction(() => context.SaveChanges());

                    // We always publish events *after* saving to store.
                    // Publish all seats that were created before.
                    foreach (var seat in conference.Seats)
                    {
                        PublishSeatCreated(conference.Id, seat);
                    }
                }
                else
                {
                    this.retryPolicy.ExecuteAction(() => context.SaveChanges());
                }

                if (isPublished)
                {
                    this.eventBus.Publish(new ConferencePublished {
                        SourceId = conferenceId
                    });
                }
                else
                {
                    this.eventBus.Publish(new ConferenceUnpublished {
                        SourceId = conferenceId
                    });
                }
            }
        }
        /// <summary>
        /// 创建座位
        /// </summary>
        /// <param name="conferenceId"></param>
        /// <param name="seat"></param>
        public void CreateSeat(Guid conferenceId, SeatType seat)
        {
            using (ConferenceContext context = new ConferenceContext(this._nameOrConnectionString)) {
                var conference = context.Conferences.Find(conferenceId);

                if (conference == null)
                {
                    throw new ObjectNotFoundException();
                }

                conference.Seats.Add(seat);

                context.SaveChanges();

                if (conference.WasEverPublished)
                {
                    this.PublishSeatCreated(conferenceId, seat);
                }
            }
        }
예제 #16
0
        public void CreateSeat(Guid conferenceId, SeatType seat)
        {
            using (var context = new ConferenceContext()) {
                var conference = context.Conferences.Find(conferenceId);
                if (conference == null)
                {
                    throw new ObjectNotFoundException();
                }

                conference.Seats.Add(seat);
                context.SaveChanges();

                // Don't publish new seats if the conference was never published
                // (and therefore is not published either).
                if (conference.WasEverPublished)
                {
                    PublishSeatCreated(conferenceId, seat);
                }
            }
        }
        private void UpdatePublished(Guid conferenceId, bool isPublished)
        {
            using (ConferenceContext context = new ConferenceContext(this._nameOrConnectionString)) {
                ConferenceInfo conference = context.Conferences.Find(conferenceId);
                if (conference == null)
                {
                    throw new ObjectNotFoundException();
                }

                conference.IsPublished = isPublished;
                if (isPublished && !conference.WasEverPublished)
                {
                    conference.WasEverPublished = true;
                    context.SaveChanges();

                    foreach (SeatType seat in conference.Seats)
                    {
                        this.PublishSeatCreated(conference.Id, seat);
                    }
                }
                else
                {
                    context.SaveChanges();
                }

                if (isPublished)
                {
                    this._eventBus.Publish(new ConferencePublished()
                    {
                        SourceId = conferenceId
                    });
                }
                else
                {
                    this._eventBus.Publish(new ConferenceUnpublished()
                    {
                        SourceId = conferenceId
                    });
                }
            }
        }
예제 #18
0
        public void CreateSeat(Guid conferenceId, SeatType seat)
        {
            using (var context = new ConferenceContext(this.nameOrConnectionString))
            {
                var conference = this.retryPolicy.ExecuteAction(() => context.Conferences.Find(conferenceId));
                if (conference == null)
                {
                    throw new ObjectNotFoundException();
                }

                conference.Seats.Add(seat);
                this.retryPolicy.ExecuteAction(() => context.SaveChanges());

                // Don't publish new seats if the conference was never published
                // (and therefore is not published either).
                if (conference.WasEverPublished)
                {
                    this.PublishSeatCreated(conferenceId, seat);
                }
            }
        }
예제 #19
0
        public void DeleteSeat(Guid id)
        {
            using (var context = new ConferenceContext()) {
                var seat = context.Seats.Find(id);
                if (seat == null)
                {
                    throw new ObjectNotFoundException();
                }

                var wasPublished = context.Conferences
                                   .Where(x => x.Seats.Any(s => s.Id == id))
                                   .Select(x => x.WasEverPublished)
                                   .FirstOrDefault();

                if (wasPublished)
                {
                    throw new InvalidOperationException("Can't delete seats from a conference that has been published at least once.");
                }

                context.Seats.Remove(seat);
                context.SaveChanges();
            }
        }
        /// <summary>
        /// 创建会议
        /// </summary>
        /// <param name="conference"></param>
        public void CreateConference(ConferenceInfo conference)
        {
            using (ConferenceContext context = new ConferenceContext(this._nameOrConnectionString)) {
                bool existingSlug = context.Conferences.Where(c => c.Slug == conference.Slug)
                                    .Select(c => c.Slug).Any();

                if (existingSlug)
                {
                    throw new DuplicateNameException("The chosen conference slug is already taken.");
                }

                if (conference.IsPublished)
                {
                    conference.IsPublished = false;
                }

                context.Conferences.Add(conference);

                context.SaveChanges();

                this.PublishConferenceEvent <ConferenceCreated>(conference);
            }
        }
예제 #21
0
        public ConferenceService(IBus bus, ConferenceContext conferenceContext)
        {
            // NOTE: the database storage cannot be transactional consistent with the
            // event bus, so there is a chance that the conference state is saved
            // to the database but the events are not published. The recommended
            // mechanism to solve this lack of transaction support is to persist
            // failed events to a table in the same database as the conference, in a
            // queue that is retried until successful delivery of events is
            // guaranteed. This mechanism has been implemented for the AzureEventSourcedRepository
            // and that implementation can be used as a guide to implement it here too.

            context  = conferenceContext;
            this.bus = bus;

            var delay = Backoff.ConstantBackoff(TimeSpan.FromMilliseconds(200), retryCount: 5, fastFirst: true);

            this.retryPolicy = Policy
                               .Handle <Exception>()
                               .WaitAndRetryAsync(delay, (exception, i, span) =>
            {
                Trace.TraceWarning(
                    $"An error occurred in attempt number {i} to access the database in ConferenceService: {exception.Message}");
            });
        }
 public ConferenceInfo FindConference(string slug)
 {
     using (ConferenceContext context = new ConferenceContext(this._nameOrConnectionString)) {
         return(context.Conferences.FirstOrDefault(x => x.Slug == slug));
     }
 }
 public SeatType FindSeatType(Guid seatTypeId)
 {
     using (ConferenceContext context = new ConferenceContext(this._nameOrConnectionString)) {
         return(context.Seats.Find(seatTypeId));
     }
 }
예제 #24
0
 public SeatType FindSeatType(Guid seatTypeId)
 {
     using (var context = new ConferenceContext()) {
         return(context.Seats.Find(seatTypeId));
     }
 }
예제 #25
0
        public static async Task SeedAsync(this ConferenceContext context, UserManager <User> userStore, CancellationToken cancellationToken = default)
        {
            if (await context.Events.AnyAsync(cancellationToken))
            {
                return;
            }

            // TODO: Use HasGeneratedTsVectorProperty instead of the following when Npgsql 5.0 is released.
            // See https://github.com/npgsql/efcore.pg/issues/1253 for more details.

            await context.Database.ExecuteSqlRawAsync(
                @"CREATE TRIGGER submission_search_vector_update BEFORE INSERT OR UPDATE
                  ON submission FOR EACH ROW EXECUTE PROCEDURE
                  tsvector_update_trigger(search_vector, 'pg_catalog.english', title, description);", cancellationToken);

            await context.Database.ExecuteSqlRawAsync(
                @"CREATE TRIGGER submission_search_vector_update BEFORE INSERT OR UPDATE
                  ON speaker_profile FOR EACH ROW EXECUTE PROCEDURE
                  tsvector_update_trigger(search_vector, 'pg_catalog.english', tag_line, bio);", cancellationToken);

            await context.Database.ExecuteSqlRawAsync(
                @"CREATE TRIGGER submission_search_vector_update BEFORE INSERT OR UPDATE
                  ON ""user"" FOR EACH ROW EXECUTE PROCEDURE
                  tsvector_update_trigger(search_vector, 'pg_catalog.english', email, user_name, given_name, family_name);", cancellationToken);

            var user = new User
            {
                Id         = new Guid("7042C1B5-1295-4A0F-B835-B1B0210FE6E6"),
                UserName   = "******",
                GivenName  = "Kristian",
                FamilyName = "Hellang",
                Email      = "*****@*****.**",
            };

            var result = await userStore.CreateAsync(user);

            if (!result.Succeeded)
            {
                throw new Exception($"Failed to create user:\n{string.Join('\n', result.Errors.Select(x => x.Description))}");
            }

            var ndc = new Event
            {
                Id            = new Guid("f225d953-bf14-449f-8de5-df48500b4ff9"),
                Name          = "NDC Oslo 2020",
                StartTime     = new LocalDateTime(2020, 06, 10, 09, 00),
                EndTime       = new LocalDateTime(2020, 06, 12, 17, 00),
                CfpOpenTime   = new LocalDateTime(2019, 11, 14, 12, 00),
                CfpCloseTime  = new LocalDateTime(2020, 02, 16, 00, 00),
                TimeZoneId    = TzdbDateTimeZoneSource.Default.GetSystemDefaultId(),
                TimeZoneRules = DateTimeZoneProviders.Tzdb.VersionId,
                Venues        =
                {
                    new Venue
                    {
                        Name     = "Oslo Spektrum",
                        Location = "Sonja Henies plass 2, 0185 Oslo",
                        Rooms    =
                        {
                            new Room {
                                Name = "Room 1", Capacity = 250
                            },
                            new Room {
                                Name = "Room 2", Capacity = 250
                            },
                            new Room {
                                Name = "Room 3", Capacity = 250
                            },
                            new Room {
                                Name = "Room 4", Capacity = 250
                            },
                            new Room {
                                Name = "Room 5", Capacity = 450
                            },
                            new Room {
                                Name = "Room 6", Capacity = 400
                            },
                            new Room {
                                Name = "Room 7", Capacity = 450
                            },
                            new Room {
                                Name = "Room 8", Capacity = 300
                            },
                            new Room {
                                Name = "Room 9", Capacity = 150
                            },
                        }
                    },
                },
                SessionFormats =
                {
                    Keynote,
                    Regular,
                    new SessionFormat {
                        Name = "Lightning Talk",Length                      = Period.FromMinutes(10)
                    },
                    new SessionFormat {
                        Name = "Workshop",Length                      = Period.FromMinutes(120)
                    },
                },
                Members =
                {
                    new EventMember {
                        Email = user.Email, Role = EventMemberRole.Admin, User = user
                    },
                },
            };

            var speakerProfile = new SpeakerProfile
            {
                User    = user,
                TagLine = "The most awesome speaker, ever!",
                Bio     = "This is the bio. Ideally it should be longer, but I can't think of something to write.",
            };

            ndc.SpeakerProfiles.Add(speakerProfile);

            ndc.Submissions.Add(new Submission
            {
                Owner       = user,
                Title       = "This is my first talk, hope you like it.",
                Description = "This is the talk description. Short and simple.",
                Formats     = { new SubmissionFormat {
                                    Format = Regular
                                } },
                Speakers = { new Speaker {
                                 Email = user.Email, Profile = speakerProfile
                             } }
            });

            GenerateAgenda(ndc);

            await context.AddAsync(ndc, cancellationToken);

            await context.SaveChangesAsync(cancellationToken);
        }
예제 #26
0
 public ConferenceInfo FindConference(string slug)
 {
     using (var context = new ConferenceContext()) {
         return(context.Conferences.FirstOrDefault(x => x.Slug == slug));
     }
 }
예제 #27
0
 public ConferenceInfo FindConference(string email, string accessCode)
 {
     using (var context = new ConferenceContext()) {
         return(context.Conferences.FirstOrDefault(x => x.OwnerEmail == email && x.AccessCode == accessCode));
     }
 }
 public ConferenceInfo FindConference(string email, string accessCode)
 {
     using (ConferenceContext context = new ConferenceContext(this._nameOrConnectionString)) {
         return(context.Conferences.FirstOrDefault(x => x.OwnerEmail == email && x.AccessCode == accessCode));
     }
 }
예제 #29
0
 protected EventEntityRepository(ConferenceContext context) : base(context)
 {
 }
 public IEnumerable <Order> FindOrders(Guid conferenceId)
 {
     using (ConferenceContext context = new ConferenceContext(this._nameOrConnectionString)) {
         return(context.Orders.Include("Seats.SeatInfo").Where(x => x.ConferenceId == conferenceId).ToList());
     }
 }
예제 #31
0
 protected CrudRepository(ConferenceContext context) : base(context)
 {
 }
        // Very similar to ConferenceService.cs
        private IEnumerable<IEvent> GenerateMissedConferenceManagementIntegrationEvents(string nameOrConnectionString)
        {
            // Note: instead of returning a list, could yield results if data set is very big. Seems unnecessary.
            var events = new List<IEvent>();
            using (var context = new ConferenceContext(nameOrConnectionString))
            {
                foreach (var conference in context.Conferences.Include(x => x.Seats))
                {
                    // Use automapper? I'd prefer this to be explicit just in case we don't make mistakes with versions.
                    events.Add(new ConferenceCreated
                    {
                        SourceId = conference.Id,
                        Owner = new Owner
                        {
                            Name = conference.OwnerName,
                            Email = conference.OwnerEmail,
                        },
                        Name = conference.Name,
                        Description = conference.Description,
                        Location = conference.Location,
                        Slug = conference.Slug,
                        Tagline = conference.Tagline,
                        TwitterSearch = conference.TwitterSearch,
                        StartDate = conference.StartDate,
                        EndDate = conference.EndDate,
                    });

                    foreach (var seat in conference.Seats)
                    {
                        events.Add(new SeatCreated
                        {
                            ConferenceId = conference.Id,
                            SourceId = seat.Id,
                            Name = seat.Name,
                            Description = seat.Description,
                            Price = seat.Price,
                            Quantity = seat.Quantity
                        });
                    }

                    if (conference.WasEverPublished)
                    {
                        events.Add(new ConferencePublished { SourceId = conference.Id });
                        if (!conference.IsPublished)
                        {
                            events.Add(new ConferenceUnpublished { SourceId = conference.Id });
                        }
                    }
                }
            }

            return events;
        }