/// <summary> /// Build and return a pipeline that can perform device detection. /// </summary> /// <returns></returns> public override IPipeline Build() { IAspectEngine deviceDetectionEngine = null; // Create the device detection engine based on the configuration. switch (_algorithm) { case DeviceDetectionAlgorithm.Hash: var hashBuilder = new DeviceDetectionHashEngineBuilder(LoggerFactory, _dataUpdateService); deviceDetectionEngine = ConfigureAndBuild(hashBuilder); break; default: throw new PipelineConfigurationException( $"Unrecognized algorithm '{_algorithm}'."); } if (deviceDetectionEngine != null) { // Add the share usage element to the list if enabled if (_shareUsageEnabled) { FlowElements.Add(new ShareUsageBuilder(LoggerFactory, _httpClient).Build()); } // Add the device detection engine to the list FlowElements.Add(deviceDetectionEngine); } else { throw new PipelineException(Messages.ExceptionErrorOnStartup); } // Create and return the pipeline return(base.Build()); }
public WrapperHash(FileInfo dataFile, PerformanceProfiles profile) { var builder = new DeviceDetectionHashEngineBuilder(_logger, null) .SetPerformanceProfile(profile) .SetUpdateMatchedUserAgent(true) .SetAutoUpdate(false) .SetDataFileSystemWatcher(false); Engine = builder .Build(dataFile.FullName, false); Pipeline = new PipelineBuilder(_logger) .AddFlowElement(Engine) .Build(); }
public void BadData_VersionNumber_File() { try { _ = new DeviceDetectionHashEngineBuilder(LoggerFactory) .SetAutoUpdate(false) .SetDataFileSystemWatcher(false) .SetDataUpdateOnStartup(false) .SetDataUpdateLicenseKey(null) .Build(BadVersionDataFile, false); Assert.Fail("No exception was thrown"); } catch (Exception e) { Assert.AreEqual( "The data is an unsupported version. Check you have the latest data and API.", e.Message); } }
public void BadData_SmallData_File() { try { _ = new DeviceDetectionHashEngineBuilder(LoggerFactory) .SetAutoUpdate(false) .SetDataFileSystemWatcher(false) .SetDataUpdateOnStartup(false) .SetDataUpdateLicenseKey(null) .Build(SmallDataFile, false); Assert.Fail("No exception was thrown"); } catch (Exception e) { Assert.AreEqual( "The data was not in the correct format. Check the data file is uncompressed.", e.Message); } }
public void Init() { _builder = new DeviceDetectionHashEngineBuilder(new LoggerFactory()); // Setup values returned by IMetaDataSwigWrapper var properties = new Mock <IPropertyCollectionSwigWrapper>(); properties.Setup(c => c.GetEnumerator()).Returns(new List <IFiftyOneAspectPropertyMetaData>().GetEnumerator()); var components = new Mock <IComponentCollectionSwigWrapper>(); components.Setup(c => c.GetEnumerator()).Returns(new List <IComponentMetaData>().GetEnumerator()); // Setup values returned by IEngineSwigWrapper var swigMetaData = new Mock <IMetaDataSwigWrapper>(); swigMetaData.Setup(d => d.getProperties(It.IsAny <DeviceDetectionHashEngine>())).Returns(properties.Object); swigMetaData.Setup(d => d.getComponents(It.IsAny <DeviceDetectionHashEngine>())).Returns(components.Object); var date = new Mock <IDateSwigWrapper>(); date.Setup(d => d.getYear()).Returns(2019); date.Setup(d => d.getMonth()).Returns(12); date.Setup(d => d.getDay()).Returns(10); // Setup swig engine wrapper var swigEngine = new Mock <IEngineSwigWrapper>(); swigEngine.Setup(e => e.getKeys()).Returns(new VectorStringSwig()); swigEngine.Setup(e => e.getMetaData()).Returns(swigMetaData.Object); swigEngine.Setup(e => e.getPublishedTime()).Returns(date.Object); swigEngine.Setup(e => e.getUpdateAvailableTime()).Returns(date.Object); // Setup factory to create our mock engine rather than a real one var factory = new SwigFactory(); factory.EngineFromData = (a, b, c, d) => { return(swigEngine.Object); }; // Assign the factory to the builder _builder.SwigFactory = factory; _builder.SetAutoUpdate(false) .SetDataFileSystemWatcher(false); }
public void BadData_VersionNumber_Memory() { try { var data = File.ReadAllBytes(BadVersionDataFile); using (var stream = new MemoryStream(data)) { _ = new DeviceDetectionHashEngineBuilder(LoggerFactory) .SetAutoUpdate(false) .SetDataFileSystemWatcher(false) .SetDataUpdateOnStartup(false) .SetDataUpdateLicenseKey(null) .Build(stream); } Assert.Fail("No exception was thrown"); } catch (Exception e) { Assert.AreEqual( "The data is an unsupported version. Check you have the latest data and API.", e.Message); } }
public void BadData_SmallData_Memory() { try { var data = File.ReadAllBytes(SmallDataFile); using (var stream = new MemoryStream(data)) { _ = new DeviceDetectionHashEngineBuilder(LoggerFactory) .SetAutoUpdate(false) .SetDataFileSystemWatcher(false) .SetDataUpdateOnStartup(false) .SetDataUpdateLicenseKey(null) .Build(stream); } Assert.Fail("No exception was thrown"); } catch (Exception e) { Assert.AreEqual( "The data was not in the correct format. Check the data file is uncompressed.", e.Message); } }
public void Run(string originalDataFile, string licenseKey) { // Copy the original data file to another location as we do not // want to preserve the original for other examples. File.Copy(originalDataFile, dataFile, true); FileInfo f = new FileInfo(dataFile); Console.WriteLine($"Using data file at '{f.FullName}'"); DateTime initialPublishedDate = DateTime.MinValue; // Create a temporary Device Detection 'Hash' Engine to check the initial published date of the data file. // There is no need to do this in production, it is for demonstration purposes only. // This also higlights the added simplicity of the Device Detection Pipeline builder. using (var loggerFactory = new LoggerFactory()) { var dataUpdateService = new DataUpdateService(loggerFactory.CreateLogger <DataUpdateService>(), new HttpClient()); using (var temporaryDeviceDetectionEngine = new DeviceDetectionHashEngineBuilder(loggerFactory, dataUpdateService) .Build(dataFile, false)) { // Get the published date of the device data file. Engines can have multiple data files but // for the Device Detection 'Hash' engine we can guarantee there will only be one. initialPublishedDate = temporaryDeviceDetectionEngine.DataFiles.Single().DataPublishedDateTime; } } Console.WriteLine($"Data file published date: {initialPublishedDate}"); Console.Write($"Creating pipeline and updating device data"); CancellationTokenSource cancellationSource = new CancellationTokenSource(); Task.Run(() => { OutputUntilCancelled(".", 1000, cancellationSource.Token); }); // Build a new Pipeline to use an on-premise Hash engine and // configure automatic updates. var pipeline = new DeviceDetectionPipelineBuilder() // Use the On-Premise engine (aka Hash engine) and pass in // the path to the data file, your license key and whether // to use a temporary file. // A license key is required otherwise automatic updates will // remain disabled. .UseOnPremise(dataFile, licenseKey, true) // Enable automatic updates. .SetAutoUpdate(true) // Watch the data file on disk and refresh the engine // as soon as that file is updated. .SetDataFileSystemWatcher(true) // Enable update on startup, the auto update system // will be used to check for an update before the // device detection engine is created. This will block // creation of the pipeline. .SetDataUpdateOnStartUp(true) .Build(); cancellationSource.Cancel(); Console.WriteLine(); // Get the published date of the data file from the Hash engine // after building the pipeline. var updatedPublishedDate = pipeline .GetElement <DeviceDetectionHashEngine>() .DataFiles .Single() .DataPublishedDateTime; if (DateTime.Equals(initialPublishedDate, updatedPublishedDate)) { Console.WriteLine("There was no update available at this time."); } Console.WriteLine($"Data file published date: {updatedPublishedDate}"); }
public void Run(string dataFile, bool test = false) { FileInfo f = new FileInfo(dataFile); Console.WriteLine($"Using data file at '{f.FullName}'"); Console.WriteLine($"This example will use the meta-data exposed " + $"by the device detection engine to display the names and " + $"details of all the properties it can populate."); // Give the user time to to read previous message as this // example prints a lot of information to the console. Skip if // run by a unit test. if (test == false) { Console.WriteLine($"Press any key to continue."); Console.ReadKey(); } // Build a new on-premise Hash engine with the low memory performance profile. using (var ddEngine = new DeviceDetectionHashEngineBuilder( new LoggerFactory()) .SetAutoUpdate(false) .SetDataFileSystemWatcher(false) .SetDataUpdateOnStartup(false) // Prefer low memory profile where all data streamed // from disk on-demand. Experiment with other profiles. //.SetPerformanceProfile(PerformanceProfiles.HighPerformance) .SetPerformanceProfile(PerformanceProfiles.LowMemory) //.SetPerformanceProfile(PerformanceProfiles.Balanced) // Finally build the engine. .Build(dataFile, false)) { // Iterate over all properties in the data file, printing the name, value type, // and description for each one. foreach (var property in ddEngine.Properties) { // Output some details about the property. // Add some formatting to highlight property names. Console.ForegroundColor = ConsoleColor.White; Console.BackgroundColor = ConsoleColor.DarkRed; Console.Write(property.Name); Console.ForegroundColor = ConsoleColor.Gray; Console.BackgroundColor = ConsoleColor.Black; Console.WriteLine($"[Category: {property.Category}]" + $"({property.Type.Name}) - {property.Description}"); // Next, output a list of the possible values this // property can have. // Most properties in the Device Metrics category do // not have defined values so exclude them. if (property.Category != "Device Metrics") { StringBuilder values = new StringBuilder("Possible values: "); foreach (var value in property.Values.Take(20)) { // add value values.Append(TruncateToNl(value.Name)); // add description if exists if (string.IsNullOrEmpty(value.Description) == false) { values.Append($"({value.Description})"); } values.Append(","); } if (property.Values.Count() > 20) { values.Append($" + {property.Values.Count() - 20} more ..."); } Console.WriteLine(values); } } } }