io.bitsensor.lib.util.DatapointUtils Maven / Gradle / Ivy
package io.bitsensor.lib.util;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.bitsensor.lib.entity.proto.*;
import io.bitsensor.lib.entity.proto.Error;
import io.bitsensor.proto.shaded.com.google.protobuf.MessageOrBuilder;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.hash.MurmurHash3;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import static io.bitsensor.lib.entity.Constants.Detection.DETECTION_HASH_FIELDS;
import static io.bitsensor.lib.entity.Constants.Detection.DETECTION_RULE_FIELDS;
import static io.bitsensor.lib.entity.util.ProtoUtils.proto2JsonWithoutHashes;
import static java.util.Arrays.asList;
public class DatapointUtils {
/**
* Generate hash and rule hash for any error, detection found in a datapoint.
*/
public static void generateHashes(Datapoint.Builder datapoint) {
for (ErrorOrBuilder errorOrBuilder : datapoint.getErrorsBuilderList()) {
DatapointUtils.generateHash(errorOrBuilder);
}
for (DetectionOrBuilder detectionOrBuilder : datapoint.getDetectionsBuilderList()) {
DatapointUtils.generateHash(detectionOrBuilder);
DatapointUtils.generateRuleHash(detectionOrBuilder);
}
}
/**
* Returns instance of {@code ErrorOrBuilder} with generated hash.
*/
@SuppressWarnings("unchecked")
public static T generateHash(T object) {
if (object instanceof Error.Builder) {
return (T) ((Error.Builder) object).setHash(createHash(object));
} else if (object instanceof Error) {
return (T) generateHash(((Error) object).toBuilder()).build();
}
return object;
}
/**
* Returns instance of {@code DetectionOrBuilder} with generated hash.
*/
@SuppressWarnings("unchecked")
public static T generateHash(T object) {
if (object instanceof Detection.Builder) {
return (T) ((Detection.Builder) object).setHash(createHash(object, DETECTION_HASH_FIELDS));
} else if (object instanceof Detection) {
return (T) generateHash(((Detection) object).toBuilder()).build();
}
return object;
}
/**
* Returns instance of {@code DetectionOrBuilder} with generated rule hash.
*/
@SuppressWarnings("unchecked")
public static T generateRuleHash(T object) {
if (object.getRuleHash() != 0) {
return object;
}
if (object instanceof Detection.Builder) {
return (T) ((Detection.Builder) object).setRuleHash(createHash(object, DETECTION_RULE_FIELDS));
} else if (object instanceof Detection) {
return (T) generateRuleHash(((Detection) object).toBuilder()).build();
}
return object;
}
/**
* Returns hash for given message for fields in the {@code onlyFields} array or for all fields if the array is
* empty.
*/
private static long createHash(MessageOrBuilder message, String... onlyFields) {
JsonObject json = proto2JsonWithoutHashes(message);
final List onlyFieldsList = asList(onlyFields);
if (onlyFields.length > 0) {
final Iterator> each = json.entrySet().iterator();
while (each.hasNext()) {
if (!onlyFieldsList.contains(each.next().getKey())) {
each.remove();
}
}
}
final BytesRef bytes = new BytesRef(json.toString());
return MurmurHash3.hash128(bytes.bytes, bytes.offset, bytes.length, 0, new MurmurHash3.Hash128()).h1;
}
}