Пример #1
0
        private async Task <(IEnumerable <OrganizationSponsorshipData> data, IEnumerable <OrganizationSponsorship> toOffer)> DoSyncAsync(Organization sponsoringOrg, IEnumerable <OrganizationSponsorshipData> sponsorshipsData)
        {
            var existingSponsorshipsDict = (await _organizationSponsorshipRepository.GetManyBySponsoringOrganizationAsync(sponsoringOrg.Id))
                                           .ToDictionary(i => i.SponsoringOrganizationUserId);

            var sponsorshipsToUpsert   = new List <OrganizationSponsorship>();
            var sponsorshipIdsToDelete = new List <Guid>();
            var sponsorshipsToReturn   = new List <OrganizationSponsorshipData>();

            foreach (var selfHostedSponsorship in sponsorshipsData)
            {
                var requiredSponsoringProductType = StaticStore.GetSponsoredPlan(selfHostedSponsorship.PlanSponsorshipType)?.SponsoringProductType;
                if (requiredSponsoringProductType == null ||
                    StaticStore.GetPlan(sponsoringOrg.PlanType).Product != requiredSponsoringProductType.Value)
                {
                    continue; // prevent unsupported sponsorships
                }

                if (!existingSponsorshipsDict.TryGetValue(selfHostedSponsorship.SponsoringOrganizationUserId, out var cloudSponsorship))
                {
                    if (selfHostedSponsorship.ToDelete && selfHostedSponsorship.LastSyncDate == null)
                    {
                        continue; // prevent invalid sponsorships in cloud. These should have been deleted by self hosted
                    }
                    if (OrgDisabledForMoreThanGracePeriod(sponsoringOrg))
                    {
                        continue; // prevent new sponsorships from disabled orgs
                    }
                    cloudSponsorship = new OrganizationSponsorship
                    {
                        SponsoringOrganizationId     = sponsoringOrg.Id,
                        SponsoringOrganizationUserId = selfHostedSponsorship.SponsoringOrganizationUserId,
                        FriendlyName        = selfHostedSponsorship.FriendlyName,
                        OfferedToEmail      = selfHostedSponsorship.OfferedToEmail,
                        PlanSponsorshipType = selfHostedSponsorship.PlanSponsorshipType,
                        LastSyncDate        = DateTime.UtcNow,
                    };
                }
                else
                {
                    cloudSponsorship.LastSyncDate = DateTime.UtcNow;
                }

                if (selfHostedSponsorship.ToDelete)
                {
                    if (cloudSponsorship.SponsoredOrganizationId == null)
                    {
                        sponsorshipIdsToDelete.Add(cloudSponsorship.Id);
                        selfHostedSponsorship.CloudSponsorshipRemoved = true;
                    }
                    else
                    {
                        cloudSponsorship.ToDelete = true;
                    }
                }
                sponsorshipsToUpsert.Add(cloudSponsorship);

                selfHostedSponsorship.ValidUntil   = cloudSponsorship.ValidUntil;
                selfHostedSponsorship.LastSyncDate = DateTime.UtcNow;
                sponsorshipsToReturn.Add(selfHostedSponsorship);
            }
            var sponsorshipsToEmailOffer = sponsorshipsToUpsert.Where(s => s.Id == default).ToArray();

            if (sponsorshipsToUpsert.Any())
            {
                await _organizationSponsorshipRepository.UpsertManyAsync(sponsorshipsToUpsert);
            }
            if (sponsorshipIdsToDelete.Any())
            {
                await _organizationSponsorshipRepository.DeleteManyAsync(sponsorshipIdsToDelete);
            }

            return(sponsorshipsToReturn, sponsorshipsToEmailOffer);
        }
Пример #2
0
        public async Task SyncOrganization(Guid organizationId, Guid cloudOrganizationId, OrganizationConnection billingSyncConnection)
        {
            if (!_globalSettings.EnableCloudCommunication)
            {
                throw new BadRequestException("Failed to sync instance with cloud - Cloud communication is disabled in global settings");
            }
            if (!billingSyncConnection.Enabled)
            {
                throw new BadRequestException($"Billing Sync Key disabled for organization {organizationId}");
            }
            if (string.IsNullOrWhiteSpace(billingSyncConnection.Config))
            {
                throw new BadRequestException($"No Billing Sync Key known for organization {organizationId}");
            }
            var billingSyncConfig = billingSyncConnection.GetConfig <BillingSyncConfig>();

            if (billingSyncConfig == null || string.IsNullOrWhiteSpace(billingSyncConfig.BillingSyncKey))
            {
                throw new BadRequestException($"Failed to get Billing Sync Key for organization {organizationId}");
            }

            var organizationSponsorshipsDict = (await _organizationSponsorshipRepository.GetManyBySponsoringOrganizationAsync(organizationId))
                                               .ToDictionary(i => i.SponsoringOrganizationUserId);

            if (!organizationSponsorshipsDict.Any())
            {
                _logger.LogInformation($"No existing sponsorships to sync for organization {organizationId}");
                return;
            }
            var syncedSponsorships = new List <OrganizationSponsorshipData>();

            foreach (var orgSponsorshipsBatch in CoreHelpers.Batch(organizationSponsorshipsDict.Values, 1000))
            {
                var response = await SendAsync <OrganizationSponsorshipSyncRequestModel, OrganizationSponsorshipSyncResponseModel>(HttpMethod.Post, "organization/sponsorship/sync", new OrganizationSponsorshipSyncRequestModel
                {
                    BillingSyncKey = billingSyncConfig.BillingSyncKey,
                    SponsoringOrganizationCloudId = cloudOrganizationId,
                    SponsorshipsBatch             = orgSponsorshipsBatch.Select(s => new OrganizationSponsorshipRequestModel(s))
                });

                if (response == null)
                {
                    _logger.LogDebug("Organization sync failed for '{OrgId}'", organizationId);
                    throw new BadRequestException("Organization sync failed");
                }

                syncedSponsorships.AddRange(response.ToOrganizationSponsorshipSync().SponsorshipsBatch);
            }

            var sponsorshipsToDelete = syncedSponsorships.Where(s => s.CloudSponsorshipRemoved).Select(i => organizationSponsorshipsDict[i.SponsoringOrganizationUserId].Id);
            var sponsorshipsToUpsert = syncedSponsorships.Where(s => !s.CloudSponsorshipRemoved).Select(i =>
            {
                var existingSponsorship = organizationSponsorshipsDict[i.SponsoringOrganizationUserId];
                if (existingSponsorship != null)
                {
                    existingSponsorship.LastSyncDate = i.LastSyncDate;
                    existingSponsorship.ValidUntil   = i.ValidUntil;
                    existingSponsorship.ToDelete     = i.ToDelete;
                }
                else
                {
                    // shouldn't occur, added in case self hosted loses a sponsorship
                    existingSponsorship = new OrganizationSponsorship
                    {
                        SponsoringOrganizationId     = organizationId,
                        SponsoringOrganizationUserId = i.SponsoringOrganizationUserId,
                        FriendlyName        = i.FriendlyName,
                        OfferedToEmail      = i.OfferedToEmail,
                        PlanSponsorshipType = i.PlanSponsorshipType,
                        LastSyncDate        = i.LastSyncDate,
                        ValidUntil          = i.ValidUntil,
                        ToDelete            = i.ToDelete
                    };
                }
                return(existingSponsorship);
            });

            if (sponsorshipsToDelete.Any())
            {
                await _organizationSponsorshipRepository.DeleteManyAsync(sponsorshipsToDelete);
            }
            if (sponsorshipsToUpsert.Any())
            {
                await _organizationSponsorshipRepository.UpsertManyAsync(sponsorshipsToUpsert);
            }
        }