public override void Handle(UserCreated e) { // is this a usf user? var usf = _queryProcessor.Execute(new EstablishmentByUrl("www.usf.edu")); var tenant = _queryProcessor.Execute(new EstablishmentById(e.TenantId)); if (tenant == null || usf == null || !usf.Equals(tenant)) { return; } var reportBuilder = new WorkReportBuilder("Handle USF User Created Event"); var logging = UsfFacultyProfileAttribute.MailLog.ToString(); try { // get the service integration var usfFacultyProfile = UsfFacultyProfileAttribute.UsfFacultyProfile.ToString(); var integration = _entities.Get <ServiceIntegration>() .EagerLoad(_entities, new Expression <Func <ServiceIntegration, object> >[] { x => x.StringAttributes, }) .SingleOrDefault(x => x.TenantId == e.TenantId && x.Name.Equals(usfFacultyProfile)); if (integration == null) { throw new InvalidOperationException(string.Format( "Found no service integration for '{0}_{1}'.", usfFacultyProfile, e.TenantId)); } reportBuilder.Report("Wrapping integration data into USF Faculty Profile Service object."); var service = new UsfFacultyProfileService(integration); logging = service.Logging; reportBuilder.Report("Invoking command to import USF person data."); _commandHandler.Handle(new ImportUsfPerson(e.Principal, service, e.UserId) { ReportBuilder = reportBuilder, }); } catch (Exception ex) { reportBuilder.Report(""); reportBuilder.Report("JOB FAILED!"); reportBuilder.Report(ex.GetType().Name); reportBuilder.Report(ex.Message); reportBuilder.Report(ex.StackTrace); _exceptionLogger.Log(ex); } finally { _entities.DiscardChanges(); var usfFacultyProfile = UsfFacultyProfileAttribute.UsfFacultyProfile.ToString(); var integration = _entities.Get <ServiceIntegration>() .EagerLoad(_entities, new Expression <Func <ServiceIntegration, object> >[] { x => x.StringAttributes, }) .SingleOrDefault(x => x.TenantId == e.TenantId && x.Name.Equals(usfFacultyProfile)); if (integration == null) { reportBuilder.Report("Found no service integration for '{0}_{1}'.", usfFacultyProfile, e.TenantId); reportBuilder.Send(_mailSender); } else { if (!string.IsNullOrWhiteSpace(logging)) { integration.LogEntries.Add(new ServiceLogEntry { IntegrationName = integration.Name, TenantId = integration.TenantId, Subject = reportBuilder.Subject, Log = reportBuilder.Message.ToString(), }); _entities.SaveChanges(); } if (logging == UsfFacultyProfileAttribute.MailLog.ToString()) { reportBuilder.Send(_mailSender); } } } }
public void Handle(ImportUsfEstablishments command) { if (command == null) { throw new ArgumentNullException("command"); } var reportBuilder = command.ReportBuilder ?? new WorkReportBuilder("Import USF Departments"); var service = command.Service; try { #region Skip import if not necessary // do we need to re-import? reportBuilder.Report("Determining whether USF department import should be skipped."); var isSkippable = !string.IsNullOrWhiteSpace(service.LastUpdate) // data has already been sync'd at least once // and the last sync date equals the command's requesting sync date && (string.IsNullOrWhiteSpace(command.LastUpdate) || service.LastUpdate.Equals(command.LastUpdate)) // and the status does not indicate a failure or in-progress state && service.Status == UsfFacultyProfileAttribute.Ready.ToString(); if (isSkippable) { reportBuilder.Report("USF department import will be skipped."); return; // note this will also happen when command.SyncDate == null } #endregion #region Wait on import already in progress // is there already an import in progress? // if so, wait on it to change reportBuilder.Report("Determining whether or not USF department import is in progress."); _entities.Reload(command.Service.Integration); // freshen status from db if (service.Status == UsfFacultyProfileAttribute.InProgress.ToString()) { // wait for the process to complete reportBuilder.Report("USF Department import is in progress, wait for completion."); WaitOnProgress(command, reportBuilder); // if was in progress, and is now ready, do not import again if (command.Service.Status == UsfFacultyProfileAttribute.Ready.ToString()) { reportBuilder.Report("USF Department import is ready, parallel import succeeded."); return; } } #endregion #region Update status, invoke USF service, and load comparison data // begin progress reportBuilder.Report("Setting status to '{0}'.", UsfFacultyProfileAttribute.InProgress.ToString()); command.Service.Status = UsfFacultyProfileAttribute.InProgress.ToString(); _entities.Update(command.Service.Integration); _entities.SaveChanges(); reportBuilder.Report("Status set to '{0}'.", UsfFacultyProfileAttribute.InProgress.ToString()); // invoke departments service reportBuilder.Report("Invoking USF department service."); var departmentsData = _queryProcessor.Execute(new UsfDepartments(command.Service) { ReportBuilder = reportBuilder }); if (departmentsData == null || departmentsData.Departments == null) { throw new InvalidOperationException(string.Format( "Could not obtain departments data for '{0}_{1}'service integration.", command.Service.Integration.Name, command.Service.Integration.TenantId)); } reportBuilder.Report("Deserialized USF department response to CLR object."); reportBuilder.Report("JSON value of deserialized response is:"); reportBuilder.Report(JsonConvert.SerializeObject(departmentsData)); // establishment types will be used later when creating establishments reportBuilder.Report("Loading establishment type entities."); var establishmentTypeName = KnownEstablishmentType.UniversityCampus.AsSentenceFragment(); var campusType = _entities.Query <EstablishmentType>().Single(t => t.EnglishName == establishmentTypeName); establishmentTypeName = KnownEstablishmentType.College.AsSentenceFragment(); var collegeType = _entities.Query <EstablishmentType>().Single(t => t.EnglishName == establishmentTypeName); establishmentTypeName = KnownEstablishmentType.Department.AsSentenceFragment(); var departmentType = _entities.Query <EstablishmentType>().Single(t => t.EnglishName == establishmentTypeName); // order the service results by campus, college, deptid departmentsData.Departments = departmentsData.Departments .OrderBy(x => x.CampusName).ThenBy(x => x.CollegeName).ThenBy(x => x.DepartmentId).ToArray(); // all units will be children of USF reportBuilder.Report("Loading USF establishment entity."); var usf = _entities.Get <Establishment>() .EagerLoad(_entities, new Expression <Func <Establishment, object> >[] { x => x.Children, x => x.Offspring.Select(y => y.Offspring), }) .Single(x => x.RevisionId == command.Service.Integration.TenantId); reportBuilder.Report("USF establishment entity loaded with id '{0}'.", usf.RevisionId); var isChanged = false; #endregion #region Populate campuses // populate the campuses first (they are ranked) var campusRanks = new Dictionary <string, int> { { "Tampa", 1 }, { "Petersburg", 2 }, { "Sarasota", 3 }, }; var campusNames = departmentsData.Departments.Select(x => x.CampusName).Distinct().ToArray(); //campusNames = campusNames.Union(new[] { "Unidentified Campus" }).ToArray(); if (campusNames.Any(x => !campusRanks.Keys.Any(x.Contains))) { throw new InvalidOperationException(string.Format( "USF Service returned unexpected campus '{0}'.", campusNames.First(x => !campusRanks.Keys.Any(x.Contains)))); } reportBuilder.Report("Iterating over {0} campus names.", campusNames.Length); foreach (var campusName in campusNames) { // note that the service returns USF Sarasota, but we want official name to be USF Sarasota-Manatee var campusByName = usf.Children.SingleOrDefault(x => x.Names.Any(y => y.Text.Equals(campusName))); if (campusByName == null) { var createCampusCommand = new CreateEstablishment(command.Principal) { NoCommit = true, NoHierarchy = true, Parent = usf, TypeId = campusType.RevisionId, Rank = campusRanks.Single(x => campusName.Contains(x.Key)).Value, OfficialName = new CreateEstablishmentName(command.Principal) { NoCommit = true, IsOfficialName = true, Text = !campusName.Contains("Sarasota") ? campusName : "USF Sarasota-Manatee", }, }; _createEstablishment.Handle(createCampusCommand); if (campusName.Contains("Sarasota")) { var createCampusNameCommand = new CreateEstablishmentName(command.Principal) { NoCommit = true, Owner = createCampusCommand.Created, Text = campusName, }; _createEstablishmentName.Handle(createCampusNameCommand); } isChanged = true; } } #endregion #region Populate Colleges // get all unique combinations of campus / college var campusColleges = departmentsData.Departments .Select(x => new { x.CampusName, x.CollegeName, }).Distinct() .OrderBy(x => x.CampusName).ThenBy(x => x.CollegeName) .ToArray(); reportBuilder.Report("Iterating over {0} campus colleges.", campusColleges.Length); foreach (var campusCollege in campusColleges) { var collegeInCampus = campusCollege; // does the college already exist? var campus = usf.Children .Single(x => x.Names.Any(y => y.Text.Equals(collegeInCampus.CampusName))); var officialName = string.Format("{0}, {1}", collegeInCampus.CollegeName, campus.OfficialName); var collegeByName = campus.Children .SingleOrDefault(x => x.OfficialName.Equals(officialName) || x.Names.Any(y => y.Text.Equals(collegeInCampus.CollegeName) && y.IsContextName)); if (collegeByName != null) { continue; } var createCollegeCommand = new CreateEstablishment(command.Principal) { NoCommit = true, NoHierarchy = true, Parent = campus, TypeId = collegeType.RevisionId, OfficialName = new CreateEstablishmentName(command.Principal) { NoCommit = true, IsOfficialName = true, Text = officialName, }, }; _createEstablishment.Handle(createCollegeCommand); var createCollegeNameCommand = new CreateEstablishmentName(command.Principal) { NoCommit = true, IsContextName = true, Owner = createCollegeCommand.Created, Text = collegeInCampus.CollegeName, }; _createEstablishmentName.Handle(createCollegeNameCommand); isChanged = true; // does this college have any department id's? var customIds = departmentsData.Departments .Where(x => x.CollegeName == collegeInCampus.CollegeName && x.CampusName == collegeInCampus.CampusName && string.IsNullOrWhiteSpace(x.DepartmentName) ) .Select(x => x.DepartmentId).Distinct() // it is possible that this custom DEPTID is named elsewhere .Where(x => !departmentsData.Departments .Any(y => y.DepartmentId == x && !string.IsNullOrWhiteSpace(y.DepartmentName))) .ToArray(); //var doubleCheckCustomIds = departmentsData.Departments // .Where(x => customIds.Contains(x.DepartmentId)).ToArray(); foreach (var customId in customIds) { createCollegeCommand.Created.CustomIds.Add(new EstablishmentCustomId { Owner = createCollegeCommand.Created, Value = customId, }); } } #endregion #region Populate Departments // we are going to skip all unnamed departments var namedDepartments = departmentsData.Departments .Where(x => !string.IsNullOrWhiteSpace(x.DepartmentName)) .ToArray(); reportBuilder.Report("Iterating over {0} named departments.", namedDepartments.Length); foreach (var departmentData in namedDepartments) { var campus = usf.Children .Single(x => x.Names.Any(y => y.Text.Equals(departmentData.CampusName))); var college = campus.Children .Single(x => x.Names.Any(y => y.Text.Equals(departmentData.CollegeName))); var officialName = string.Format("{0}, {1}, {2}", departmentData.DepartmentName, departmentData.CollegeName, campus.OfficialName); // is the name of the department the same as the name of the college? if (departmentData.DepartmentName == departmentData.CollegeName) { if (college.CustomIds.All(x => x.Value != departmentData.DepartmentId)) { college.CustomIds.Add(new EstablishmentCustomId { Owner = college, Value = departmentData.DepartmentId, }); isChanged = true; } continue; } // does the department already exist? var departmentByName = college.Children .SingleOrDefault(x => x.OfficialName.Equals(officialName) || x.Names.Any(y => y.Text.Equals(departmentData.DepartmentName))); var departmentById = college.Children .SingleOrDefault(x => x.CustomIds.Select(y => y.Value).Contains(departmentData.DepartmentId)); if (departmentByName == null) { if (departmentById == null) { var createDepartmentCommand = new CreateEstablishment(command.Principal) { NoCommit = true, NoHierarchy = true, Parent = college, TypeId = departmentType.RevisionId, OfficialName = new CreateEstablishmentName(command.Principal) { NoCommit = true, IsOfficialName = true, Text = officialName, }, }; _createEstablishment.Handle(createDepartmentCommand); var createDepartmentNameCommand = new CreateEstablishmentName(command.Principal) { NoCommit = true, IsContextName = true, Owner = createDepartmentCommand.Created, Text = departmentData.DepartmentName, }; _createEstablishmentName.Handle(createDepartmentNameCommand); departmentByName = createDepartmentCommand.Created; } else { var formerContextNames = departmentById.Names.Where(x => x.IsContextName).ToArray(); foreach (var formerContextName in formerContextNames) { formerContextName.IsFormerName = true; } var newContextName = formerContextNames.SingleOrDefault(x => x.Text == departmentData.DepartmentName); if (newContextName != null) { newContextName.IsFormerName = false; } else { departmentById.Names.Add(new EstablishmentName { ForEstablishment = departmentById, IsContextName = true, Text = departmentData.DepartmentName, }); } departmentById.Names.Single(x => x.IsOfficialName).Text = officialName; departmentById.OfficialName = officialName; departmentByName = departmentById; } isChanged = true; } if (departmentById == null) { departmentByName.CustomIds.Add(new EstablishmentCustomId { Owner = departmentByName, Value = departmentData.DepartmentId, }); isChanged = true; } } #endregion #region Populate Unnamed Department Id's var unnamedDepartments = departmentsData.Departments .Where(x => string.IsNullOrWhiteSpace(x.DepartmentName)) .ToArray(); foreach (var departmentData in unnamedDepartments) { var campus = usf.Children .Single(x => x.Names.Any(y => y.Text.Equals(departmentData.CampusName))); var college = campus.Children .Single(x => x.Names.Any(y => y.Text.Equals(departmentData.CollegeName))); if (college.CustomIds.All(x => x.Value != departmentData.DepartmentId)) { college.CustomIds.Add(new EstablishmentCustomId { EstablishmentId = college.RevisionId, Owner = college, Value = departmentData.DepartmentId, }); isChanged = true; } } #endregion if (isChanged) { // TODO: only update hierarchy when establishments are added or removed reportBuilder.Report("USF Department import has pending database changes."); _updateHierarchy.Handle(new UpdateEstablishmentHierarchy(usf)); _entities.SaveChanges(); reportBuilder.Report("USF Department import pending database changes have been committed."); } reportBuilder.Report("USF Department import is complete."); reportBuilder.Report("Setting status to '{0}'.", UsfFacultyProfileAttribute.Ready.ToString()); command.Service.Status = UsfFacultyProfileAttribute.Ready.ToString(); reportBuilder.Report("Setting last update to '{0}'.", command.LastUpdate); command.Service.LastUpdate = command.LastUpdate; _entities.Update(command.Service.Integration); _entities.SaveChanges(); reportBuilder.Report("Status set to '{0}'.", UsfFacultyProfileAttribute.Ready.ToString()); } catch { reportBuilder.Report("USF Department import encountered an exception."); _entities.DiscardChanges(); reportBuilder.Report("Setting status to '{0}'.", UsfFacultyProfileAttribute.FailedState.ToString()); command.Service.Status = UsfFacultyProfileAttribute.FailedState.ToString(); _entities.Update(command.Service.Integration); _entities.SaveChanges(); reportBuilder.Report("Status set to '{0}'.", UsfFacultyProfileAttribute.FailedState.ToString()); reportBuilder.Report("Rethrowing exception."); throw; } }