Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,6 @@ For tests and examples that require a license key add the following option:
## Projects

- **ip-intelligence** - Main package providing all IP Intelligence capabilities including both cloud and on-premise engines.
- **ip-intelligence.engine.on-premise** - On-premise detection engine using local data files for IP intelligence analysis.
- **ip-intelligence.cloud** - Cloud-based detection service for IP intelligence (coming soon).
- **ip-intelligence.engine.on-premise** - On-premise engine using local data files for IP intelligence analysis.
- **ip-intelligence.cloud** - Cloud-based IP intelligence engine (coming soon).
- **ip-intelligence.shared** - Shared classes and utilities used across all IP intelligence engines.
6 changes: 3 additions & 3 deletions ci/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ The following secrets are required for publishing releases (this should only be
* `CODE_SIGNING_CERT_PASSWORD` - Password for the `CODE_SIGNING_CERT`

The following secrets are optional:
* `DEVICE_DETECTION_URL` - URL for downloading the enterprise TAC hash file
* Default: `https://distributor.51degrees.com/api/v2/download?LicenseKeys=DEVICE_DETECTION_KEY&Type=HashV41&Download=True&Product=V4TAC`
* `IPI_DATA_FILE_URL` - URL for downloading the enterprise IPI data file
* Default: the 51Degrees Distributor URL using the `DEVICE_DETECTION_KEY` license key

## Integration Tests

Expand All @@ -48,7 +48,7 @@ graph TD
It performs the following steps:

1. Clone Examples Repo: Clone the "ip-intelligence-java-examples" repository into the common-ci directory.
3. Set up test files: Move the 51Degrees-EnterpriseIpiV41.ipi file to the ip-intelligence-java-examples/ip-intelligence-data directory and download Evidence and User-Agent files into ip-intelligence-data directory.
3. Set up test files: Move the 51Degrees-EnterpriseIpiV41.ipi file to the ip-intelligence-java-examples/ip-intelligence-data directory and download Evidence files into ip-intelligence-data directory.
4. Enter ip-intelligence-examples directory: Changes the current working directory to the ip-intelligence-java-examples folder.
5. Set package dependency version: Sets the version of the ip-intelligence package dependency for the examples to the specified Version parameter. This will be the version installed in the local repository found in the .m2 folder.
6. Test Examples: Runs the Maven clean test command, passing the TestResourceKey, SuperResourceKey, and LicenseKey as parameters.
Expand Down
4 changes: 3 additions & 1 deletion ci/fetch-assets.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ $ipIntelligenceData = "$PSSCriptRoot/../ip-intelligence.engine.on-premise/src/ma

./steps/fetch-assets.ps1 -IpIntelligenceUrl $IpIntelligenceUrl -Assets '51Degrees-EnterpriseIpiV41.ipi', '51Degrees-LiteIpiV41.ipi'
New-Item -ItemType SymbolicLink -Force -Target "$PWD/assets/51Degrees-EnterpriseIpiV41.ipi" -Path "$ipIntelligenceData/51Degrees-EnterpriseIpiV41.ipi"
New-Item -ItemType SymbolicLink -Force -Target "$PWD/assets/51Degrees-LiteIpiV41.ipi" -Path "$ipIntelligenceData/51Degrees-LiteIpiV41.ipi"
# The asset is fetched under the blob name, but FileUtils and the data repo
# scripts use the unpacked name 51Degrees-LiteV41.ipi, so link it as that.
New-Item -ItemType SymbolicLink -Force -Target "$PWD/assets/51Degrees-LiteIpiV41.ipi" -Path "$ipIntelligenceData/51Degrees-LiteV41.ipi"

Write-Host "Assets hashes:"
Get-FileHash -Algorithm MD5 -Path assets/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@

/**
* Encapsulates a list of {@link IPIntelligenceData} instances which can be returned
* by the 51Degrees Cloud service when certain evidence is provided (e.g. TAC)
* by the 51Degrees Cloud service when evidence matching multiple profiles is
* provided.
*/
public class MultiIPIDataCloud
extends AspectDataBase
implements MultiProfileData<IPIntelligenceData> {
private static final String DEVICE_LIST_KEY = "profiles";
private static final String PROFILE_LIST_KEY = "profiles";

/**
* Constructs a new instance with a non-thread-safe, case-insensitive
Expand All @@ -58,7 +59,7 @@ public MultiIPIDataCloud(
FlowData flowData,
AspectEngine<? extends AspectData, ? extends AspectPropertyMetaData> engine) {
super(logger, flowData, engine);
this.put(DEVICE_LIST_KEY, new ArrayList<IPIntelligenceData>());
this.put(PROFILE_LIST_KEY, new ArrayList<IPIntelligenceData>());
}

/**
Expand All @@ -77,25 +78,25 @@ public MultiIPIDataCloud(
AspectEngine<? extends AspectData, ? extends AspectPropertyMetaData> engine,
MissingPropertyService missingPropertyService) {
super(logger, flowData, engine, missingPropertyService);
this.put(DEVICE_LIST_KEY, new ArrayList<IPIntelligenceData>());
this.put(PROFILE_LIST_KEY, new ArrayList<IPIntelligenceData>());
}

@Override
public List<IPIntelligenceData> getProfiles() {
return getDeviceList();
return getProfileList();
}

@Override
public void addProfile(IPIntelligenceData profile) {
getDeviceList().add(profile);
getProfileList().add(profile);
}

/**
* Internal method to get the list of devices form the underlying data.
* @return the list of devices form the underlying data.
* Internal method to get the list of profiles from the underlying data.
* @return the list of profiles from the underlying data.
*/
@SuppressWarnings("unchecked")
private List<IPIntelligenceData> getDeviceList() {
return (List<IPIntelligenceData>)this.get(DEVICE_LIST_KEY);
private List<IPIntelligenceData> getProfileList() {
return (List<IPIntelligenceData>)this.get(PROFILE_LIST_KEY);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@

/**
* Engine that takes the JSON response from the {@link CloudRequestEngine} and
* uses it populate a {@link MultiIPIDataCloud} instance for easier consumption.
* uses it to populate a {@link MultiIPIDataCloud} instance for easier
* consumption.
* @see <a href="https://github.com/51Degrees/specifications/blob/main/ip-intelligence-specification/pipeline-elements/hardware-profile-lookup-cloud.md">Specification</a>
*/
public class HardwareProfileCloudEngine
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@

/**
* Engine that takes the JSON response from the {@link CloudRequestEngine} and
* uses it populate a {@link IPIntelligenceDataCloud} instance for easier consumption.
* uses it to populate a {@link IPIntelligenceDataCloud} instance for easier
* consumption.
* @see <a href="https://github.com/51Degrees/specifications/blob/main/ip-intelligence-specification/pipeline-elements/ip-intelligence-cloud.md">Specification</a>
*/
public class IPIntelligenceCloudEngine
Expand All @@ -62,13 +63,13 @@ public class IPIntelligenceCloudEngine
/**
* Construct a new instance of the {@link IPIntelligenceCloudEngine}.
* @param logger logger instance to use for logging
* @param IPIDataFactory the factory to use when creating a
* @param ipiDataFactory the factory to use when creating a
* {@link IPIntelligenceDataCloud} instance
*/
public IPIntelligenceCloudEngine(
Logger logger,
ElementDataFactory<IPIntelligenceDataCloud> IPIDataFactory) {
super(logger, IPIDataFactory);
ElementDataFactory<IPIntelligenceDataCloud> ipiDataFactory) {
super(logger, ipiDataFactory);
this.cloudRequestEngine = null;
}

Expand Down Expand Up @@ -111,71 +112,71 @@ protected void processEngine(FlowData data, IPIntelligenceDataCloud aspectData)

// Extract data from json to the aspectData instance.
JSONObject jsonObj = new JSONObject(json);
JSONObject deviceObj = jsonObj.getJSONObject("ip-intelligence");
JSONObject ipiObj = jsonObj.getJSONObject("ip-intelligence");

Map<String, Object> deviceMap =
Map<String, Object> propertyMap =
new TreeMap<>(String.CASE_INSENSITIVE_ORDER);

for (AspectPropertyMetaData property : getProperties()) {
String type = property.getType().getSimpleName();
switch(type) {
case ("List"):
deviceMap.put(
propertyMap.put(
property.getName(),
getListAspectPropertyValue(deviceObj, property));
getListAspectPropertyValue(ipiObj, property));
break;
case ("JavaScript"):
deviceMap.put(
propertyMap.put(
property.getName(),
getJavaScriptAspectPropertyValue(deviceObj, property));
getJavaScriptAspectPropertyValue(ipiObj, property));
break;
case ("String"):
deviceMap.put(
propertyMap.put(
property.getName(),
getStringAspectPropertyValue(deviceObj, property));
getStringAspectPropertyValue(ipiObj, property));
break;
case ("boolean"):
deviceMap.put(
propertyMap.put(
property.getName(),
getBooleanAspectPropertyValue(deviceObj, property));
getBooleanAspectPropertyValue(ipiObj, property));
break;
case ("int"):
deviceMap.put(
propertyMap.put(
property.getName(),
getIntegerAspectPropertyValue(deviceObj, property));
getIntegerAspectPropertyValue(ipiObj, property));
break;
case ("double"):
deviceMap.put(
propertyMap.put(
property.getName(),
getDoubleAspectPropertyValue(deviceObj, property));
getDoubleAspectPropertyValue(ipiObj, property));
break;
default:
deviceMap.put(
propertyMap.put(
property.getName(),
getStringAspectPropertyValue(deviceObj, property));
getStringAspectPropertyValue(ipiObj, property));
break;
}
}

// Add no value messages for any properties which have not yet been
// populated.
for (String key : deviceObj.keySet()) {
for (String key : ipiObj.keySet()) {
if (key.endsWith("nullreason")) {
String actualKey = key
.replace("nullreason", "");
if (deviceMap.containsKey(actualKey) == false) {
if (propertyMap.containsKey(actualKey) == false) {
AspectPropertyValue<?> nullValue =
new AspectPropertyValueDefault<Object>();
nullValue.setNoValueMessage(
deviceObj.optString(key, "Unknown"));
deviceMap.put(
ipiObj.optString(key, "Unknown"));
propertyMap.put(
actualKey,
nullValue);
}
}
}

aspectData.populateFromMap(deviceMap);
aspectData.populateFromMap(propertyMap);
}
}

Expand Down Expand Up @@ -237,79 +238,79 @@ private boolean loadAspectProperties(CloudRequestEngine engine) {
/**
* Get the integer representation of a value from the cloud engine's JSON
* response, and wrap it in an {@link AspectPropertyValue}.
* @param deviceObj to get the value from
* @param ipiObj to get the value from
* @param property to get the value of
* @return {@link AspectPropertyValue} with a parsed value, or the reason
* for the value not being present
*/
private AspectPropertyValue<Integer> getIntegerAspectPropertyValue(
JSONObject deviceObj,
JSONObject ipiObj,
AspectPropertyMetaData property) {
String key = property.getName().toLowerCase();
AspectPropertyValue<Integer> intValue = new AspectPropertyValueDefault<>();
if(deviceObj.isNull(key)){
intValue.setNoValueMessage(getNoValueReason(deviceObj, key));
if(ipiObj.isNull(key)){
intValue.setNoValueMessage(getNoValueReason(ipiObj, key));
}
else {
intValue.setValue(deviceObj.getInt(key));
intValue.setValue(ipiObj.getInt(key));
}
return intValue;
}

private AspectPropertyValue<Double> getDoubleAspectPropertyValue(JSONObject deviceObj, AspectPropertyMetaData property) {
private AspectPropertyValue<Double> getDoubleAspectPropertyValue(JSONObject ipiObj, AspectPropertyMetaData property) {
String key = property.getName().toLowerCase();
AspectPropertyValue<Double> doubleValue = new AspectPropertyValueDefault<>();
if(deviceObj.isNull(key)){
doubleValue.setNoValueMessage(getNoValueReason(deviceObj, key));
if(ipiObj.isNull(key)){
doubleValue.setNoValueMessage(getNoValueReason(ipiObj, key));
}
else {
doubleValue.setValue(deviceObj.getDouble(key));
doubleValue.setValue(ipiObj.getDouble(key));
}
return doubleValue;
}

/**
* Get the boolean representation of a value from the cloud engine's JSON
* response, and wrap it in an {@link AspectPropertyValue}.
* @param deviceObj to get the value from
* @param ipiObj to get the value from
* @param property to get the value of
* @return {@link AspectPropertyValue} with a parsed value, or the reason
* for the value not being present
*/
private AspectPropertyValue<Boolean> getBooleanAspectPropertyValue(
JSONObject deviceObj,
JSONObject ipiObj,
AspectPropertyMetaData property) {
String key = property.getName().toLowerCase();
AspectPropertyValue<Boolean> booleanValue = new AspectPropertyValueDefault<>();
if(deviceObj.isNull(key)){
booleanValue.setNoValueMessage(getNoValueReason(deviceObj, key));
if(ipiObj.isNull(key)){
booleanValue.setNoValueMessage(getNoValueReason(ipiObj, key));
}
else {
booleanValue.setValue(deviceObj.getBoolean(key));
booleanValue.setValue(ipiObj.getBoolean(key));
}
return booleanValue;
}

/**
* Get the string list representation of a value from the cloud engine's
* JSON response, and wrap it in an {@link AspectPropertyValue}.
* @param deviceObj to get the value from
* @param ipiObj to get the value from
* @param property to get the value of
* @return {@link AspectPropertyValue} with a parsed value, or the reason
* for the value not being present
*/
private AspectPropertyValue<List<String>> getListAspectPropertyValue(
JSONObject deviceObj,
JSONObject ipiObj,
AspectPropertyMetaData property){
String key = property.getName().toLowerCase();
AspectPropertyValue<List<String>> listValue = new AspectPropertyValueDefault<>();
if(deviceObj.isNull(key))
if(ipiObj.isNull(key))
{
listValue.setNoValueMessage(getNoValueReason(deviceObj, key));
listValue.setNoValueMessage(getNoValueReason(ipiObj, key));
}
else
{
JSONArray jsonArray = deviceObj.getJSONArray(key);
JSONArray jsonArray = ipiObj.getJSONArray(key);
List<String> strings = new ArrayList<>(jsonArray.length());
for (Object object : jsonArray.toList()) {
strings.add(Objects.toString(object, null));
Expand All @@ -322,55 +323,55 @@ private AspectPropertyValue<List<String>> getListAspectPropertyValue(
/**
* Get the JavaScript representation of a value from the cloud engine's JSON
* response, and wrap it in an {@link AspectPropertyValue}.
* @param deviceObj to get the value from
* @param ipiObj to get the value from
* @param property to get the value of
* @return {@link AspectPropertyValue} with a parsed value, or the reason
* for the value not being present
*/
private AspectPropertyValue<JavaScript> getJavaScriptAspectPropertyValue(
JSONObject deviceObj,
JSONObject ipiObj,
AspectPropertyMetaData property){
String key = property.getName().toLowerCase();
AspectPropertyValue<JavaScript> jsValue = new AspectPropertyValueDefault<>();
if(deviceObj.isNull(key)){
jsValue.setNoValueMessage(getNoValueReason(deviceObj, key));
if(ipiObj.isNull(key)){
jsValue.setNoValueMessage(getNoValueReason(ipiObj, key));
} else {
jsValue.setValue(new JavaScript(deviceObj.getString(key)));
jsValue.setValue(new JavaScript(ipiObj.getString(key)));
}
return jsValue;
}

/**
* Get the string representation of a value from the cloud engine's JSON
* response, and wrap it in an {@link AspectPropertyValue}.
* @param deviceObj to get the value from
* @param ipiObj to get the value from
* @param property to get the value of
* @return {@link AspectPropertyValue} with a parsed value, or the reason
* for the value not being present
*/
private AspectPropertyValue<String> getStringAspectPropertyValue(
JSONObject deviceObj,
JSONObject ipiObj,
AspectPropertyMetaData property){
String key = property.getName().toLowerCase();
AspectPropertyValue<String> stringValue = new AspectPropertyValueDefault<>();
if(deviceObj.isNull(key)){
stringValue.setNoValueMessage(getNoValueReason(deviceObj, key));
if(ipiObj.isNull(key)){
stringValue.setNoValueMessage(getNoValueReason(ipiObj, key));
}
else {
stringValue.setValue(deviceObj.getString(key));
stringValue.setValue(ipiObj.getString(key));
}
return stringValue;
}

/**
* Get the reason for the value of a property not being present in the cloud
* engine's JSON response.
* @param deviceObj to get the null reason from
* @param ipiObj to get the null reason from
* @param key to get the null reason from
* @return the reason for the missing property
*/
private String getNoValueReason(JSONObject deviceObj, String key){
Object reason = tryToGet(deviceObj, key + "nullreason");
private String getNoValueReason(JSONObject ipiObj, String key){
Object reason = tryToGet(ipiObj, key + "nullreason");
return reason == null ? null : reason.toString();
}

Expand Down
Loading
Loading