YARN-3551. Consolidate data model change according to the backend implementation (Zhijie Shen via sale)
(cherry picked from commit 557a3950bddc837469244835f5577899080115d8)
This commit is contained in:
parent
8c7b6dd2c7
commit
fc8485d893
|
@ -261,7 +261,7 @@ public class TimelineServicePerformanceV2 extends Configured implements Tool {
|
||||||
// add a metric
|
// add a metric
|
||||||
TimelineMetric metric = new TimelineMetric();
|
TimelineMetric metric = new TimelineMetric();
|
||||||
metric.setId("foo_metric");
|
metric.setId("foo_metric");
|
||||||
metric.setSingleData(123456789L);
|
metric.addValue(System.currentTimeMillis(), 123456789L);
|
||||||
entity.addMetric(metric);
|
entity.addMetric(metric);
|
||||||
// add a config
|
// add a config
|
||||||
entity.addConfig("foo", "bar");
|
entity.addConfig("foo", "bar");
|
||||||
|
|
|
@ -80,7 +80,7 @@ public class TimelineEntity {
|
||||||
private TimelineEntity real;
|
private TimelineEntity real;
|
||||||
private Identifier identifier;
|
private Identifier identifier;
|
||||||
private HashMap<String, Object> info = new HashMap<>();
|
private HashMap<String, Object> info = new HashMap<>();
|
||||||
private HashMap<String, Object> configs = new HashMap<>();
|
private HashMap<String, String> configs = new HashMap<>();
|
||||||
private Set<TimelineMetric> metrics = new HashSet<>();
|
private Set<TimelineMetric> metrics = new HashSet<>();
|
||||||
private Set<TimelineEvent> events = new HashSet<>();
|
private Set<TimelineEvent> events = new HashSet<>();
|
||||||
private HashMap<String, Set<String>> isRelatedToEntities = new HashMap<>();
|
private HashMap<String, Set<String>> isRelatedToEntities = new HashMap<>();
|
||||||
|
@ -213,7 +213,7 @@ public class TimelineEntity {
|
||||||
// required by JAXB
|
// required by JAXB
|
||||||
@InterfaceAudience.Private
|
@InterfaceAudience.Private
|
||||||
@XmlElement(name = "configs")
|
@XmlElement(name = "configs")
|
||||||
public HashMap<String, Object> getConfigsJAXB() {
|
public HashMap<String, String> getConfigsJAXB() {
|
||||||
if (real == null) {
|
if (real == null) {
|
||||||
return configs;
|
return configs;
|
||||||
} else {
|
} else {
|
||||||
|
@ -221,7 +221,7 @@ public class TimelineEntity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> getConfigs() {
|
public Map<String, String> getConfigs() {
|
||||||
if (real == null) {
|
if (real == null) {
|
||||||
return configs;
|
return configs;
|
||||||
} else {
|
} else {
|
||||||
|
@ -229,19 +229,19 @@ public class TimelineEntity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConfigs(Map<String, Object> configs) {
|
public void setConfigs(Map<String, String> configs) {
|
||||||
if (real == null) {
|
if (real == null) {
|
||||||
if (configs != null && !(configs instanceof HashMap)) {
|
if (configs != null && !(configs instanceof HashMap)) {
|
||||||
this.configs = new HashMap<String, Object>(configs);
|
this.configs = new HashMap<String, String>(configs);
|
||||||
} else {
|
} else {
|
||||||
this.configs = (HashMap<String, Object>) configs;
|
this.configs = (HashMap<String, String>) configs;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
real.setConfigs(configs);
|
real.setConfigs(configs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addConfigs(Map<String, Object> configs) {
|
public void addConfigs(Map<String, String> configs) {
|
||||||
if (real == null) {
|
if (real == null) {
|
||||||
this.configs.putAll(configs);
|
this.configs.putAll(configs);
|
||||||
} else {
|
} else {
|
||||||
|
@ -249,7 +249,7 @@ public class TimelineEntity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addConfig(String key, Object value) {
|
public void addConfig(String key, String value) {
|
||||||
if (real == null) {
|
if (real == null) {
|
||||||
configs.put(key, value);
|
configs.put(key, value);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -24,24 +24,47 @@ import javax.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
import java.util.HashMap;
|
import java.util.Comparator;
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
@XmlRootElement(name = "metric")
|
@XmlRootElement(name = "metric")
|
||||||
@XmlAccessorType(XmlAccessType.NONE)
|
@XmlAccessorType(XmlAccessType.NONE)
|
||||||
@InterfaceAudience.Public
|
@InterfaceAudience.Public
|
||||||
@InterfaceStability.Unstable
|
@InterfaceStability.Unstable
|
||||||
public class TimelineMetric {
|
public class TimelineMetric {
|
||||||
|
|
||||||
|
public static enum Type {
|
||||||
|
SINGLE_VALUE,
|
||||||
|
TIME_SERIES
|
||||||
|
}
|
||||||
|
|
||||||
|
private Type type;
|
||||||
private String id;
|
private String id;
|
||||||
private HashMap<String, Object> info = new HashMap<>();
|
private Comparator<Long> reverseComparator = new Comparator<Long>() {
|
||||||
private Object singleData;
|
@Override
|
||||||
private HashMap<Long, Object> timeSeries = new LinkedHashMap<>();
|
public int compare(Long l1, Long l2) {
|
||||||
private long startTime;
|
return -l1.compareTo(l2);
|
||||||
private long endTime;
|
}
|
||||||
|
};
|
||||||
|
private TreeMap<Long, Number> values = new TreeMap<>(reverseComparator);
|
||||||
|
|
||||||
public TimelineMetric() {
|
public TimelineMetric() {
|
||||||
|
this(Type.SINGLE_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimelineMetric(Type type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@XmlElement(name = "type")
|
||||||
|
public Type getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(Type type) {
|
||||||
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@XmlElement(name = "id")
|
@XmlElement(name = "id")
|
||||||
|
@ -55,82 +78,50 @@ public class TimelineMetric {
|
||||||
|
|
||||||
// required by JAXB
|
// required by JAXB
|
||||||
@InterfaceAudience.Private
|
@InterfaceAudience.Private
|
||||||
@XmlElement(name = "info")
|
@XmlElement(name = "values")
|
||||||
public HashMap<String, Object> getInfoJAXB() {
|
public TreeMap<Long, Number> getValuesJAXB() {
|
||||||
return info;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> getInfo() {
|
public Map<Long, Number> getValues() {
|
||||||
return info;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInfo(Map<String, Object> info) {
|
public void setValues(Map<Long, Number> values) {
|
||||||
if (info != null && !(info instanceof HashMap)) {
|
if (type == Type.SINGLE_VALUE) {
|
||||||
this.info = new HashMap<String, Object>(info);
|
overwrite(values);
|
||||||
} else {
|
} else {
|
||||||
this.info = (HashMap<String, Object>) info;
|
if (values != null) {
|
||||||
|
this.values = new TreeMap<Long, Number>(reverseComparator);
|
||||||
|
this.values.putAll(values);
|
||||||
|
} else {
|
||||||
|
this.values = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addInfo(Map<String, Object> info) {
|
public void addValues(Map<Long, Number> values) {
|
||||||
this.info.putAll(info);
|
if (type == Type.SINGLE_VALUE) {
|
||||||
}
|
overwrite(values);
|
||||||
|
|
||||||
public void addInfo(String key, Object value) {
|
|
||||||
info.put(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@XmlElement(name = "data")
|
|
||||||
public Object getSingleData() {
|
|
||||||
return singleData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSingleData(Object singleData) {
|
|
||||||
this.singleData = singleData;
|
|
||||||
}
|
|
||||||
|
|
||||||
// required by JAXB
|
|
||||||
@InterfaceAudience.Private
|
|
||||||
@XmlElement(name = "timeseries")
|
|
||||||
public HashMap<Long, Object> getTimeSeriesJAXB() {
|
|
||||||
return timeSeries;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Long, Object> getTimeSeries() {
|
|
||||||
return timeSeries;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTimeSeries(Map<Long, Object> timeSeries) {
|
|
||||||
if (timeSeries != null && !(timeSeries instanceof LinkedHashMap)) {
|
|
||||||
this.timeSeries = new LinkedHashMap<Long, Object>(timeSeries);
|
|
||||||
} else {
|
} else {
|
||||||
this.timeSeries = (LinkedHashMap<Long, Object>) timeSeries;
|
this.values.putAll(values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTimeSeries(Map<Long, Object> timeSeries) {
|
public void addValue(long timestamp, Number value) {
|
||||||
this.timeSeries.putAll(timeSeries);
|
if (type == Type.SINGLE_VALUE) {
|
||||||
|
values.clear();
|
||||||
|
}
|
||||||
|
values.put(timestamp, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTimeSeriesData(long timestamp, Object value) {
|
private void overwrite(Map<Long, Number> values) {
|
||||||
timeSeries.put(timestamp, value);
|
if (values.size() > 1) {
|
||||||
}
|
throw new IllegalArgumentException(
|
||||||
|
"Values cannot contain more than one point in " +
|
||||||
@XmlElement(name = "starttime")
|
Type.SINGLE_VALUE + " mode");
|
||||||
public long getStartTime() {
|
}
|
||||||
return startTime;
|
this.values.clear();
|
||||||
}
|
this.values.putAll(values);
|
||||||
|
|
||||||
public void setStartTime(long startTime) {
|
|
||||||
this.startTime = startTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
@XmlElement(name = "endtime")
|
|
||||||
public long getEndTime() {
|
|
||||||
return endTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEndTime(long endTime) {
|
|
||||||
this.endTime = endTime;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,11 @@ import org.apache.hadoop.yarn.util.timeline.TimelineUtils;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
public class TestTimelineServiceRecords {
|
public class TestTimelineServiceRecords {
|
||||||
|
@ -41,38 +45,83 @@ public class TestTimelineServiceRecords {
|
||||||
entity.setType("test type 1");
|
entity.setType("test type 1");
|
||||||
entity.setId("test id 1");
|
entity.setId("test id 1");
|
||||||
entity.addInfo("test info key 1", "test info value 1");
|
entity.addInfo("test info key 1", "test info value 1");
|
||||||
entity.addInfo("test info key 2", "test info value 2");
|
entity.addInfo("test info key 2",
|
||||||
|
Arrays.asList("test info value 2", "test info value 3"));
|
||||||
|
entity.addInfo("test info key 3", true);
|
||||||
|
Assert.assertTrue(
|
||||||
|
entity.getInfo().get("test info key 3") instanceof Boolean);
|
||||||
entity.addConfig("test config key 1", "test config value 1");
|
entity.addConfig("test config key 1", "test config value 1");
|
||||||
entity.addConfig("test config key 2", "test config value 2");
|
entity.addConfig("test config key 2", "test config value 2");
|
||||||
TimelineMetric metric1 = new TimelineMetric();
|
|
||||||
|
TimelineMetric metric1 =
|
||||||
|
new TimelineMetric(TimelineMetric.Type.TIME_SERIES);
|
||||||
metric1.setId("test metric id 1");
|
metric1.setId("test metric id 1");
|
||||||
metric1.addInfo("test info key 1", "test info value 1");
|
metric1.addValue(1L, 1.0F);
|
||||||
metric1.addInfo("test info key 2", "test info value 2");
|
metric1.addValue(3L, 3.0D);
|
||||||
metric1.addTimeSeriesData(1L, "test time series 1");
|
metric1.addValue(2L, 2);
|
||||||
metric1.addTimeSeriesData(2L, "test time series 2");
|
Assert.assertEquals(TimelineMetric.Type.TIME_SERIES, metric1.getType());
|
||||||
metric1.setStartTime(0L);
|
Iterator<Map.Entry<Long, Number>> itr =
|
||||||
metric1.setEndTime(1L);
|
metric1.getValues().entrySet().iterator();
|
||||||
|
Map.Entry<Long, Number> entry = itr.next();
|
||||||
|
Assert.assertEquals(new Long(3L), entry.getKey());
|
||||||
|
Assert.assertEquals(new Double(3.0D), entry.getValue());
|
||||||
|
entry = itr.next();
|
||||||
|
Assert.assertEquals(new Long(2L), entry.getKey());
|
||||||
|
Assert.assertEquals(new Integer(2), entry.getValue());
|
||||||
|
entry = itr.next();
|
||||||
|
Assert.assertEquals(new Long(1L), entry.getKey());
|
||||||
|
Assert.assertEquals(new Float(1.0F), entry.getValue());
|
||||||
|
Assert.assertFalse(itr.hasNext());
|
||||||
entity.addMetric(metric1);
|
entity.addMetric(metric1);
|
||||||
TimelineMetric metric2 = new TimelineMetric();
|
|
||||||
|
TimelineMetric metric2 =
|
||||||
|
new TimelineMetric(TimelineMetric.Type.SINGLE_VALUE);
|
||||||
metric2.setId("test metric id 1");
|
metric2.setId("test metric id 1");
|
||||||
metric2.addInfo("test info key 1", "test info value 1");
|
metric2.addValue(3L, (short) 3);
|
||||||
metric2.addInfo("test info key 2", "test info value 2");
|
Assert.assertEquals(TimelineMetric.Type.SINGLE_VALUE, metric2.getType());
|
||||||
metric2.setSingleData("test info value 3");
|
Assert.assertTrue(
|
||||||
metric1.setStartTime(0L);
|
metric2.getValues().values().iterator().next() instanceof Short);
|
||||||
metric1.setEndTime(1L);
|
Map<Long, Number> points = new HashMap<>();
|
||||||
|
points.put(4L, 4.0D);
|
||||||
|
points.put(5L, 5.0D);
|
||||||
|
try {
|
||||||
|
metric2.setValues(points);
|
||||||
|
Assert.fail();
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
Assert.assertTrue(e.getMessage().contains(
|
||||||
|
"Values cannot contain more than one point in"));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
metric2.addValues(points);
|
||||||
|
Assert.fail();
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
Assert.assertTrue(e.getMessage().contains(
|
||||||
|
"Values cannot contain more than one point in"));
|
||||||
|
}
|
||||||
entity.addMetric(metric2);
|
entity.addMetric(metric2);
|
||||||
|
|
||||||
TimelineEvent event1 = new TimelineEvent();
|
TimelineEvent event1 = new TimelineEvent();
|
||||||
event1.setId("test event id 1");
|
event1.setId("test event id 1");
|
||||||
event1.addInfo("test info key 1", "test info value 1");
|
event1.addInfo("test info key 1", "test info value 1");
|
||||||
event1.addInfo("test info key 2", "test info value 2");
|
event1.addInfo("test info key 2",
|
||||||
|
Arrays.asList("test info value 2", "test info value 3"));
|
||||||
|
event1.addInfo("test info key 3", true);
|
||||||
|
Assert.assertTrue(
|
||||||
|
event1.getInfo().get("test info key 3") instanceof Boolean);
|
||||||
event1.setTimestamp(0L);
|
event1.setTimestamp(0L);
|
||||||
entity.addEvent(event1);
|
entity.addEvent(event1);
|
||||||
|
|
||||||
TimelineEvent event2 = new TimelineEvent();
|
TimelineEvent event2 = new TimelineEvent();
|
||||||
event2.setId("test event id 2");
|
event2.setId("test event id 2");
|
||||||
event2.addInfo("test info key 1", "test info value 1");
|
event2.addInfo("test info key 1", "test info value 1");
|
||||||
event2.addInfo("test info key 2", "test info value 2");
|
event2.addInfo("test info key 2",
|
||||||
|
Arrays.asList("test info value 2", "test info value 3"));
|
||||||
|
event2.addInfo("test info key 3", true);
|
||||||
|
Assert.assertTrue(
|
||||||
|
event2.getInfo().get("test info key 3") instanceof Boolean);
|
||||||
event2.setTimestamp(1L);
|
event2.setTimestamp(1L);
|
||||||
entity.addEvent(event2);
|
entity.addEvent(event2);
|
||||||
|
|
||||||
entity.setCreatedTime(0L);
|
entity.setCreatedTime(0L);
|
||||||
entity.setModifiedTime(1L);
|
entity.setModifiedTime(1L);
|
||||||
entity.addRelatesToEntity("test type 2", "test id 2");
|
entity.addRelatesToEntity("test type 2", "test id 2");
|
||||||
|
|
|
@ -572,7 +572,7 @@ public class ContainersMonitorImpl extends AbstractService implements
|
||||||
ResourceCalculatorProcessTree.UNAVAILABLE) {
|
ResourceCalculatorProcessTree.UNAVAILABLE) {
|
||||||
TimelineMetric memoryMetric = new TimelineMetric();
|
TimelineMetric memoryMetric = new TimelineMetric();
|
||||||
memoryMetric.setId(ContainerMetric.MEMORY.toString() + pId);
|
memoryMetric.setId(ContainerMetric.MEMORY.toString() + pId);
|
||||||
memoryMetric.addTimeSeriesData(currentTime, currentPmemUsage);
|
memoryMetric.addValue(currentTime, currentPmemUsage);
|
||||||
entity.addMetric(memoryMetric);
|
entity.addMetric(memoryMetric);
|
||||||
}
|
}
|
||||||
// if cpuUsageTotalCoresPercentage data is available
|
// if cpuUsageTotalCoresPercentage data is available
|
||||||
|
@ -580,7 +580,7 @@ public class ContainersMonitorImpl extends AbstractService implements
|
||||||
ResourceCalculatorProcessTree.UNAVAILABLE) {
|
ResourceCalculatorProcessTree.UNAVAILABLE) {
|
||||||
TimelineMetric cpuMetric = new TimelineMetric();
|
TimelineMetric cpuMetric = new TimelineMetric();
|
||||||
cpuMetric.setId(ContainerMetric.CPU.toString() + pId);
|
cpuMetric.setId(ContainerMetric.CPU.toString() + pId);
|
||||||
cpuMetric.addTimeSeriesData(currentTime,
|
cpuMetric.addValue(currentTime,
|
||||||
cpuUsageTotalCoresPercentage);
|
cpuUsageTotalCoresPercentage);
|
||||||
entity.addMetric(cpuMetric);
|
entity.addMetric(cpuMetric);
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,12 @@ public class TestTimelineServiceClientIntegration {
|
||||||
TimelineEntity entity = new TimelineEntity();
|
TimelineEntity entity = new TimelineEntity();
|
||||||
entity.setType("test entity type");
|
entity.setType("test entity type");
|
||||||
entity.setId("test entity id");
|
entity.setId("test entity id");
|
||||||
|
TimelineMetric metric =
|
||||||
|
new TimelineMetric(TimelineMetric.Type.TIME_SERIES);
|
||||||
|
metric.setId("test metric id");
|
||||||
|
metric.addValue(1L, 1.0D);
|
||||||
|
metric.addValue(2L, 2.0D);
|
||||||
|
entity.addMetric(metric);
|
||||||
client.putEntities(entity);
|
client.putEntities(entity);
|
||||||
client.putEntitiesAsync(entity);
|
client.putEntitiesAsync(entity);
|
||||||
} finally {
|
} finally {
|
||||||
|
|
Loading…
Reference in New Issue