Exemple #1
0
        public async Task <IEnumerable <MeetingSessionDTO> > CreateBatchAsync(CreateMeetingSessionsBatchDto dto, LtiParamDTO param)
        {
            LmsCourseMeeting meeting   = _lmsCourseMeetingModel.GetOneById(dto.MeetingId).Value;
            DateTime         startDate = dto.StartTimestamp;

            if (dto.StartTimestamp < DateTime.UtcNow) //todo: remove these crazy conditions and parsing
            {
                throw new ArgumentException("Start time should be more then current time");
            }

            var endDate = TimeSpan.TryParse(dto.Duration, out var duration)
                ? startDate.AddMinutes((int)duration.TotalMinutes)
                : startDate.AddHours(1);

            MeetingNameInfo nameInfo = string.IsNullOrWhiteSpace(meeting.MeetingNameJson)
                ? new MeetingNameInfo()
                : JsonConvert.DeserializeObject <MeetingNameInfo>(meeting.MeetingNameJson);
            var meetingName       = nameInfo.meetingName ?? nameInfo.reusedMeetingName;
            int i                 = 1;
            var latestDateToCheck = startDate.AddDays(dto.Weeks * 7);

            var listOfEvents = new List <MeetingSessionDTO>();

            while (startDate < latestDateToCheck)
            {
                if (dto.DaysOfWeek.Contains((int)startDate.DayOfWeek))
                {
                    var ev = new MeetingSessionDTO
                    {
                        Name      = meetingName + " #" + i.ToString(),
                        Summary   = string.Empty,
                        StartDate = startDate, //.ToString("yyyy-MM-dd HH:mm"),
                        EndDate   = endDate,   //.ToString("yyyy-MM-dd HH:mm"),
                    };
                    listOfEvents.Add(ev);
                    i++;
                }

                startDate = startDate.AddDays(1);
                endDate   = endDate.AddDays(1);
            }

            if (_calendarExportService != null)
            {
                listOfEvents = (await _calendarExportService.SaveEventsAsync(meeting.Id, listOfEvents, param, _license))
                               .ToList();
            }

            meeting.MeetingSessions.AddRange(listOfEvents.Select(x => new LmsMeetingSession
            {
                LmsCalendarEventId = x.EventId,
                Name             = x.Name,
                StartDate        = x.StartDate,
                EndDate          = x.EndDate,
                LmsCourseMeeting = meeting
            }));

            await CreateCalendarEvents(param, meeting);

            _lmsCourseMeetingModel.RegisterSave(meeting, true);
            return(meeting.MeetingSessions.Select(ConvertFromEntity).ToArray());
        }
Exemple #2
0
        public async Task SynchronizeUsers(ILmsLicense lmsCompany, bool syncACUsers, IEnumerable <int> meetingIds = null)
        {
            LmsUserServiceBase service = null;

            if ((LmsProviderEnum)lmsCompany.LmsProviderId == LmsProviderEnum.Brightspace)
            {
                service = IoC.Resolve <LmsUserServiceBase>(LmsProviderEnum.Brightspace.ToString() + "_Sync");
            }
            else
            {
                service = lmsFactory.GetUserService((LmsProviderEnum)lmsCompany.LmsProviderId);
            }

            var acProvider = acAccountService.GetProvider(lmsCompany);
            var meetings   = lmsCompany.LmsCourseMeetings.Where(x =>
                                                                meetingIds == null || meetingIds.Any(m => m == x.Id)).ToList();
            var scoIds          = new HashSet <string>(meetings.Select(x => x.GetMeetingScoId())).ToList();
            var scos            = acProvider.ReportBulkObjects(scoIds).Values;
            var settings        = lmsCompany.Settings.ToList(); //to avoid nhibernate errors
            var groupedMeetings = meetings
                                  .Where(x => scos.Any(s => s.ScoId == x.ScoId))
                                  .GroupBy(y => y.CourseId);
            List <LmsUser> users = lmsCompany.LmsUsers.ToList();//meetingIds == null ? lmsCompany.LmsUsers.ToList() : null;

            object localLockObject = new object();
            Dictionary <string, IEnumerable <LmsUserDTO> > licenseUsers = new Dictionary <string, IEnumerable <LmsUserDTO> >();
//            var input = meetings.Select(x => new Tuple<LmsCourseMeeting, string>(x, x.GetMeetingScoId())).ToList();
            var timer = Stopwatch.StartNew();

//synchronous version
            //var parallelMode = ConfigurationManager.AppSettings["ParallelMode"];
            //if (parallelMode == null || parallelMode != "1")
            //{
            foreach (var groupedMeeting in groupedMeetings)
            {
                var courseId = groupedMeeting.Key;
                var opResult = await service.GetUsers(lmsCompany.GetLMSSettings(_settings), courseId);

                if (opResult.IsSuccess)
                {
                    licenseUsers.Add(courseId, opResult.Data);
                }
                else
                {
                    licenseUsers.Add(courseId, new List <LmsUserDTO>());
                }
            }
            //}
//parallel version
            //else
            //{
            //    Parallel.ForEach<int, Dictionary<int, IEnumerable<LmsUserDTO>>>(
            //        groupedMeetings.Select(x => x.Key),
            //        () => new Dictionary<int, IEnumerable<LmsUserDTO>>(),
            //        (courseId, state, localDictionary) =>
            //        {
            //            var opResult = service.GetUsers(lmsCompany, courseId);
            //            if (opResult.IsSuccess)
            //            {
            //                localDictionary.Add(courseId, opResult.Data);
            //            }
            //            else
            //            {
            //                localDictionary.Add(courseId, new List<LmsUserDTO>());
            //            }

            //            return localDictionary;
            //        },
            //        (finalResult) =>
            //        {
            //            lock (localLockObject)
            //                foreach (var item in finalResult)
            //                {
            //                    licenseUsers.Add(item.Key, item.Value);
            //                }
            //        }
            //    );
            //}
            timer.Stop();
            logger.Warn($"Users from API elapsed seconds:{timer.Elapsed.ToString()}");
            acProvider = acAccountService.GetProvider(lmsCompany); //users retrieve can take more than session timeout

            foreach (var courseGroup in groupedMeetings)
            {
                logger.InfoFormat("Retrieving users for LmsCompanyId={0}, LmsProvider={1}, CourseId={2}; MeetingIds:{3}",
                                  lmsCompany.Id, (LmsProviderEnum)lmsCompany.LmsProviderId, courseGroup.Key, String.Join(",", courseGroup.Select(x => x.Id)));
                try
                {
                    //todo: set extra data param
//                    var opResult = service.GetUsers(lmsCompany, lmsCompany.AdminUser, courseGroup.Key);
//                    if (opResult.IsSuccess)
//                    {
                    var usersCount = licenseUsers[courseGroup.Key].Count();
                    if (usersCount == 0)
                    {
                        //todo: take all users (meeting.Users) and make foreach trying to retrieve
                        logger.WarnFormat("Couldn't retrieve users from API for LmsCompanyId={0}, LmsProvider={1}, CourseId={2}",
                                          lmsCompany.Id, (LmsProviderEnum)lmsCompany.LmsProviderId, courseGroup.Key);
                    }
                    else if (usersCount > Core.Utils.Constants.SyncUsersCountLimit)
                    {
                        logger.WarnFormat("Course contains {0} users that is more than limit for users sync ({1}). LmsCompanyId={2}, LmsProvider={3}, CourseId={4}",
                                          usersCount, Core.Utils.Constants.SyncUsersCountLimit, lmsCompany.Id, (LmsProviderEnum)lmsCompany.LmsProviderId, courseGroup.Key);
                        foreach (var meeting in courseGroup)
                        {
                            if (!meeting.EnableDynamicProvisioning)
                            {
                                meeting.EnableDynamicProvisioning = true;
                                lmsCourseMeetingModel.RegisterSave(meeting, true);
                            }
                        }
                    }
                    else
                    {
                        var licenseUsersVar = licenseUsers[courseGroup.Key].ToList();

                        // var userIds = licenseUsersVar.Select(x => x.LtiId ?? x.Id);
//                        logger.InfoFormat("API user ids: {0}", String.Join(",", userIds));
                        var existedDbUsers = users.Where(x => licenseUsersVar.Any(u => (u.LtiId ?? u.Id) == x.UserId));
                        //?? lmsUserModel.GetByUserIdAndCompanyLms(userIds.ToArray(), lmsCompany.Id);
                        var existedUserIds = existedDbUsers.Select(x => x.Id).ToList();

                        var newUsers = UpdateDbUsers(licenseUsers[courseGroup.Key].ToList(), lmsCompany, users, acProvider);
                        users.AddRange(newUsers);
                        // merge results;
                        foreach (var meeting in courseGroup)
                        {
                            if (lmsCompany.GetSetting <bool>(LmsLicenseSettingNames.UseCourseSections))
                            {
                                licenseUsersVar =
                                    licenseUsers[courseGroup.Key].Where(
                                        x => x.SectionIds == null || x.SectionIds.Any(s => meeting.CourseSections.Any(cs => cs.LmsId == s))).ToList();
                                existedDbUsers =
                                    users.Where(x => licenseUsersVar.Any(u => (u.LtiId ?? u.Id) == x.UserId));
                                existedUserIds = existedDbUsers.Select(x => x.Id).ToList();
                                newUsers       = new List <LmsUser>();
                            }

                            //sync DB roles
                            foreach (var dbRole in meeting.MeetingRoles)
                            {
                                var lmsUser =
                                    licenseUsersVar.FirstOrDefault(x => (x.LtiId ?? x.Id) == dbRole.User.UserId);
                                if (lmsUser != null)
                                {
                                    dbRole.LmsRole = lmsUser.LmsRole;
                                }
                            }

                            var userRolesToDelete =
                                meeting.MeetingRoles.Where(x => existedUserIds.All(u => u != x.User.Id)).ToList();

                            var usersToAddToMeeting = new List <LmsUser>(newUsers);
                            usersToAddToMeeting.AddRange(
                                existedDbUsers.Where(
                                    x => meeting.MeetingRoles.Select(mr => mr.User).All(u => u.Id != x.Id)).ToList());

                            if (userRolesToDelete.Any())
                            {
                                logger.InfoFormat(
                                    "LmsUser ids to delete from meetingId={0}, courseId={1}: {2}",
                                    meeting.Id, meeting.CourseId,
                                    String.Join(", ", userRolesToDelete.Select(x => x.User.Id)));
                            }
                            if (usersToAddToMeeting.Any())
                            {
                                logger.InfoFormat(
                                    "LmsUser ids to add to meetingId={0}, courseId={1}: {2}",
                                    meeting.Id, meeting.CourseId,
                                    String.Join(", ", usersToAddToMeeting.Select(x => x.UserId)));
                            }

                            userRolesToDelete.ForEach(x => meeting.MeetingRoles.Remove(x));
                            usersToAddToMeeting.ForEach(x => meeting.MeetingRoles.Add(new LmsUserMeetingRole
                            {
                                Meeting = meeting,
                                User    = x,
                                LmsRole =
                                    licenseUsers[courseGroup.Key].First(dto => x.UserId == (dto.LtiId ?? dto.Id))
                                    .LmsRole
                            }));
                            meeting.EnableDynamicProvisioning = false;
                            lmsCourseMeetingModel.RegisterSave(meeting, true);
                            // todo: optimize condition, probably refresh roles not for all users
                            var dbPrincipalIds = new HashSet <string>(
                                meeting.MeetingRoles.Where(x => x.User.PrincipalId != null).Select(x => x.User.PrincipalId));
                            List <MeetingPermissionInfo> enrollments = usersSetup.GetMeetingAttendees(acProvider, meeting.GetMeetingScoId());
                            var acPrincipalIds = new HashSet <string>(enrollments.Select(e => e.PrincipalId));

                            if (syncACUsers &&
                                (meeting.LmsMeetingType == (int)LmsMeetingType.Meeting || meeting.LmsMeetingType == (int)LmsMeetingType.VirtualClassroom || meeting.LmsMeetingType == (int)LmsMeetingType.Seminar)
                                &&
                                (dbPrincipalIds.Count != meeting.MeetingRoles.Count ||
                                 dbPrincipalIds.Count != acPrincipalIds.Count ||
                                 dbPrincipalIds.Any(x => acPrincipalIds.All(p => p != x))))
                            {
                                logger.InfoFormat("Synchronizing AC for meetingId={0}, courseId={1}", meeting.Id, meeting.CourseId);
                                UpdateACRoles(lmsCompany, meeting, acProvider, enrollments);
                            }
                        }
                    }
//                    }
                }

                catch (Exception e)
                {
                    var message = String.Format(
                        $"Error happened when tried to update users for LmsCompany with id={lmsCompany.Id}, lmsCourseId={courseGroup.Key}");
                    logger.Error(message, e);
                }
            }
        }