This example shows how to use 51Degrees device detection to process
a file containing many User-Agents.
This example requires a local data file. The free 'Lite' data file can be downloaded with the
scripts in the data GitHub repository, which
this repository includes at cxx/data. Fetch the submodules by running
git submodule update --init --recursive, then run
sh cxx/data/get-data-files.sh 51Degrees-LiteV4.1.hash from the repository root,
which saves the file as cxx/data/device-detection/51Degrees-LiteV4.1.hash.
The Lite data file is only used for illustration, and has limited accuracy and capabilities.
The Enterprise data file has every property.
Contact us about a copy.
package fiftyone.devicedetection.examples.console;
import fiftyone.devicedetection.DeviceDetectionPipelineBuilder;
import fiftyone.devicedetection.examples.shared.DataFileHelper;
import fiftyone.devicedetection.hash.engine.onpremise.flowelements.DeviceDetectionHashEngine;
import fiftyone.devicedetection.shared.DeviceData;
import fiftyone.pipeline.core.data.FlowData;
import fiftyone.pipeline.core.flowelements.Pipeline;
import fiftyone.pipeline.engines.Constants;
import fiftyone.pipeline.engines.data.AspectPropertyValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import java.io.*;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import static fiftyone.common.testhelpers.LogbackHelper.configureLogback;
import static fiftyone.devicedetection.examples.shared.PropertyHelper.asString;
import static fiftyone.pipeline.util.FileFinder.getFilePath;
public class OfflineProcessing {
static final Logger logger = LoggerFactory.getLogger(OfflineProcessing.class);
public static final String LITE_V_4_1_HASH =
"device-detection/51Degrees-LiteV4.1.hash";
private static final String CONTACT_US = "/contact-us?utm_source=code&utm_medium=example&utm_campaign=51degrees-java&utm_content=console-src-main-java-fiftyone-devicedetection-examples-console-offlineprocessing.java&utm_term=enterprise-data-file";
public static final String HEADER_EVIDENCE_YML =
"device-detection/20000 Evidence Records.yml";
public static void main(String[] args) throws Exception {
configureLogback(getFilePath("logback.xml"));
File evidenceFile = DataFileHelper.findDataFile(HEADER_EVIDENCE_YML);
run(LITE_V_4_1_HASH, Files.newInputStream(evidenceFile.toPath()), System.out);
}
@SuppressWarnings("unchecked")
public static void run(String dataFile, InputStream is, OutputStream os)
throws Exception {
String detectionFile;
try {
detectionFile =
DataFileHelper.findDataFile(dataFile).getAbsolutePath();
} catch (Exception e) {
DataFileHelper.cantFindDataFile(dataFile);
throw e;
}
DumperOptions dumperOptions = new DumperOptions();
dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
dumperOptions.setDefaultScalarStyle(DumperOptions.ScalarStyle.PLAIN);
dumperOptions.setSplitLines(false);
Yaml yaml = new Yaml(dumperOptions);
Iterator<Object> evidenceIterator = yaml.loadAll(is).iterator();
logger.info("Constructing pipeline with on-premise hash " +
"engine from file " + dataFile);
try (Pipeline
pipeline =
new DeviceDetectionPipelineBuilder()
.useOnPremise(detectionFile, false)
.setShareUsage(false)
.setAutoUpdate(false)
.setPerformanceProfile(Constants.PerformanceProfiles.LowMemory)
.build()) {
DeviceDetectionHashEngine engine =
pipeline.getElement(DeviceDetectionHashEngine.class);
logger.info("Device data file was created {}", engine.getDataFilePublishedDate());
try (Writer writer = new OutputStreamWriter(os)) {
int count = 0;
boolean needsEnterprise = false;
while (evidenceIterator.hasNext() && count < 20) {
try (FlowData flowData =
pipeline.createFlowData()) {
flowData.addEvidence(
filterEvidence((Map<String, String>) evidenceIterator.next(),
"header."));
flowData.process();
DeviceData device = flowData.get(DeviceData.class);
Map<String, ? super Object> resultMap = new HashMap<>();
resultMap.put("device.ismobile", asString(device.getIsMobile()));
resultMap.put("device.platformname", asString(device.getPlatformName()));
resultMap.put("device.platformversion", asString(device.getPlatformVersion()));
needsEnterprise |= putEnterpriseValue(resultMap,
"device.hardwarevendor", engine, "HardwareVendor",
device::getHardwareVendor);
needsEnterprise |= putEnterpriseValue(resultMap,
"device.hardwarename", engine, "HardwareName",
device::getHardwareName);
needsEnterprise |= putEnterpriseValue(resultMap,
"device.devicetype", engine, "DeviceType",
device::getDeviceType);
writer.write("---\n");
yaml.dump(flowData.getEvidence().asKeyMap(), writer);
yaml.dump(resultMap, writer);
writer.flush();
}
count++;
}
if (needsEnterprise) {
writer.write("# Some of these properties need the " +
"Enterprise data file. Contact us for a copy at " +
CONTACT_US + "\n");
}
writer.write("...\n");
writer.flush();
logger.info("Finished processing {} records", count);
}
}
}
private static boolean putEnterpriseValue(Map<String, ? super Object> resultMap,
String key,
DeviceDetectionHashEngine engine,
String property,
Supplier<AspectPropertyValue<?>> value) {
if (DataFileHelper.hasProperty(engine, property)) {
resultMap.put(key, asString(value.get()));
return false;
}
resultMap.put(key, DataFileHelper.NEEDS_ENTERPRISE);
return true;
}
@SuppressWarnings("SameParameterValue")
private static Map<String, String> filterEvidence(Map<String, String> evidence, String prefix) {
return evidence.entrySet()
.stream()
.filter(e -> e.getKey().startsWith(prefix))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
@SuppressWarnings({"SameParameterValue", "unused"})
private static Map<String, Object> getPopulatedProperties(DeviceData data, String prefix) {
return data.asKeyMap().entrySet()
.stream()
.filter(e -> ((AspectPropertyValue<?>) e.getValue()).hasValue())
.collect(Collectors.toMap(e -> prefix + e.getKey(),
e -> ((AspectPropertyValue<?>)e.getValue()).getValue()));
}
}
static void run(String dataFile, InputStream is, OutputStream os)
Process a YAML representation of evidence - and create a YAML output containing the processed evidenc...
Definition OfflineProcessing.java:106