/// <summary> /// Executes the specified reader. /// </summary> /// <param name="reader">The reader instance.</param> /// <param name="action">The logic to execute.</param> /// <param name="logger">The logger.</param> /// <exception cref="System.ArgumentNullException">If the reader instance is null</exception> public void Execute(TextReader reader, Action<Collection<string>, LogHelper> action, LogHelper logger) { if (reader == null) { throw new ArgumentNullException("reader"); } int lineNum = -1; try { string line = null; while ((line = reader.ReadLine()) != null) { lineNum++; if (lineNum == 0) { string[] separator = new string[] { this.DelimiterAsString }; string[] commaSeperator = new string[] { "," }; int length = line.Split(separator, StringSplitOptions.None).Length; if (line.Split(commaSeperator, StringSplitOptions.None).Length > length) { this.DelimiterAsString = commaSeperator[0]; } } else if ((lineNum <= 1) || !string.IsNullOrEmpty(line.Trim())) { try { Collection<string> entries = this.ParseLineIntoEntries(line); action.Invoke(entries, logger); } catch (Exception ex) { logger.LogException(string.Empty, ex); } } } } catch (Exception ex) { logger.LogException(string.Empty, ex); } }
/// <summary> /// Instances the specified loggers. /// </summary> /// <param name="loggers">The loggers.</param> /// <returns>An instance of the log helper</returns> public static LogHelper Instance(LoggerCollection loggers, bool logVerbose = false) { if (instance == null) { lock (syncRoot) { if (instance == null) { verbose = logVerbose; loggerInstances = loggers; instance = new LogHelper(); foreach (var logger in loggers) { logger.Initialise(); } } } } return instance; }
/// <summary> /// Iterates the row from the CSV file /// </summary> /// <param name="context">The ClientContext instance.</param> /// <param name="entries">The collection values per row.</param> /// <param name="logger">The logger.</param> public override void IterateCollection(ClientContext context, Collection<string> entries, LogHelper logger) { List<PropertyData> data = new List<PropertyData>(); foreach (PropertyBase item in this.Properties) { if (item.Index < entries.Count) { try { string account = entries[this.UserNameIndex]; PropertyData property = new PropertyData(); property.Name = item.Name; property = item.Process(property, entries[item.Index], this) as PropertyData; data.Add(property); } catch (Exception ex) { logger.LogException(string.Format(System.Globalization.CultureInfo.InvariantCulture, "Error occured whilst processing account '{0}', Property '{1}'. Stack {2}", entries[this.UserNameIndex], item.Name, ex.ToString()), ex); } } } logger.LogVerbose(string.Format("Attempting to update profile for account '{0}'", entries[this.UserNameIndex])); try { this.profileService.ModifyUserPropertyByAccountName(entries[this.UserNameIndex], data.ToArray()); logger.LogOutcome(entries[this.UserNameIndex], "SUCCESS"); } catch(Exception ex) { logger.LogException(string.Format(System.Globalization.CultureInfo.InvariantCulture, "Error occured whilst processing account '{0}' - the account does not exist", entries[this.UserNameIndex]), ex); logger.LogOutcome(entries[this.UserNameIndex], "FAILURE"); } }
/// <summary> /// Executes the business logic /// </summary> /// <param name="logger">The logger.</param> public override void Run(BaseAction parentAction, DateTime CurrentTime, LogHelper logger) { if (parentAction != null) { this.Properties = parentAction.Properties; } CsvProcessor csvProcessor = new CsvProcessor(); string[] csvFiles = Directory.GetFiles(this.CSVDirectoryLocation, "*.csv", SearchOption.TopDirectoryOnly); logger.LogVerbose(string.Format("Attempting to get files from directory 'location' {0}. Number of files found {1}", this.CSVDirectoryLocation, csvFiles.Length)); foreach (string csvFile in csvFiles) { logger.LogVerbose(string.Format("Attempting to read CSV file '{0}' from location {1}", csvFile, this.CSVDirectoryLocation)); logger.LogVerbose(string.Format("Pausing the utility for '{0}' seconds so ASMX service is not overloaded", this.SleepPeriod)); Thread.Sleep(this.SleepPeriod * 1000); using (StreamReader reader = new StreamReader(csvFile)) { logger.LogVerbose(string.Format("Establishing connection with tenant at '{0}'", this.TenantSiteUrl)); using (ClientContext context = new ClientContext(this.TenantSiteUrl)) { Uri site = new Uri(this.TenantSiteUrl); try { UserProfileService.UserProfileService profileService = new UserProfileService.UserProfileService(site.ToString() + ProfileService); this.profileService = profileService; profileService.UseDefaultCredentials = false; using (SecureString password = new SecureString()) { foreach (char c in this.TenantAdminPassword.ToCharArray()) { password.AppendChar(c); } logger.LogVerbose(string.Format("Attempting to authenticate against tenant with user name '{1}'", this.TenantSiteUrl, this.TenantAdminUserName)); var crudentials = new SharePointOnlineCredentials(this.TenantAdminUserName, password); string cookie = crudentials.GetAuthenticationCookie(site); profileService.CookieContainer = new CookieContainer(); profileService.CookieContainer.Add(new Cookie(FedAuthCookieName, cookie.TrimStart(SPOIDCookieValue.ToCharArray()), string.Empty, site.Authority)); csvProcessor.Execute(reader, (entries, y) => { IterateCollection(context, entries, logger); }, logger); } } finally { if (this.profileService != null) { this.profileService.Dispose(); } } } } // Clean up current CSV file System.IO.File.Delete(csvFile); } }
/// <summary> /// Iterates the row from the CSV file /// </summary> /// <param name="entries">The collection values per row.</param> /// <param name="logger">The logger.</param> public override void IterateCollection(Collection<string> entries, LogHelper logger) { Stopwatch IterationSW = new Stopwatch(); IterationSW.Start(); logger.LogVerbose(string.Format(CultureInfo.CurrentCulture, "Establishing context object to: '{0}'", entries[this.SiteIndex])); try { // Use context of current iteration URL for current user item using (ClientContext context = new ClientContext(entries[this.SiteIndex])) { using (SecureString password = new SecureString()) { foreach (char c in this.Password.ToCharArray()) { password.AppendChar(c); } context.Credentials = new SharePointOnlineCredentials(this.UserName, password); // Get file to upload from directory FileInfo theFileToUpload = new FileInfo(Path.Combine(this.DirectoryLocation + "\\", entries[this.FileIndex] + ".xlsx")); logger.LogVerbose(string.Format(CultureInfo.CurrentCulture, "Attempting to {0} file {1}", this.DocumentAction, theFileToUpload)); // Ensure account has permissions to access BasePermissions perm = new BasePermissions(); perm.Set(PermissionKind.AddListItems); ConditionalScope scope = new ConditionalScope(context, () => context.Web.DoesUserHavePermissions(perm).Value); using(scope.StartScope()) { Stopwatch tempSW = new Stopwatch(); tempSW.Start(); int success = 0; while(tempSW.Elapsed.TotalSeconds < 20) { var digest = context.GetFormDigestDirect(); string cookie = ((SharePointOnlineCredentials)context.Credentials).GetAuthenticationCookie(new Uri(entries[this.SiteIndex])).TrimStart("SPOIDCRL=".ToCharArray()); using (Stream s = theFileToUpload.OpenRead()) { // Define REST string request to upload document to context string theTargetUri = string.Format(CultureInfo.CurrentCulture, "{0}/_api/web/lists/getByTitle('Documents')/RootFolder/Files/add(url='{1}',overwrite='true')?", entries[this.SiteIndex], this.FileUploadName); // Define REST HTTP request obkect HttpWebRequest SPORequest = (HttpWebRequest)HttpWebRequest.Create(theTargetUri); // Define HTTP request action method if (this.DocumentAction == "Upload") { SPORequest.Method = "POST"; } else if (this.DocumentAction == "Delete") { SPORequest.Method = "DELETE"; } else { logger.LogVerbose(string.Format(CultureInfo.CurrentCulture, "There was a problem with the HTTP request in DocumentAction attribute of XML file")); throw new Exception("The HTTP Request operation is not supported, please check the value of DocumentAction in the XML file"); } // Build out additional HTTP request details SPORequest.Accept = "application/json;odata=verbose"; SPORequest.Headers.Add("X-RequestDigest", digest.DigestValue); SPORequest.ContentLength = s.Length; SPORequest.ContentType = "application/octet-stream"; // Handle authentication to context through cookie SPORequest.CookieContainer = new CookieContainer(); SPORequest.CookieContainer.Add(new Cookie("SPOIDCRL", cookie, string.Empty, new Uri(entries[this.SiteIndex]).Authority)); // Perform file upload/deletion using (Stream requestStream = SPORequest.GetRequestStream()) { s.CopyTo(requestStream); } // Get HTTP response to determine success of operation HttpWebResponse SPOResponse = (HttpWebResponse)SPORequest.GetResponse(); logger.LogVerbose(string.Format(CultureInfo.CurrentCulture, "Successfully '{0}' file {1}", this.DocumentAction, theFileToUpload)); logger.LogOutcome(entries[this.SiteIndex], "SUCCCESS"); success = 1; // Dispose of the HTTP response SPOResponse.Close(); break; } } tempSW.Stop(); if (success != 1) { throw new Exception("The HTTP Request operation exceeded the timeout of 20 seconds"); } } } } } catch(Exception ex) { logger.LogVerbose(string.Format(CultureInfo.CurrentCulture, "There was an issue performing '{0}' on to the URL '{1}' with exception: {2}", this.DocumentAction, entries[this.SiteIndex], ex.Message)); logger.LogOutcome(entries[this.SiteIndex], "FAILURE"); } finally { IterationSW.Stop(); logger.LogVerbose(string.Format(CultureInfo.CurrentCulture, "Completed processing URL:'{0}' in {1} seconds", entries[this.SiteIndex], IterationSW.ElapsedMilliseconds/1000)); } }
/// <summary> /// Executes the business logic /// </summary> /// <param name="logger">The logger.</param> public override void Run(BaseAction parentAction, DateTime CurrentTime, LogHelper logger) { CsvProcessor csvProcessor = new CsvProcessor(); logger.LogVerbose(string.Format("Attempting to read mapping CSV file '{0}'", this.UserMappingCSVFile)); using (StreamReader reader = new StreamReader(this.UserMappingCSVFile)) { csvProcessor.Execute(reader, (entries, y) => { IterateCollection(entries, logger); }, logger); } }
/// <summary> /// Executes the business logic /// </summary> /// <param name="logger">The logger.</param> public virtual void Run(BaseAction parentAction, DateTime CurrentTime, LogHelper logger = null) { CsvProcessor csvProcessor = new CsvProcessor(); string[] csvFiles = Directory.GetFiles(this.CSVDirectoryLocation, "*.csv", SearchOption.TopDirectoryOnly); foreach (string csvFile in csvFiles) { using (StreamReader reader = new StreamReader(csvFile)) { using (ClientContext context = new ClientContext(this.TenantSiteUrl)) { using (SecureString password = new SecureString()) { foreach (char c in this.TenantAdminPassword.ToCharArray()) { password.AppendChar(c); } context.Credentials = new SharePointOnlineCredentials(this.TenantAdminUserName, password); } csvProcessor.Execute(reader, (entries, y) => { IterateCollection(context, entries, logger); }, logger); } } } }
/// <summary> /// Iterates the row from the CSV file /// </summary> /// <param name="context">The ClientContext instance.</param> /// <param name="entries">The collection values per row.</param> /// <param name="logger">The logger.</param> public abstract void IterateCollection(ClientContext context, Collection<string> entries, LogHelper logger);
/// <summary> /// Executes the business logic /// </summary> /// <param name="logger">The logger.</param> public virtual void Run(BaseAction parentAction, DateTime CurrentTime, LogHelper logger = null) { }
/// <summary> /// Iterates the row from the CSV file /// </summary> /// <param name="context">The ClientContext instance.</param> /// <param name="entries">The collection values per row.</param> /// <param name="logger">The logger.</param> public abstract void IterateCollection(Collection<string> entries, LogHelper logger);