/// <summary> /// Formats as block-formatted string of an <see cref="ILinkDetails" />. /// </summary> /// <param name="linkDetails">The data to format.</param> /// <returns>The formatted string.</returns> public string Format(ILinkDetails linkDetails) { if (linkDetails == null) { return("<null>"); } StringBuilder returnBuilder = new StringBuilder((linkDetails.Details?.Count ?? 1) * 128); returnBuilder.Append("Link Details:"); if (linkDetails.Details.Count == 0) { returnBuilder.Append(" No link found."); } else { foreach (var item in linkDetails.Details) { returnBuilder.AppendLine().AppendLine(SnmpAbstraction.IndentLines(this.Format(item))); } } return(returnBuilder.ToString()); }
/// <summary> /// Construct by copying another <see cref="ILinkDetails" /> /// </summary> /// <param name="linkDetails">The link details to copy and store.</param> public LinkDetailsStoreOnlyContainer(ILinkDetails linkDetails) { this.DeviceAddress = linkDetails.DeviceAddress; this.DeviceModel = linkDetails.DeviceModel; this.Details = linkDetails.Details.Select(d => new LinkDetailStoreOnlyContainer(d)).ToList(); // assign this last so it contains the sum of the possibly lazy evaluations triggered by above assignments this.QueryDuration = linkDetails.QueryDuration; }
/// <summary> /// Construct from error info and link details. /// </summary> /// <param name="linkDetails">The link details.</param> public LinkDetailsReply(ILinkDetails linkDetails) { if (linkDetails == null) { throw new ArgumentNullException(nameof(linkDetails), "The link details to return is null"); } linkDetails.ForceEvaluateAll(); this.Details = linkDetails.Details.Select(d => new LinkDetailReply(d)).ToList(); }
/// <summary> /// Calls the <see cref="IAquiredDataHandler.RecordDetailsInDatabaseAsync" /> for all configured handlers. /// </summary> private void SendResultsToDataHandlers(KeyValuePair<IHamnetDbSubnet, IHamnetDbHosts> pair, ILinkDetails linkDetails, IEnumerable<IDeviceSystemData> systemDatas, DateTime queryTime) { foreach (IAquiredDataHandler handler in this.dataHandlers) { try { handler.RecordRssiDetailsInDatabaseAsync(pair, linkDetails, queryTime); handler.RecordUptimesInDatabase(pair, linkDetails, systemDatas, queryTime); } catch(Exception ex) { this.logger.LogError($"Excpetion recording failed query at handler {handler.Name}: {ex.Message}"); } } }
private async Task GetAndMapContentItem( IList <IBaseContentItemModel> contentItem, ILinkDetails linkDetail, Dictionary <int, List <string> > retrievedPaths, CmsApiOptions options, int level) { var mappingToUse = contentTypeMappingService.GetMapping(linkDetail.ContentType !); var isOwnAncestor = AncestorsContainsType(linkDetail.Uri !.AbsolutePath, retrievedPaths, level); var passedRecursionCheck = !options.PreventRecursion || !isOwnAncestor; if (mappingToUse == null || !passedRecursionCheck) { return; } if (!retrievedPaths.ContainsKey(level)) { retrievedPaths.Add(level, new List <string>()); } var contentType = GetContentType(linkDetail.Uri !.AbsolutePath) ?? "Unknown"; retrievedPaths[level].Add(contentType); var keyName = (options.ContentTypeOptions?.ContainsKey(contentType) == true ? options.ContentTypeOptions[contentType].KeyName : null) ?? "Uri"; var key = keyName.ToUpperInvariant() switch { "TITLE" => linkDetail.Title !, _ => linkDetail.Uri.ToString() }; if (options.ContentTypeOptions?.ContainsKey(contentType) == true && options.ContentTypeOptions[contentType].Transform != null) { key = options.ContentTypeOptions[contentType].Transform !(key); } var pagesApiContentItemModel = GetFromApiCache <IBaseContentItemModel>(mappingToUse, key) ?? AddToApiCache(key, await GetContentItemAsync <IBaseContentItemModel>(mappingToUse !, linkDetail.Uri !).ConfigureAwait(false)); if (pagesApiContentItemModel == null) { return; } mapper.Map(linkDetail, pagesApiContentItemModel); if (pagesApiContentItemModel.ContentLinks != null) { pagesApiContentItemModel.ContentLinks.ExcludePageLocation = true; await GetSharedChildContentItems( pagesApiContentItemModel.ContentLinks, pagesApiContentItemModel.ContentItems, retrievedPaths, options, level).ConfigureAwait(false); } contentItem.Add(pagesApiContentItemModel !); }
private async Task GetAndMapContentItem(IList <IBaseContentItemModel> contentItem, ILinkDetails linkDetail) { var mappingToUse = contentTypeMappingService.GetMapping(linkDetail.ContentType !); if (mappingToUse != null) { var pagesApiContentItemModel = GetFromApiCache <IBaseContentItemModel>(mappingToUse, linkDetail.Uri !) ?? AddToApiCache(await GetContentItemAsync <IBaseContentItemModel>(mappingToUse !, linkDetail !.Uri !).ConfigureAwait(false)); if (pagesApiContentItemModel != null) { mapper.Map(linkDetail, pagesApiContentItemModel); if (pagesApiContentItemModel.ContentLinks != null) { pagesApiContentItemModel.ContentLinks.ExcludePageLocation = true; await GetSharedChildContentItems(pagesApiContentItemModel.ContentLinks, pagesApiContentItemModel.ContentItems).ConfigureAwait(false); } contentItem.Add(pagesApiContentItemModel !); } } }
/// <inheritdoc /> public void RecordRssiDetailsInDatabase(KeyValuePair <IHamnetDbSubnet, IHamnetDbHosts> inputData, ILinkDetails linkDetails, DateTime queryTime) { using (var databaseContext = QueryResultDatabaseProvider.Instance.CreateContext()) { using (var transaction = databaseContext.Database.BeginTransaction()) { this.DoRecordRssiDetailsInDatabase(databaseContext, inputData, linkDetails, DateTime.UtcNow); this.DoDeleteFailingRssiQuery(databaseContext, inputData.Key); databaseContext.SaveChanges(); transaction.Commit(); } } }
/// <summary> /// Records the link details in the database. /// </summary> /// <param name="databaseContext">The database context to work with.</param> /// <param name="inputData">The input data of the query.</param> /// <param name="linkDetails">The link details to record.</param> /// <param name="queryTime">The time of the data aquisition (recorded with the data).</param> private void DoRecordRssiDetailsInDatabase(QueryResultDatabaseContext databaseContext, KeyValuePair <IHamnetDbSubnet, IHamnetDbHosts> inputData, ILinkDetails linkDetails, DateTime queryTime) { string host1call = inputData.Value.First().Callsign?.ToUpperInvariant(); string host2call = inputData.Value.Last().Callsign?.ToUpperInvariant(); foreach (var item in linkDetails.Details) { this.SetNewRssiForLink(databaseContext, inputData.Key, queryTime, item, item.Address1.ToString(), item.RxLevel1at2, host1call, $"{host1call} at {host2call}"); this.SetNewRssiForLink(databaseContext, inputData.Key, queryTime, item, item.Address2.ToString(), item.RxLevel2at1, host2call, $"{host2call} at {host1call}"); } }
/// <inheritdoc /> public Task RecordUptimesInDatabaseAsync(KeyValuePair <IHamnetDbSubnet, IHamnetDbHosts> inputData, ILinkDetails linkDetails, IEnumerable <IDeviceSystemData> systemDatas, DateTime queryTime) { // Currently a NOP for this database handler return(Task.CompletedTask); }
/// <inheritdoc /> public void RecordUptimesInDatabase(KeyValuePair <IHamnetDbSubnet, IHamnetDbHosts> inputData, ILinkDetails linkDetails, IEnumerable <IDeviceSystemData> systemDatas, DateTime queryTime) { // Currently a NOP for this database handler }
/// <inheritdoc /> public Task RecordRssiDetailsInDatabaseAsync(KeyValuePair <IHamnetDbSubnet, IHamnetDbHosts> inputData, ILinkDetails linkDetails, DateTime queryTime) { return(Task.Run(() => { try { this.RecordRssiDetailsInDatabase(inputData, linkDetails, queryTime); } catch (Exception ex) { // we don not want to throw from an async task log.Error($"Caught and ignored exception in async recording of details for {inputData.Key} @ {queryTime}: {ex.Message}", ex); } })); }
/// <summary> /// Formats a generic object if it's of one of the supported types. /// </summary> /// <param name="someObject">The object to format.</param> /// <returns>The formatted text.</returns> public string Format(object someObject) { if (someObject == null) { return("<null>"); } IDeviceSystemData asDevSysData = someObject as IDeviceSystemData; if (asDevSysData != null) { return(this.Format(asDevSysData)); } IInterfaceDetails asIfDetails = someObject as IInterfaceDetails; if (asIfDetails != null) { return(this.Format(asIfDetails)); } IInterfaceDetail asIfDetail = someObject as IInterfaceDetail; if (asIfDetail != null) { return(this.Format(asIfDetail)); } IWirelessPeerInfos asWiPeerInfos = someObject as IWirelessPeerInfos; if (asWiPeerInfos != null) { return(this.Format(asWiPeerInfos)); } IWirelessPeerInfo asWiPeerInfo = someObject as IWirelessPeerInfo; if (asWiPeerInfo != null) { return(this.Format(asWiPeerInfo)); } ILinkDetails asLinkDetails = someObject as ILinkDetails; if (asLinkDetails != null) { return(this.Format(asLinkDetails)); } IBgpPeers asBgpPeers = someObject as IBgpPeers; if (asBgpPeers != null) { return(this.Format(asBgpPeers)); } IBgpPeer asBgpPeer = someObject as IBgpPeer; if (asBgpPeer != null) { return(this.Format(asBgpPeer)); } ITracerouteResult asTracerouteResult = someObject as ITracerouteResult; if (asTracerouteResult != null) { return(this.Format(asTracerouteResult)); } ITracerouteHop asTracerouteHop = someObject as ITracerouteHop; if (asTracerouteHop != null) { return(this.Format(asTracerouteHop)); } // fallback: call the object's ToString return(someObject.ToString()); }
/// <inheritdoc /> public void RecordUptimesInDatabase(KeyValuePair <IHamnetDbSubnet, IHamnetDbHosts> inputData, ILinkDetails linkDetails, IEnumerable <IDeviceSystemData> systemDatas, DateTime queryTime) { lock (this.recordingLock) { this.CreateNewPayload(); string host1call = inputData.Value.First().Callsign?.ToUpperInvariant(); string host2call = inputData.Value.Last().Callsign?.ToUpperInvariant(); var queryUniversalTime = queryTime.ToUniversalTime(); this.currentPayload.Add( new LineProtocolPoint( InfluxLinkUptimeDatapointName, new Dictionary <string, object> { { InfluxValueKey, linkDetails.Details.First().LinkUptime } }, new Dictionary <string, string> { { InfluxSubnetTagName, inputData.Key.Subnet.ToString() }, { InfluxCallTagName, host1call }, { InfluxCall2TagName, host2call }, { InfluxDescriptionTagName, $"{host1call} and {host2call}" } }, queryUniversalTime)); foreach (var item in systemDatas) { if (!item.Uptime.HasValue) { continue; } var itemDbHost = inputData.Value.FirstOrDefault(h => h.Address.Equals((IPAddress)item.DeviceAddress)); if (itemDbHost == null) { log.Error($"Cannot find address {item.DeviceAddress} in HamnetDB. Hence cannot provide call for that address. Skipping this device for recording of device uptime in InfluxDB"); continue; } string hostCall = itemDbHost.Callsign.ToUpperInvariant(); this.currentPayload.Add( new LineProtocolPoint( InfluxDeviceUptimeDatapointName, new Dictionary <string, object> { { InfluxValueKey, item.Uptime.Value } }, new Dictionary <string, string> { { InfluxHostTagName, item.DeviceAddress.ToString() }, { InfluxSubnetTagName, inputData.Key.Subnet.ToString() }, { InfluxCallTagName, hostCall }, { InfluxDescriptionTagName, $"System Uptime {hostCall}" } }, queryUniversalTime)); } this.SendCurrentPayload(); } }
/// <inheritdoc /> public void RecordRssiDetailsInDatabase(KeyValuePair <IHamnetDbSubnet, IHamnetDbHosts> inputData, ILinkDetails linkDetails, DateTime queryTime) { lock (this.recordingLock) { this.CreateNewPayload(); string host1call = inputData.Value.First().Callsign?.ToUpperInvariant(); string host2call = inputData.Value.Last().Callsign?.ToUpperInvariant(); var queryUniversalTime = queryTime.ToUniversalTime(); this.currentPayload.Add( new LineProtocolPoint( InfluxLinkUptimeDatapointName, new Dictionary <string, object> { { InfluxValueKey, linkDetails.Details.First().LinkUptime } }, new Dictionary <string, string> { { InfluxSubnetTagName, inputData.Key.Subnet.ToString() }, { InfluxCallTagName, host1call }, { InfluxCall2TagName, host2call }, { InfluxDescriptionTagName, $"RF Link {host1call} and {host2call}" } }, queryUniversalTime)); foreach (var item in linkDetails.Details) { if (this.currentPayload == null) { this.CreateNewPayload(); } this.currentPayload.Add( new LineProtocolPoint( InfluxRssiDatapointName, new Dictionary <string, object> { { InfluxValueKey, item.RxLevel1at2 } }, new Dictionary <string, string> { { InfluxHostTagName, item.Address1.ToString() }, { InfluxSubnetTagName, inputData.Key.Subnet.ToString() }, { InfluxCallTagName, host1call }, { InfluxDescriptionTagName, $"RSSI {host1call} at {host2call}" } }, queryUniversalTime)); this.currentPayload.Add( new LineProtocolPoint( InfluxRssiDatapointName, new Dictionary <string, object> { { InfluxValueKey, item.RxLevel2at1 } }, new Dictionary <string, string> { { InfluxHostTagName, item.Address2.ToString() }, { InfluxSubnetTagName, inputData.Key.Subnet.ToString() }, { InfluxCallTagName, host2call }, { InfluxDescriptionTagName, $"RSSI {host2call} at {host1call}" } }, queryUniversalTime)); if (item.Ccq1.HasValue) { this.currentPayload.Add( new LineProtocolPoint( InfluxCcqHostDatapointName, new Dictionary <string, object> { { InfluxValueKey, item.Ccq1.Value } }, new Dictionary <string, string> { { InfluxSubnetTagName, inputData.Key.Subnet.ToString() }, { InfluxCallTagName, host1call }, { InfluxDescriptionTagName, $"CCQ at {host1call} to {host2call}" } }, queryUniversalTime)); } if (item.Ccq2.HasValue) { this.currentPayload.Add( new LineProtocolPoint( InfluxCcqHostDatapointName, new Dictionary <string, object> { { InfluxValueKey, item.Ccq2.Value } }, new Dictionary <string, string> { { InfluxSubnetTagName, inputData.Key.Subnet.ToString() }, { InfluxCallTagName, host2call }, { InfluxDescriptionTagName, $"CCQ at {host2call} to {host1call}" } }, queryUniversalTime)); } if (item.Ccq.HasValue) { this.currentPayload.Add( new LineProtocolPoint( InfluxCcqDatapointName, new Dictionary <string, object> { { InfluxValueKey, item.Ccq.Value } }, new Dictionary <string, string> { { InfluxSubnetTagName, inputData.Key.Subnet.ToString() }, { InfluxCallTagName, host1call }, { InfluxCall2TagName, host2call }, { InfluxDescriptionTagName, $"CCQ {host1call} and {host2call}" } }, queryUniversalTime)); } } this.SendCurrentPayload(); } }