package org.rakam.collection;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.google.common.collect.ImmutableMultimap;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericRecord;
import org.rakam.server.http.annotations.ApiParam;
import java.util.List;
import java.util.Map;
@JsonPropertyOrder({"project", "collection", "api", "properties"})
public class Event
{
@JsonIgnore
private final String project;
private final String collection;
@JsonIgnore
private List<SchemaField> schema;
@JsonInclude(JsonInclude.Include.NON_NULL)
private EventContext api;
private GenericRecord properties;
@JsonCreator
public Event(@ApiParam(value = "collection", description = "The collection of event (pageview, touch, click etc.)") String collection,
@ApiParam("api") EventContext api,
@ApiParam(value = "properties", description = "The properties of the event") GenericRecord properties)
{
this(null, collection, api, null, properties);
}
public Event(String project,
String collection,
EventContext api,
List<SchemaField> schema,
GenericRecord properties)
{
this.project = project;
this.collection = collection;
this.properties = properties;
this.schema = schema;
this.api = api;
}
public String project()
{
return project;
}
@JsonProperty
public String collection()
{
return collection;
}
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_NULL)
public EventContext api()
{
return api;
}
@JsonProperty
public GenericRecord properties()
{
return properties;
}
public List<SchemaField> schema()
{
return schema;
}
public <T> T getAttribute(String attr)
{
return (T) properties().get(attr);
}
@Override
public String toString()
{
return "Event{" +
"project='" + project + '\'' +
", collection='" + collection + '\'' +
", schema=" + schema +
", api=" + api +
", properties=" + properties +
'}';
}
@Override
public boolean equals(Object o)
{
if (this == o) {
return true;
}
if (!(o instanceof Event)) {
return false;
}
Event event = (Event) o;
if (!project.equals(event.project)) {
return false;
}
if (!collection.equals(event.collection)) {
return false;
}
if (schema != null ? !schema.equals(event.schema) : event.schema != null) {
return false;
}
if (api != null ? !api.equals(event.api) : event.api != null) {
return false;
}
return properties.equals(event.properties);
}
@Override
public int hashCode()
{
int result = project.hashCode();
result = 31 * result + collection.hashCode();
result = 31 * result + (schema != null ? schema.hashCode() : 0);
result = 31 * result + (api != null ? api.hashCode() : 0);
result = 31 * result + properties.hashCode();
return result;
}
// TODO: find a way to make this class immutable
public void properties(GenericData.Record record, List<SchemaField> fields)
{
properties = record;
schema = fields;
}
public static class Library
{
public final String name;
public final String version;
@JsonCreator
public Library(@ApiParam("name") String name, @ApiParam("version") String version)
{
this.name = name;
this.version = version;
}
}
public static class EventContext
{
private static final EventContext EMPTY_CONTEXT = new EventContext(null, null, null, null, null, null);
@JsonProperty("api_key") public final String apiKey;
@JsonProperty(value = "library") public final Library library;
@JsonProperty(value = "api_version") public final String apiVersion;
@JsonProperty(value = "upload_time") public final Long uploadTime;
@JsonProperty(value = "checksum") public final String checksum;
@JsonProperty(value = "uuid") public final String uuid;
@JsonCreator
public EventContext(
@ApiParam(value = "api_key", required = false) String apiKey,
@ApiParam(value = "library", required = false, description = "Optional library information for statistics") Library library,
@ApiParam(value = "api_version", required = false, description = "Optional API version for versioning") String apiVersion,
@ApiParam(value = "upload_time", required = false, description = "Optional client upload time for clock synchronization") Long uploadTime,
@ApiParam(value = "uuid", required = false, description = "Optional UUID for deduplication") String uuid,
@ApiParam(value = "checksum", required = false, description = "Optional checksum for verify the body content") String checksum)
{
this.library = library;
this.apiKey = apiKey;
this.apiVersion = apiVersion;
this.uploadTime = uploadTime;
this.uuid = uuid;
this.checksum = checksum;
}
public static EventContext apiKey(String apiKey)
{
return new EventContext(apiKey, null, null, null, null, null);
}
public static EventContext empty()
{
return EMPTY_CONTEXT;
}
@Override
public String toString()
{
return "EventContext{" +
"apiKey='" + apiKey + '\'' +
", apiVersion='" + apiVersion + '\'' +
", uploadTime=" + uploadTime +
", checksum='" + checksum + '\'' +
'}';
}
@Override
public boolean equals(Object o)
{
if (this == o) {
return true;
}
if (!(o instanceof EventContext)) {
return false;
}
EventContext context = (EventContext) o;
if (apiKey != null ? !apiKey.equals(context.apiKey) : context.apiKey != null) {
return false;
}
if (apiVersion != null ? !apiVersion.equals(context.apiVersion) : context.apiVersion != null) {
return false;
}
if (uploadTime != null ? !uploadTime.equals(context.uploadTime) : context.uploadTime != null) {
return false;
}
return !(checksum != null ? !checksum.equals(context.checksum) : context.checksum != null);
}
@Override
public int hashCode()
{
int result = apiKey != null ? apiKey.hashCode() : 0;
result = 31 * result + (apiVersion != null ? apiVersion.hashCode() : 0);
result = 31 * result + (uploadTime != null ? uploadTime.hashCode() : 0);
result = 31 * result + (checksum != null ? checksum.hashCode() : 0);
return result;
}
}
}