protected void OnDeserialized(StreamingContext context) { if (Energieverbrauch == null) { Energieverbrauch = new List <Verbrauch>(); } else if (Energieverbrauch.Count > 0) { Energieverbrauch = Energieverbrauch .Select(v => Verbrauch.FixSapCdsBug(v)) .Where(v => !(v.Startdatum == DateTime.MinValue || v.Enddatum == DateTime.MinValue)) .Where(v => !(v.UserProperties != null && v.UserProperties.ContainsKey("invalid") && (bool)v.UserProperties["invalid"] == true)) .ToList(); if (UserProperties != null && UserProperties.TryGetValue(Verbrauch._SAP_PROFDECIMALS_KEY, out JToken profDecimalsRaw)) { var profDecimals = profDecimalsRaw.Value <int>(); if (profDecimals > 0) { for (int i = 0; i < profDecimals; i++) { // or should I import math.pow() for this purpose? foreach (Verbrauch v in Energieverbrauch.Where(v => v.UserProperties == null || !v.UserProperties.ContainsKey(Verbrauch._SAP_PROFDECIMALS_KEY))) { v.Wert /= 10.0M; } } } UserProperties.Remove(Verbrauch._SAP_PROFDECIMALS_KEY); } } }
/// <summary> /// Our SAP Core Data Service view definition reading the profile values has a bug: /// The time stamp of both start- and enddatum is simply a concatenated string using the /// date (defining the table row) and the time (determining the column). The design of /// the table eprofval is pure PITA but we've got to deal with it anyway. Since it's /// impossible to artificially increment the date directly in the definition of the /// ABAP/SQL view (as of SAP 7.51), we're attempting to fix it here. On 363 days a year /// the symptom is easy to detect: The last time slice of the day ranges from 23:45 of /// the current day and has the enddatum t 00:00 still on the same day instead of the /// following. What makes it difficult are the edge cases. What happens on the day we /// switch from daylight saving time to non-daylight saving time? The time difference /// could be in the order of magnitude of 22 to 25 hours. Please add new unit tests for /// every edge case. /// </summary> public void FixSapCdsBug() { //using (MiniProfiler.Current.Step("FixSapCdsBug (Verbrauch)")) // don't do this. it slows down everything ! // { if (Startdatum != null && Enddatum != null && Startdatum > Enddatum) { TimeSpan diff = Startdatum - Enddatum; if (diff.Hours <= 25 && diff.Hours >= 23 && diff.Minutes == 45 && Startdatum.Hour >= 22 && Enddatum.Hour == 0) { Enddatum += new TimeSpan(diff.Hours + 1, 0, 0); } else { // something seems wrong but not sure how to fix it. } } Startdatum = DateTime.SpecifyKind(Startdatum, DateTimeKind.Utc); Enddatum = DateTime.SpecifyKind(Enddatum, DateTimeKind.Utc); if ((int)(Enddatum - Startdatum).TotalHours == 2) { // check DST of start and enddatum var startdatumLocal = TimeZoneInfo.ConvertTimeFromUtc(Startdatum, Verbrauch.CENTRAL_EUROPE_STANDARD_TIME); var enddatumLocal = TimeZoneInfo.ConvertTimeFromUtc(Enddatum, Verbrauch.CENTRAL_EUROPE_STANDARD_TIME); if (!Verbrauch.CENTRAL_EUROPE_STANDARD_TIME.IsDaylightSavingTime(startdatumLocal - new TimeSpan(0, 0, 1)) && Verbrauch.CENTRAL_EUROPE_STANDARD_TIME.IsDaylightSavingTime(enddatumLocal)) { // change winter-->summer time (e.g. UTC+1-->UTC+2) // this is an artefact of the sap enddatum computation Enddatum -= new TimeSpan(1, 0, 0); // toDo: get offset from timezoneinfo->rules->dstOffset } } else if ((int)(Enddatum - Startdatum).TotalMinutes == -45) { // check DST of start and enddatum //var startdatumLocal = TimeZoneInfo.ConvertTimeFromUtc(startdatum, Verbrauch.CENTRAL_EUROPE_STANDARD_TIME); var enddatumLocal = TimeZoneInfo.ConvertTimeFromUtc(Enddatum, Verbrauch.CENTRAL_EUROPE_STANDARD_TIME); if (!Verbrauch.CENTRAL_EUROPE_STANDARD_TIME.IsDaylightSavingTime(enddatumLocal - new TimeSpan(1, 0, 0)) && Verbrauch.CENTRAL_EUROPE_STANDARD_TIME.IsDaylightSavingTime(enddatumLocal - new TimeSpan(1, 0, 1))) { // change winter-->summer time (e.g. UTC+1-->UTC+2) // this is an artefact of the sap enddatum computation Enddatum += new TimeSpan(1, 0, 0); // toDo: get offset from timezoneinfo->rules->dstOffset } } if (UserProperties != null && UserProperties.TryGetValue(_SAP_PROFDECIMALS_KEY, out JToken profDecimalsRaw)) { var profDecimals = profDecimalsRaw.Value <int>(); if (profDecimals > 0) { // or should I import math.pow() for this purpose? for (int i = 0; i < profDecimals; i++) { Wert /= 10.0M; } } UserProperties.Remove(_SAP_PROFDECIMALS_KEY); } }
private static string SetPropertiesToUser(DirectoryEntry destUser, UserProperties newProps) { string changedProps = ""; foreach (var prop in propNamesDestination) { string[] newValue; if (!propIgnoreDest.Contains(prop)) { if (newProps.TryGetValue(prop, out newValue)) { changedProps += CheckAndSetProperty(destUser.Properties, prop, newValue, true); } } //else // changedProps += CheckAndSetProperty(destUser.Properties, prop, null, true); } return(changedProps); }
protected void OnDeserialized(StreamingContext context) { if (Energieverbrauch == null) { Energieverbrauch = new List <Verbrauch>(); } else if (Energieverbrauch.Count > 0) { Energieverbrauch = Energieverbrauch .Select(Verbrauch.FixSapCdsBug) .Where(v => !(v.Startdatum == DateTimeOffset.MinValue || v.Enddatum == DateTimeOffset.MinValue)) .Where(v => !v.UserPropertyEquals("invalid", true)) .ToList(); if (UserProperties != null && UserProperties.TryGetValue(Verbrauch.SapProfdecimalsKey, out var profDecimalsRaw)) { var profDecimals = 0; if (profDecimalsRaw is string raw) { profDecimals = int.Parse(raw); } else { profDecimals = ((JsonElement)profDecimalsRaw).GetInt32(); } if (profDecimals > 0) { for (var i = 0; i < profDecimals; i++) { // or should I import math.pow() for this purpose? foreach (var v in Energieverbrauch.Where(v => v.UserProperties == null || !v.UserProperties.ContainsKey(Verbrauch.SapProfdecimalsKey))) { v.Wert /= 10.0M; } } } UserProperties.Remove(Verbrauch.SapProfdecimalsKey); } } }
private static void InitializeAllAccounts() { CacheAllGroups(); log.LogInfo("Initialize accounts ..."); PollAD adSource = GetAvailableAD(config.SourceADServers, lastHighUSNs, true); PollAD adDest = GetAvailableAD(config.DestADServers, lastHighUSNs, true); lastHighUSNs[adSource.GetInvocationID] = adSource.CurrentHighUSN; try { IDictionary <string, UserProperties> userByObjectSID = new Dictionary <string, UserProperties>(adDest.ChangedUsersProperties.Count); IDictionary <string, UserProperties> userBySamAccount = new Dictionary <string, UserProperties>(adDest.ChangedUsersProperties.Count); log.LogInfo("Loaded " + adSource.ChangedUsersProperties.Count + " accounts from SourceAD " + adSource.DnsHostName + " and " + adDest.ChangedUsersProperties.Count + " accounts from Destination AD " + adDest.DnsHostName); foreach (var userProps in adDest.ChangedUsersProperties) { userProps.Remove("ObjectSID"); if (userProps.ContainsKey("Pager") && userProps["Pager"] != null) { userByObjectSID[userProps["Pager"][0]] = userProps; } userBySamAccount[userProps["samAccountName"][0]] = userProps; } log.LogDebug(" " + userByObjectSID.Count + " users has initialized ObjectSID in DestAD"); var changedUsers = new List <UserProperties>(); var cnt = adSource.ChangedUsersProperties.Count; FilterAccounts(adSource.ChangedUsersProperties, config.DestADServers.Select(s => s.ServerUserName), oUsToMonitor, oUsDNToMonitor); if (cnt - adSource.ChangedUsersProperties.Count > 0) { log.LogInfo("Filtered out " + (cnt - adSource.ChangedUsersProperties.Count) + " accounts"); } // Compare Source and Destination users ... foreach (var userProps in adSource.ChangedUsersProperties) { UserProperties destUser = null; if (!userByObjectSID.TryGetValue(userProps["ObjectSID"][0], out destUser) || destUser == null) { userBySamAccount.TryGetValue(userProps["samAccountName"][0], out destUser); } if (destUser == null) // not found by SID nor samAccountName { log.LogDebug(" '" + userProps["samAccountName"][0] + "' is new user"); changedUsers.Add(userProps); // new user } else { ADHintElement adHint = null; try { string notUsed; adHint = ADHintsConfigurationSection.GetOUByAttributes(userProps, destUser, out notUsed); } catch (Exception) { } // {[distinguishedName, CN=user3. sdfsdf,OU=Office31,OU=Office3,OU=Domain Controllers,DC=kireev,DC=local]} // simple way to determine if OU is changed if (adHint != null && destUser["distinguishedName"][0].IndexOf(adHint.DestOU, StringComparison.OrdinalIgnoreCase) < 0) { log.LogDebug(" '" + destUser["distinguishedName"][0] + "' need to move to " + adHint.DestOU); changedUsers.Add(userProps); // OU is changed } else { foreach (var prop in userProps) { string[] destPropVal; if (!PollAD.propIgnoreDest.Contains(prop.Key) && destUser.TryGetValue(prop.Key, out destPropVal) && prop.Value != null && !Utils.CheckEquals(prop.Value, destPropVal)) { log.LogDebug(" '" + userProps["samAccountName"][0] + "' changed [" + prop.Key + "]='" + Utils.PropVal(destPropVal) + "' -> '" + Utils.PropVal(prop.Value) + "'"); changedUsers.Add(userProps); break; } } } } } if (changedUsers.Count == 0) { log.LogInfo("Initialization complete. No differences between SourceAD and DestinationAD found."); } else { log.LogInfo("Need to update " + changedUsers.Count + " accounts..."); var updatedCnt = PutToDestinationAD(config.DestADServers, changedUsers, true); log.LogInfo("Initialization complete. Successfully updated " + updatedCnt + " of " + changedUsers.Count + " accounts."); } } catch (Exception ex) { log.LogError(ex, "Failed to Initialize: " + ex.Message); return; } }
/// <summary> /// Convert CompletenessReport to CSV string /// </summary> /// <param name="separator">Seperatur char for CSV items. By default is ';'</param> /// <param name="headerLine">Shows header of columns in return string?</param> /// <param name="lineTerminator">This value goes to end of every line. By default is "\\n"</param> /// <returns></returns> public string ToCSV(string separator = ";", bool headerLine = true, string lineTerminator = "\\n") { var builder = new StringBuilder(); if (headerLine) { var headerColumns = new List <string> { "Startdatum", "Enddatum", "MeLo", "MaLo", "Messung", "MSB", "Profil-Nr.", "Profil-Typ", "Zeitbereich in dem kein wahrer Wert vorhanden ist von", "Zeitbereich in dem kein wahrer Wert vorhanden ist bis", "Anzahl fehlende Werte", "Prozentuale Vollständigkeit", "Status" }; builder.Append(string.Join(separator, headerColumns) + lineTerminator); } var columns = new List <string> { ReferenceTimeFrame.Startdatum.Value.ToString("yyyy-MM-ddTHH:mm:ssZ"), ReferenceTimeFrame.Enddatum.Value.ToString("yyyy-MM-ddTHH:mm:ssZ") }; if (Messlokation.ValidateId(LokationsId)) { columns.Add(LokationsId); // melo columns.Add(string.Empty); // malo } else if (Marktlokation.ValidateId(LokationsId)) { columns.Add(string.Empty); //melo columns.Add(LokationsId); //malo } else { // fallback only columns.Add(LokationsId); columns.Add(LokationsId); } columns.Add(imsysRegex.Match(Obiskennzahl).Success ? "IMS" : "RLM"); // messung columns.Add("MSB"); // MSB if (UserProperties.TryGetValue("profil", out var profil)) { columns.Add(profil.ToString()); } else { columns.Add(string.Empty); } if (UserProperties.TryGetValue("profilRolle", out var profilRolle)) { columns.Add(profilRolle.ToString()); } else { columns.Add(string.Empty); } if (Gaps != null && Gaps.Any()) { var minGap = Gaps.Min(x => x.Startdatum); // OrderBy(x => x.Startdatum).First().Startdatum; var maxGap = Gaps.Max(x => x.Enddatum); // OrderByDescending(x => x.Enddatum).First().Enddatum; columns.Add(minGap.ToString("yyyy-MM-ddTHH:mm:ssZ")); columns.Add(maxGap.ToString("yyyy-MM-ddTHH:mm:ssZ")); var gapsHours = (maxGap - minGap).TotalHours; columns.Add((gapsHours * 4).ToString(CultureInfo.InvariantCulture)); } else { columns.Add(string.Empty); columns.Add(string.Empty); columns.Add(string.Empty); } if (Coverage.HasValue) { columns.Add((Coverage.Value * 100).ToString("0.####") + " %"); } else { columns.Add(string.Empty); } columns.Add("Status"); builder.Append(string.Join(separator, columns) + lineTerminator); return(builder.ToString()); }