Exemplo n.º 1
0
        /// <summary>
        /// Tries to obtain the device version ID (database key) for the given device version (or the highest available version if null).
        /// </summary>
        /// <param name="context">The device database context to extend.</param>
        /// <param name="deviceId">The device ID to search versions for.</param>
        /// <param name="version">The version number to return the device version ID for. If null, the ID for the highest available version will be retrieved.</param>
        /// <param name="deviceVersion">Returns the device version object if a device version of for given device ID and version range has been found.</param>
        /// <returns><c>true</c> if a device version of the given version has been found and the ID returned. Otherwise <c>false</c>.</returns>
        public static bool TryFindDeviceVersionId(this DeviceDatabaseContext context, int deviceId, SemanticVersion version, out DeviceVersion deviceVersion)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context), "The context to search device version ID on is null");
            }

            deviceVersion = null;

            var result = context.DeviceVersions.Where(d => d.DeviceId == deviceId).OrderByDescending(d => d.HigherOrEqualVersion).ToList();

            if (result.Count == 0)
            {
                // no such device ID at all
                return(false);
            }

            if (version == null)
            {
                // no specific version requested, returns first entry (i.e. the one with the highest MinimumVersion)
                deviceVersion = result[0];
                return(true);
            }

            // need to search for the best match of specified version:
            // we take the entry with the highest minimum version where the requested version is below maximum version
            foreach (DeviceVersion item in result)
            {
                if ((item.HigherOrEqualVersion <= version) && ((item.LowerThanVersion == null) || (item.LowerThanVersion > version)))
                {
                    deviceVersion = item;
                    return(true);
                }
            }

            log.Debug($"TryFindDeviceVersionId: No version range for device ID {deviceId} in database is applicable to requested version '{version}'");

            return(false);
        }
        /// <summary>
        /// Gets the OID lookup table for the specified device name and version.
        /// </summary>
        /// <param name="deviceName">The device name to look up.</param>
        /// <param name="version">The current version of the device.</param>
        /// <param name="deviceVersion">Returns the device version container matching this device.</param>
        /// <param name="deviceAddress">The IP address of the device (only used to include it with possible exceptions).</param>
        /// <returns>The OID lookup table for the specified device name and version.</returns>
        protected IDeviceSpecificOidLookup ObtainOidTable(string deviceName, SemanticVersion version, out DeviceVersion deviceVersion, IpAddress deviceAddress)
        {
            using (var database = DeviceDatabaseProvider.Instance.DeviceDatabase)
            {
                int foundDeviceId = -1;
                if (!database.TryFindDeviceId(deviceName, out foundDeviceId))
                {
                    var exception = new HamnetSnmpException($"Device name '{deviceName}' cannot be found in device database", deviceAddress?.ToString());
                    log.Error(exception.Message);
                    this.CollectException("No OID lookup for device name", exception);
                    throw exception;
                }

                deviceVersion = null;
                if (!database.TryFindDeviceVersionId(foundDeviceId, version, out deviceVersion))
                {
                    var exception = new HamnetSnmpException($"Version '{version}' of device named '{deviceName}' (ID {foundDeviceId}) cannot be matched to any version range of device database", deviceAddress?.ToString());
                    log.Error(exception.Message);
                    this.CollectException("No OID lookup for device version", exception);
                    throw exception;
                }

                string foundOidMappingIds = string.Empty;
                if (!database.TryFindOidLookupId(deviceVersion.Id, out foundOidMappingIds))
                {
                    var exception = new HamnetSnmpException($"Version '{version}' of device named '{deviceName}' (ID {foundDeviceId}, version ID {deviceVersion.Id}) cannot be matched to any OID mapping ID of device database", deviceAddress?.ToString());
                    log.Error(exception.Message);
                    this.CollectException("No OID mapping for device version", exception);
                    throw exception;
                }

                // need to convert the string containing a comma-separated list of OID lookup tables IDs into single, integer table IDs
                // Example: There are two lookups given in order "3,1" in the foundOidMappingIds string.
                //          If a RetrievableValuesEnum has a value in lookup of ID 3 that value shall be used. Otherwise the value of lookup #1.
                string[] splitOidMappingIds = foundOidMappingIds.Split(new char[] { ',', ';', ':', ' ' }, StringSplitOptions.RemoveEmptyEntries);
                List <IDeviceSpecificOidLookup> orderedOidLookupsList = new List <IDeviceSpecificOidLookup>(splitOidMappingIds.Length);
                foreach (var sid in splitOidMappingIds)
                {
                    int intId;
                    if (!int.TryParse(sid, out intId))
                    {
                        log.Warn($"OID mapping table ID '{sid}' as found for device '{deviceName}' v '{version}' (version ID {deviceVersion.Id}, mapping IDs '{foundOidMappingIds}') is not an integer value and will be ignored");
                        continue;
                    }

                    IDeviceSpecificOidLookup foundLookup = null;
                    if (!database.TryFindDeviceSpecificOidLookup(intId, deviceVersion.MaximumSupportedSnmpVersion.ToSnmpVersion(), out foundLookup))
                    {
                        var exception = new HamnetSnmpException($"Version '{version}' of device named '{deviceName}': Cannot find OID mapping ID table of ID {intId} in device database", deviceAddress?.ToString());
                        log.Error(exception.Message);
                        this.CollectException("No OID mapping for mapping ID", exception);
                        throw exception;
                    }

                    orderedOidLookupsList.Add(foundLookup);
                }

                return(new DeviceSpecificMultiLayerOidLookupProxy(orderedOidLookupsList));
            }
        }