package eu.toolchain.ffwd; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.RequiredArgsConstructor; import com.spotify.ffwd.protocol0.Protocol0; import com.spotify.ffwd.protocol0.Protocol0.Attribute; import com.spotify.ffwd.protocol0.Protocol0.Metric.Builder; @RequiredArgsConstructor @EqualsAndHashCode(of = { "has", "proc", "time", "key", "value", "host", "tags", "attributes" }) public class Metric { private final List<String> EMPTY_TAGS = new ArrayList<String>(); private final Map<String, String> EMPTY_ATTRIBUTES = new HashMap<String, String>(); public static final long PROC = 1 << 0; public static final long TIME = 1 << 1; public static final long KEY = 1 << 2; public static final long VALUE = 1 << 3; public static final long HOST = 1 << 4; public static final long TAGS = 1 << 5; public static final long ATTRIBUTES = 1 << 6; private final long has; @Getter private final String proc; @Getter private final long time; @Getter private final String key; @Getter private final double value; @Getter private final String host; @Getter private final List<String> tags; @Getter private final Map<String, String> attributes; public Metric() { this.has = 0; this.proc = null; this.time = 0; this.key = null; this.value = 0; this.host = null; this.tags = EMPTY_TAGS; this.attributes = EMPTY_ATTRIBUTES; } private boolean test(long n) { return (has & n) != 0; } private long set(long n) { return has | n; } public Metric proc(String proc) { return new Metric(set(PROC), proc, time, key, value, host, tags, attributes); } public Metric time(long time) { return new Metric(set(TIME), proc, time, key, value, host, tags, attributes); } public Metric key(String key) { return new Metric(set(KEY), proc, time, key, value, host, tags, attributes); } public Metric value(double value) { return new Metric(set(VALUE), proc, time, key, value, host, tags, attributes); } public Metric host(String host) { return new Metric(set(HOST), proc, time, key, value, host, tags, attributes); } public Metric tag(String tag) { final List<String> tags = new ArrayList<String>(this.tags); tags.add(tag); return new Metric(set(TAGS), proc, time, key, value, host, tags, attributes); } public Metric tags(List<String> tags) { return new Metric(set(TAGS), proc, time, key, value, host, new ArrayList<String>(tags), attributes); } public Metric attribute(String k, String v) { final Map<String, String> attributes = new HashMap<String, String>( this.attributes); attributes.put(k, v); return new Metric(set(ATTRIBUTES), proc, time, key, value, host, tags, attributes); } public Metric attributes(Map<String, String> attributes) { return new Metric(set(ATTRIBUTES), proc, time, key, value, host, tags, new HashMap<String, String>(attributes)); } public byte[] serialize() { final Protocol0.Metric.Builder builder = Protocol0.Metric.newBuilder(); if (test(PROC)) builder.setProc(proc); if (test(TIME)) builder.setTime(time); if (test(KEY)) builder.setKey(key); if (test(VALUE)) builder.setValue(value); if (test(HOST)) builder.setHost(host); if (test(TAGS)) { for (final String tag : tags) { builder.addTags(tag); } } if (test(ATTRIBUTES)) { for (final Map.Entry<String, String> entry : attributes.entrySet()) { if (entry.getKey() == null) continue; final Attribute.Builder attributeBuilder = Protocol0.Attribute.newBuilder().setKey(entry.getKey()); if (entry.getValue() != null) attributeBuilder.setValue(entry.getValue()); builder.addAttributes(attributeBuilder.build()); } } final Protocol0.Metric m = builder.build(); return Protocol0.Message.newBuilder().setMetric(m).build() .toByteArray(); } }