/// <summary> /// Construct for a lower layer and a cache data set (from which we return the non-volatile data). /// </summary> public VolatileFetchingWirelessPeerInfos(IWirelessPeerInfos wirelessPeerInfos, ISnmpLowerLayer lowerLayer) { this.lowerLayer = lowerLayer ?? throw new System.ArgumentNullException(nameof(lowerLayer), "lower layer is null"); this.underlyingWirelessPeerInfo = wirelessPeerInfos ?? throw new System.ArgumentNullException(nameof(wirelessPeerInfos), "underlying wireless peer info is null"); this.Details = wirelessPeerInfos.Details.Select(underlyingPeerInfo => new VolatileFetchingWirelessPeerInfo(underlyingPeerInfo, this.lowerLayer)).ToList(); }
/// <summary> /// Formats as block-formatted string of an <see cref="IWirelessPeerInfos" />. /// </summary> /// <param name="wirelessPeerInfos">The data to format.</param> /// <returns>The formatted string.</returns> public string Format(IWirelessPeerInfos wirelessPeerInfos) { if (wirelessPeerInfos == null) { return("<null>"); } StringBuilder returnBuilder = new StringBuilder(256); returnBuilder.Append("Wireless Peer Infos: "); if (wirelessPeerInfos.Details == null) { returnBuilder.Append(NotAvailableString); } else { foreach (var item in wirelessPeerInfos.Details) { returnBuilder.AppendLine().AppendLine(SnmpAbstraction.IndentLines(this.Format(item))); } } return(returnBuilder.ToString()); }
/// <summary> /// Construct from IWirelessPeerInfos. /// </summary> public SerializableWirelessPeerInfos(IWirelessPeerInfos inputInfos) { if (inputInfos is null) { throw new ArgumentNullException(nameof(inputInfos), "The IWirelessPeerInfos to make serializable is null"); } this.peerInfosBacking = inputInfos.Details.Select(p => new SerializableWirelessPeerInfo(p) as IWirelessPeerInfo).ToList(); this.DeviceAddress = inputInfos.DeviceAddress; this.DeviceModel = inputInfos.DeviceModel; }
/// <inheritdoc /> public ILinkDetails DoQuery() { // we're only interested in the Wireless interfaces (not in ethernet ports or similar) and hence filter // for interface type 71 (ieee80211) // Note: We need to make the result distinct on MAC as some devices tend to return mulitple IEEE 802.11 interfaces with same MAC address. var wifiInterfaces1 = this.querier1.NetworkInterfaceDetails.Where(i => i.InterfaceType == IanaInterfaceType.Ieee80211).Distinct(this.InterfaceByMacAddressEqualityComparer).ToList(); var wifiInterfaces2 = this.querier2.NetworkInterfaceDetails.Where(i => i.InterfaceType == IanaInterfaceType.Ieee80211).Distinct(this.InterfaceByMacAddressEqualityComparer).ToList(); IWirelessPeerInfos wlPeerInfo1 = this.querier1.WirelessPeerInfos; IWirelessPeerInfos wlPeerInfo2 = this.querier2.WirelessPeerInfos; // see if side #2 has peers with MAC address of side #1 var peeringWithSide1 = (from wlp2 in wlPeerInfo2 from wi1 in wifiInterfaces1 where (wlp2.RemoteMacString?.ToLowerInvariant() == wi1.MacAddressString?.ToLowerInvariant()) select new Tuple <IInterfaceDetail, IWirelessPeerInfo>(wi1, wlp2)).SingleOrDefault(); // see if side #1 has peers with MAC address of side #2 var peeringWithSide2 = (from wlp1 in wlPeerInfo1 from wi2 in wifiInterfaces2 where (wlp1.RemoteMacString?.ToLowerInvariant() == wi2.MacAddressString?.ToLowerInvariant()) select new Tuple <IInterfaceDetail, IWirelessPeerInfo>(wi2, wlp1)).SingleOrDefault(); if (peeringWithSide1 == null) { throw new HamnetSnmpException($"Side #2 ({this.querier2.Address}) seems to have no peerings with side #1 ({this.querier1.Address})", this.querier2.Address?.ToString(), this.querier1.Address?.ToString()); } if (peeringWithSide2 == null) { throw new HamnetSnmpException($"Side #1 ({this.querier1.Address}) seems to have no peerings with side #2 ({this.querier2.Address})", this.querier1.Address?.ToString(), this.querier2.Address?.ToString()); } var returnDetails = new LinkDetails( new LinkDetail[] { new LinkDetail( this.querier1.Address, new LinkRelatedResultCollection( peeringWithSide1.Item1, peeringWithSide2.Item1, peeringWithSide2.Item2, peeringWithSide1.Item2)) }, this.querier1.Address, this.querier1.SystemData.DeviceModel); var lazyContainerSum = wifiInterfaces1.Aggregate(TimeSpan.Zero, (a, c) => a += c.QueryDuration); lazyContainerSum += wifiInterfaces2.Aggregate(TimeSpan.Zero, (a, c) => a += c.QueryDuration); lazyContainerSum += wlPeerInfo1.Aggregate(TimeSpan.Zero, (a, c) => a += c.QueryDuration); lazyContainerSum += wlPeerInfo2.Aggregate(TimeSpan.Zero, (a, c) => a += c.QueryDuration); log.Debug($"LinkDetectionQuery: Lazy container sum = {lazyContainerSum.TotalMilliseconds} ms"); return(returnDetails); }
/// <summary> /// Fetches wireless peer data. /// </summary> private void FetchWirelessPeerInfo() { if (this.wirelessPeerInfosBacking != null) { return; } Stopwatch stopper = Stopwatch.StartNew(); this.EnsureOpenConnection(); var wirelessPeers = this.TikConnection.LoadList <WirelessRegistrationTable>(); stopper.Stop(); this.wirelessPeerInfosBacking = new SerializableWirelessPeerInfos { DeviceAddress = this.Address, DeviceModel = this.SystemData.DeviceModel, Details = wirelessPeers.Select(d => this.MakeWirelessPeerInfo(d)).ToList(), QueryDuration = stopper.Elapsed }; }
/// <summary> /// Fetches the wireless peer info from lower querier and saves it to the database. /// </summary> private void LowerQuerierFetchWirelessPeerInfo() { lock (this.SyncRoot) { if (this.volatileFetchingWirelessPeerInfo != null) { return; } if (this.cacheEntry.WirelessPeerInfos == null) { this.InitializeLowerQuerier(); var lowerLayerWirelessPeerInfos = this.lowerQuerier.WirelessPeerInfos; // we force immediate evaluation in order to ensure that really all cachable OIDs have been set. lowerLayerWirelessPeerInfos.ForceEvaluateAll(); this.cacheEntry.WirelessPeerInfos = new SerializableWirelessPeerInfos(lowerLayerWirelessPeerInfos); this.cacheEntry.LastModification = DateTime.UtcNow; this.cacheDatabaseContext.CacheData.Update(this.cacheEntry); this.cacheDatabaseContext.SaveChanges(); } if (this.cacheEntry.ApiUsed.HasFlag(QueryApis.VendorSpecific)) { log.Info($"Forcing non-cached operation for FetchWirelessPeerInfo of device {this.Address} due to vendor specific API usage"); this.InitializeLowerQuerier(); this.volatileFetchingWirelessPeerInfo = this.lowerQuerier.WirelessPeerInfos; } else { this.volatileFetchingWirelessPeerInfo = new VolatileFetchingWirelessPeerInfos(this.cacheEntry.WirelessPeerInfos, this.lowerLayer); } } }
/// <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()); }