This is an automated email from the ASF dual-hosted git repository.
guoyp pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/griffin.git
The following commit(s) were added to refs/heads/master by this push:
new ee2c7ac [GRIFFIN-244] get metrics by instance
ee2c7ac is described below
commit ee2c7acad7c58ca16d35c4887656f71dea6989d9
Author: Rodion Gorkovenko <[email protected]>
AuthorDate: Sun Apr 14 08:45:07 2019 +0800
[GRIFFIN-244] get metrics by instance
This is just a squashed version of #491
Author: Rodion Gorkovenko <[email protected]>
Author: rodion <[email protected]>
Closes #492 from RodionGork/griffin-244-squashed.
---
griffin-doc/service/api-guide.md | 39 ++++++
griffin-doc/service/postman/griffin.json | 146 ++++++++++++++++++++-
.../griffin/measure/context/MetricWrapper.scala | 4 +-
.../measure/context/MetricWrapperTest.scala | 5 +-
.../core/exception/GriffinExceptionMessage.java | 2 +
.../griffin/core/job/entity/JobInstanceBean.java | 7 +
.../griffin/core/metric/MetricController.java | 6 +
.../apache/griffin/core/metric/MetricService.java | 2 +
.../griffin/core/metric/MetricServiceImpl.java | 22 ++++
.../apache/griffin/core/metric/MetricStore.java | 2 +
.../griffin/core/metric/MetricStoreImpl.java | 28 +++-
.../griffin/core/metric/model/MetricValue.java | 44 +++++++
.../apache/griffin/core/job/JobControllerTest.java | 11 ++
.../griffin/core/metric/MetricServiceImplTest.java | 44 +++++++
.../griffin/core/metric/MetricStoreImplTest.java | 79 ++++++++++-
service/src/test/resources/metricvalue.json | 51 +++++++
16 files changed, 475 insertions(+), 17 deletions(-)
diff --git a/griffin-doc/service/api-guide.md b/griffin-doc/service/api-guide.md
index 95113af..17bca5b 100644
--- a/griffin-doc/service/api-guide.md
+++ b/griffin-doc/service/api-guide.md
@@ -42,12 +42,14 @@ Apache Griffin default `BASE_PATH` is `http://<your
ip>:8080`.
- [Get Job Instances](#34)
- [Get Job Healthy Statistics](#35)
- [Download Sample Records](#36)
+ - [Get Job Instance by Id](#38)
- [Metrics](#4)
- [Get Metrics](#41)
- [Add Metric Value](#42)
- [Get Metric Value](#43)
- [Remove Metric Value](#44)
+ - [Get Metric Value by Job Instance Id](#45)
- [Hive MetaStore](#5)
- [Get Table Metadata](#51)
@@ -747,6 +749,17 @@ curl -k -G -X GET
http://127.0.0.1:8080/api/v1/jobs/download \
```
If successful, this method returns missing records in the response body,
maximum record count is 100.
+<div id = "38"></div>
+
+### Get Job Instance by Id
+`GET /api/v1/jobs/instances/{jobInstanceId}`
+
+#### API Example
+```
+curl -k -G -X GET http://127.0.0.1:8080/api/v1/jobs/instances/1
+```
+If successful, this method returns job instance description for the given job
instance id. If there is no instance with given id found, returns Griffin
Exception.
+
<h2 id = "4"></h2>
## Metrics
@@ -927,6 +940,32 @@ curl -k -H "Accept: application/json" \
}
```
+<div id = "45"></div>
+
+### Get Metric Value by Job Instance Id
+`GET http://127.0.0.1:8080/api/v1/metrics/values/:jobInstanceId`
+#### API Example
+```
+curl -k -G -X GET http://127.0.0.1:8080/api/v1/metrics/values/{304}
+{
+ "name": "some_job",
+ "tmst": 1553526960000,
+ "value": {
+ "total": 74,
+ "miss": 31,
+ "matched": 43,
+ "matchedFraction": 0.581081081081081
+ },
+ "metadata": {
+ "applicationId": "\"application_1549876136110_0237\"",
+ }
+}
+```
+
+
+
+
+
<h2 id = "5"></h2>
### Hive MetaStore
diff --git a/griffin-doc/service/postman/griffin.json
b/griffin-doc/service/postman/griffin.json
index e789121..55d7bac 100644
--- a/griffin-doc/service/postman/griffin.json
+++ b/griffin-doc/service/postman/griffin.json
@@ -1406,7 +1406,7 @@
"health"
]
},
- "description": "`GET
/api/v1/jobs/health`\n\n#### Response Body Sample\n```\n{\n
\"healthyJobCount\": 1,\n \"jobCount\": 2\n}\n```"
+ "description": "`GET
/api/v1/jobs/health`\n\n#### Response Body Sample\n```\n{\n \"job instance
info\"\n}\n```"
},
"response": [
{
@@ -1430,7 +1430,7 @@
"health"
]
},
- "description":
"`GET /api/v1/jobs/health`\n\n#### Response Body Sample\n```\n{\n
\"healthyJobCount\": 1,\n \"jobCount\": 2\n}\n```"
+ "description":
"`GET /api/v1/jobs/health`\n\n#### Response Body Sample\n```\n{\n \"job
instance info\"\n}\n```"
},
"status": "OK",
"code": 200,
@@ -1838,6 +1838,75 @@
"body": ""
}
]
+ },
+ {
+ "name": "Get Job Instance by Id",
+ "request": {
+ "method": "GET",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": ""
+ },
+ "url": {
+ "raw":
"{{BASE_PATH}}/api/v1/jobs/instances/:id",
+ "host": [
+ "{{BASE_PATH}}"
+ ],
+ "path": [
+ "api",
+ "v1",
+ "jobs",
+ "instances",
+ ":id"
+ ],
+ "variable": [
+ {
+ "key":
"id",
+
"value": "2"
+ }
+ ]
+ },
+ "description": "`GET
/api/v1/jobs/instances/{id}`\n\n#### Response Body Sample\n```\n{\n \"job
instance info\"\n}\n```"
+ },
+ "response": [
+ {
+ "name": "Get Job
Instance by Id",
+ "originalRequest": {
+ "method": "GET",
+ "header": [],
+ "body": {
+ "mode":
"raw",
+ "raw":
""
+ },
+ "url": {
+ "raw":
"{{BASE_PATH}}/api/v1/jobs/instances/:id",
+ "host":
[
+
"{{BASE_PATH}}"
+ ],
+ "path":
[
+
"api",
+
"v1",
+
"jobs",
+
"instances",
+
":id"
+ ],
+
"variable": [
+
{
+
"key": "id",
+
"value": "2"
+
}
+ ]
+ },
+ "description":
"`GET /api/v1/jobs/instances/{id}`\n\n#### Response Body Sample\n```\n{\n
\"job instance info\"\n}\n```"
+ },
+ "status": "OK",
+ "code": 200,
+
"_postman_previewlanguage": "json",
+ "cookie": [],
+ "body": "{\n
\"healthyJobCount\": 1,\n \"jobCount\": 2\n}"
+ }
+ ]
}
]
},
@@ -2080,7 +2149,7 @@
],
"body": {
"mode": "raw",
- "raw":
"[\n\t{\n\t\t\"name\" : \"metricName\",\n\t\t\"tmst\" :
1509599811123,\n\t\t\"value\" : {\n\t\t\t\"__tmst\" :
1509599811123,\n\t\t\t\"miss\" : 11,\n\t\t\t\"total\" :
125000,\n\t\t\t\"matched\" : 124989\n\t\t}\n }\n]"
+ "raw":
"[\n\t{\n\t\t\"name\" : \"metricName\",\n\t\t\"tmst\" :
1509599811123,\n\t\t\"applicationId\" : \"app_1\",\n\t\t\"value\" :
{\n\t\t\t\"__tmst\" : 1509599811123,\n\t\t\t\"miss\" : 11,\n\t\t\t\"total\" :
125000,\n\t\t\t\"matched\" : 124989\n\t\t}\n }\n]"
},
"url": {
"raw":
"{{BASE_PATH}}/api/v1/metrics/values",
@@ -2109,7 +2178,7 @@
],
"body": {
"mode":
"raw",
- "raw":
"[\n\t{\n\t\t\"name\" : \"metricName\",\n\t\t\"tmst\" :
1509599811123,\n\t\t\"value\" : {\n\t\t\t\"__tmst\" :
1509599811123,\n\t\t\t\"miss\" : 11,\n\t\t\t\"total\" :
125000,\n\t\t\t\"matched\" : 124989\n\t\t}\n }\n]"
+ "raw":
"[\n\t{\n\t\t\"name\" : \"metricName\",\n\t\t\"tmst\" :
1509599811123,\n\t\t\"applicationId\" : \"app_1\",\n\t\t\"value\" :
{\n\t\t\t\"__tmst\" : 1509599811123,\n\t\t\t\"miss\" : 11,\n\t\t\t\"total\" :
125000,\n\t\t\t\"matched\" : 124989\n\t\t}\n }\n]"
},
"url": {
"raw":
"{{BASE_PATH}}/api/v1/metrics/values",
@@ -2307,6 +2376,75 @@
"body":
"{\"took\":363,\"timed_out\":false,\"total\":5,\"deleted\":5,\"batches\":1,\"version_conflicts\":0,\"noops\":0,\"retries\":{\"bulk\":0,\"search\":0},\"throttled_millis\":0,\"requests_per_second\":-1.0,\"throttled_until_millis\":0,\"failures\":[]}"
}
]
+ },
+ {
+ "name": "Get Metrics Value by Job
Instance Id",
+ "request": {
+ "method": "GET",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": ""
+ },
+ "url": {
+ "raw":
"{{BASE_PATH}}/api/v1/metrics/values/:jobInstanceId",
+ "host": [
+ "{{BASE_PATH}}"
+ ],
+ "path": [
+ "api",
+ "v1",
+ "metrics",
+ "values",
+ ":jobInstanceId"
+ ],
+ "variable": [
+ {
+ "key":
"jobInstanceId",
+
"value": "304"
+ }
+ ]
+ },
+ "description": "`GET
/api/v1/metrics/values/{jobInstanceId}`\n\n#### Response Body Sample\n```\n{\n
\"metric value\"\n}\n```"
+ },
+ "response": [
+ {
+ "name": "Get Metrics
Value by Job Instance Id",
+ "originalRequest": {
+ "method": "GET",
+ "header": [],
+ "body": {
+ "mode":
"raw",
+ "raw":
""
+ },
+ "url": {
+ "raw":
"{{BASE_PATH}}/api/v1/metrics/values/:jobInstanceId",
+ "host":
[
+
"{{BASE_PATH}}"
+ ],
+ "path":
[
+
"api",
+
"v1",
+
"metrics",
+
"values",
+
":jobInstanceId"
+ ],
+
"variable": [
+
{
+
"key": "jobInstanceId",
+
"value": "304"
+
}
+ ]
+ },
+ "description":
"`GET /api/v1/metrics/values/{jobInstanceId}`\n\n#### Response Body
Sample\n```\n{\n \"metric value\"\n}\n```"
+ },
+ "status": "OK",
+ "code": 200,
+
"_postman_previewlanguage": "json",
+ "cookie": [],
+ "body": "{\n
\"name\": some_job,\n \"tmst\": 1553526960000\n \"applicationId\":
application_1549876136110_0237\n \"value\": {\n \"total\": 74}}"
+ }
+ ]
}
]
},
diff --git
a/measure/src/main/scala/org/apache/griffin/measure/context/MetricWrapper.scala
b/measure/src/main/scala/org/apache/griffin/measure/context/MetricWrapper.scala
index df162a7..484797a 100644
---
a/measure/src/main/scala/org/apache/griffin/measure/context/MetricWrapper.scala
+++
b/measure/src/main/scala/org/apache/griffin/measure/context/MetricWrapper.scala
@@ -28,7 +28,7 @@ case class MetricWrapper(name: String, applicationId: String)
extends Serializab
val _Name = "name"
val _Timestamp = "tmst"
val _Value = "value"
- val _ApplicationId = "applicationId"
+ val _Metadata = "metadata"
val metrics: MutableMap[Long, Map[String, Any]] = MutableMap()
@@ -47,7 +47,7 @@ case class MetricWrapper(name: String, applicationId: String)
extends Serializab
(_Name -> name),
(_Timestamp -> timestamp),
(_Value -> value),
- (_ApplicationId -> applicationId)
+ (_Metadata -> Map("applicationId" -> applicationId))
))
}
}
diff --git
a/measure/src/test/scala/org/apache/griffin/measure/context/MetricWrapperTest.scala
b/measure/src/test/scala/org/apache/griffin/measure/context/MetricWrapperTest.scala
index 8ad7d5d..4a49c75 100644
---
a/measure/src/test/scala/org/apache/griffin/measure/context/MetricWrapperTest.scala
+++
b/measure/src/test/scala/org/apache/griffin/measure/context/MetricWrapperTest.scala
@@ -35,8 +35,9 @@ class MetricWrapperTest extends FlatSpec with Matchers {
metricWrapper.insertMetric(2, Map("miss" -> 4))
metricWrapper.flush should be (Map(
1L -> Map("name" -> "test", "tmst" -> 1, "value" -> Map("total" -> 10,
"miss"-> 2, "match" -> 8),
- "applicationId" -> "appId"),
- 2L -> Map("name" -> "test", "tmst" -> 2, "value" -> Map("total" -> 20,
"miss"-> 4), "applicationId" -> "appId")
+ "metadata" -> Map("applicationId" -> "appId")),
+ 2L -> Map("name" -> "test", "tmst" -> 2, "value" -> Map("total" -> 20,
"miss"-> 4),
+ "metadata" -> Map("applicationId" -> "appId"))
))
}
diff --git
a/service/src/main/java/org/apache/griffin/core/exception/GriffinExceptionMessage.java
b/service/src/main/java/org/apache/griffin/core/exception/GriffinExceptionMessage.java
index 6a9b9da..4f65248 100644
---
a/service/src/main/java/org/apache/griffin/core/exception/GriffinExceptionMessage.java
+++
b/service/src/main/java/org/apache/griffin/core/exception/GriffinExceptionMessage.java
@@ -76,6 +76,8 @@ public enum GriffinExceptionMessage {
INSTANCE_ID_DOES_NOT_EXIST(40409, "Instance id does not exist"),
+ JOB_INSTANCE_NOT_FOUND(40410, "No job instances with given job instance id
found"),
+
//409, "Conflict"
MEASURE_NAME_ALREADY_EXIST(40901, "Measure name already exists"),
diff --git
a/service/src/main/java/org/apache/griffin/core/job/entity/JobInstanceBean.java
b/service/src/main/java/org/apache/griffin/core/job/entity/JobInstanceBean.java
index 6fc5cf2..c3b0f1c 100644
---
a/service/src/main/java/org/apache/griffin/core/job/entity/JobInstanceBean.java
+++
b/service/src/main/java/org/apache/griffin/core/job/entity/JobInstanceBean.java
@@ -186,6 +186,13 @@ public class JobInstanceBean extends
AbstractAuditableEntity {
public JobInstanceBean() {
}
+ public JobInstanceBean(State state, Long tms, Long expireTms, String
appId) {
+ this.state = state;
+ this.tms = tms;
+ this.expireTms = expireTms;
+ this.appId=appId;
+ }
+
public JobInstanceBean(State state, Long tms, Long expireTms) {
this.state = state;
this.tms = tms;
diff --git
a/service/src/main/java/org/apache/griffin/core/metric/MetricController.java
b/service/src/main/java/org/apache/griffin/core/metric/MetricController.java
index 4d39ba3..5cd43af 100644
--- a/service/src/main/java/org/apache/griffin/core/metric/MetricController.java
+++ b/service/src/main/java/org/apache/griffin/core/metric/MetricController.java
@@ -27,6 +27,7 @@ import org.apache.griffin.core.metric.model.MetricValue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@@ -71,4 +72,9 @@ public class MetricController {
String metricName) {
return metricService.deleteMetricValues(metricName);
}
+
+ @RequestMapping(value = "/metrics/values/{instanceId}", method =
RequestMethod.GET)
+ public MetricValue getMetric(@PathVariable("instanceId") Long id){
+ return metricService.findMetric(id);
+ }
}
diff --git
a/service/src/main/java/org/apache/griffin/core/metric/MetricService.java
b/service/src/main/java/org/apache/griffin/core/metric/MetricService.java
index 039b0cb..75402ff 100644
--- a/service/src/main/java/org/apache/griffin/core/metric/MetricService.java
+++ b/service/src/main/java/org/apache/griffin/core/metric/MetricService.java
@@ -37,4 +37,6 @@ public interface MetricService {
ResponseEntity addMetricValues(List<MetricValue> values);
ResponseEntity<?> deleteMetricValues(String metricName);
+
+ MetricValue findMetric(Long id);
}
diff --git
a/service/src/main/java/org/apache/griffin/core/metric/MetricServiceImpl.java
b/service/src/main/java/org/apache/griffin/core/metric/MetricServiceImpl.java
index f817f65..beca19e 100644
---
a/service/src/main/java/org/apache/griffin/core/metric/MetricServiceImpl.java
+++
b/service/src/main/java/org/apache/griffin/core/metric/MetricServiceImpl.java
@@ -23,6 +23,7 @@ package org.apache.griffin.core.metric;
import static
org.apache.griffin.core.exception.GriffinExceptionMessage.INVALID_METRIC_RECORDS_OFFSET;
import static
org.apache.griffin.core.exception.GriffinExceptionMessage.INVALID_METRIC_RECORDS_SIZE;
import static
org.apache.griffin.core.exception.GriffinExceptionMessage.INVALID_METRIC_VALUE_FORMAT;
+import static
org.apache.griffin.core.exception.GriffinExceptionMessage.JOB_INSTANCE_NOT_FOUND;
import java.io.IOException;
import java.util.ArrayList;
@@ -36,6 +37,8 @@ import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.griffin.core.exception.GriffinException;
import org.apache.griffin.core.job.entity.AbstractJob;
+import org.apache.griffin.core.job.entity.JobInstanceBean;
+import org.apache.griffin.core.job.repo.JobInstanceRepo;
import org.apache.griffin.core.job.repo.JobRepo;
import org.apache.griffin.core.measure.entity.Measure;
import org.apache.griffin.core.measure.repo.MeasureRepo;
@@ -59,6 +62,8 @@ public class MetricServiceImpl implements MetricService {
private JobRepo<AbstractJob> jobRepo;
@Autowired
private MetricStore metricStore;
+ @Autowired
+ private JobInstanceRepo jobInstanceRepo;
@Override
public Map<String, List<Metric>> getAllMetrics() {
@@ -139,6 +144,23 @@ public class MetricServiceImpl implements MetricService {
}
}
+ @Override
+ public MetricValue findMetric(Long id) {
+ JobInstanceBean jobInstanceBean = jobInstanceRepo.findByInstanceId(id);
+ if (jobInstanceBean == null){
+ LOGGER.warn("There are no job instances with id {} ", id);
+ throw new GriffinException
+ .NotFoundException(JOB_INSTANCE_NOT_FOUND);
+ }
+ String appId = jobInstanceBean.getAppId();
+ try {
+ return metricStore.getMetric(appId);
+ } catch (IOException e) {
+ LOGGER.warn("Failed to get metric for applicationId {} ", appId);
+ throw new GriffinException.ServiceException("Failed to find
metric", e);
+ }
+ }
+
private void checkFormat(MetricValue value) {
if (StringUtils.isBlank(value.getName()) || value.getTmst() == null
|| MapUtils.isEmpty(value.getValue())) {
diff --git
a/service/src/main/java/org/apache/griffin/core/metric/MetricStore.java
b/service/src/main/java/org/apache/griffin/core/metric/MetricStore.java
index a452648..f85c4db 100644
--- a/service/src/main/java/org/apache/griffin/core/metric/MetricStore.java
+++ b/service/src/main/java/org/apache/griffin/core/metric/MetricStore.java
@@ -34,4 +34,6 @@ public interface MetricStore {
throws IOException;
ResponseEntity<?> deleteMetricValues(String metricName) throws IOException;
+
+ MetricValue getMetric(String applicationId) throws IOException;
}
diff --git
a/service/src/main/java/org/apache/griffin/core/metric/MetricStoreImpl.java
b/service/src/main/java/org/apache/griffin/core/metric/MetricStoreImpl.java
index 3bff8f5..2d577bb 100644
--- a/service/src/main/java/org/apache/griffin/core/metric/MetricStoreImpl.java
+++ b/service/src/main/java/org/apache/griffin/core/metric/MetricStoreImpl.java
@@ -31,7 +31,9 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
+import org.apache.commons.lang.StringUtils;
import org.apache.griffin.core.metric.model.MetricValue;
import org.apache.griffin.core.util.JsonUtil;
import org.apache.http.Header;
@@ -142,14 +144,16 @@ public class MetricStoreImpl implements MetricStore {
.hasNonNull("hits")) {
for (JsonNode node : jsonNode.get("hits").get("hits")) {
JsonNode sourceNode = node.get("_source");
- Map<String, Object> value = JsonUtil.toEntity(sourceNode
- .get("value").toString(),
- new TypeReference<Map<String, Object>>() {
- });
- MetricValue metricValue = new MetricValue(sourceNode
- .get("name")
- .asText(),
+ Map<String, Object> value = JsonUtil.toEntity(
+ sourceNode.get("value").toString(),
+ new TypeReference<Map<String, Object>>() {});
+ Map<String, Object> meta = JsonUtil.toEntity(
+ Objects.toString(sourceNode.get("metadata"), null),
+ new TypeReference<Map<String, Object>>() {});
+ MetricValue metricValue = new MetricValue(
+ sourceNode.get("name").asText(),
Long.parseLong(sourceNode.get("tmst").asText()),
+ meta,
value);
metricValues.add(metricValue);
}
@@ -206,4 +210,14 @@ public class MetricStoreImpl implements MetricStore {
return String.format("Basic %s", Base64.getEncoder().encodeToString(
auth.getBytes()));
}
+
+ @Override
+ public MetricValue getMetric(String applicationId) throws IOException {
+ Response response = client.performRequest(
+ "GET", urlGet,
+ Collections.singletonMap(
+ "q", "metadata.applicationId:" + applicationId));
+ List<MetricValue> metricValues = getMetricValuesFromResponse(response);
+ return metricValues.get(0);
+ }
}
diff --git
a/service/src/main/java/org/apache/griffin/core/metric/model/MetricValue.java
b/service/src/main/java/org/apache/griffin/core/metric/model/MetricValue.java
index 4839f9f..4c7f386 100644
---
a/service/src/main/java/org/apache/griffin/core/metric/model/MetricValue.java
+++
b/service/src/main/java/org/apache/griffin/core/metric/model/MetricValue.java
@@ -19,7 +19,9 @@ under the License.
package org.apache.griffin.core.metric.model;
+import java.util.Collections;
import java.util.Map;
+import java.util.Objects;
public class MetricValue {
@@ -27,6 +29,8 @@ public class MetricValue {
private Long tmst;
+ private Map<String, Object> metadata;
+
private Map<String, Object> value;
public MetricValue() {
@@ -36,6 +40,15 @@ public class MetricValue {
this.name = name;
this.tmst = tmst;
this.value = value;
+ this.metadata = Collections.emptyMap();
+ }
+
+
+ public MetricValue(String name, Long tmst, Map<String, Object> metadata,
Map<String, Object> value) {
+ this.name = name;
+ this.tmst = tmst;
+ this.metadata = metadata;
+ this.value = value;
}
public String getName() {
@@ -61,4 +74,35 @@ public class MetricValue {
public void setValue(Map<String, Object> value) {
this.value = value;
}
+
+ public Map<String, Object> getMetadata() {
+ return metadata;
+ }
+
+ public void setMetadata(Map<String, Object> metadata) {
+ this.metadata = metadata;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ MetricValue that = (MetricValue) o;
+ return Objects.equals(name, that.name) &&
+ Objects.equals(tmst, that.tmst) &&
+ Objects.equals(metadata, that.metadata) &&
+ Objects.equals(value, that.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, tmst, metadata, value);
+ }
+
+ @Override
+ public String toString() {
+ return String.format(
+ "MetricValue{name=%s, ts=%s, meta=%s, value=%s}",
+ name, tmst, metadata, value);
+ }
}
diff --git
a/service/src/test/java/org/apache/griffin/core/job/JobControllerTest.java
b/service/src/test/java/org/apache/griffin/core/job/JobControllerTest.java
index d9d5d80..aa10cf2 100644
--- a/service/src/test/java/org/apache/griffin/core/job/JobControllerTest.java
+++ b/service/src/test/java/org/apache/griffin/core/job/JobControllerTest.java
@@ -38,6 +38,7 @@ import java.util.Collections;
import org.apache.griffin.core.exception.GriffinException;
import org.apache.griffin.core.exception.GriffinExceptionHandler;
+import org.apache.griffin.core.exception.GriffinExceptionMessage;
import org.apache.griffin.core.job.entity.AbstractJob;
import org.apache.griffin.core.job.entity.JobHealth;
import org.apache.griffin.core.job.entity.JobInstanceBean;
@@ -186,6 +187,16 @@ public class JobControllerTest {
}
@Test
+ public void testJobInstanceWithGivenIdNotFound() throws Exception {
+ Long jobInstanceId = 2L;
+ doThrow(new
GriffinException.NotFoundException(GriffinExceptionMessage.JOB_INSTANCE_NOT_FOUND))
+ .when(service).findInstance(jobInstanceId);
+
+ mvc.perform(get(URLHelper.API_VERSION_PATH + "/jobs/instances/2"))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
public void testGetHealthInfo() throws Exception {
JobHealth jobHealth = new JobHealth(1, 3);
given(service.getHealthInfo()).willReturn(jobHealth);
diff --git
a/service/src/test/java/org/apache/griffin/core/metric/MetricServiceImplTest.java
b/service/src/test/java/org/apache/griffin/core/metric/MetricServiceImplTest.java
index aa55f7a..39837f0 100644
---
a/service/src/test/java/org/apache/griffin/core/metric/MetricServiceImplTest.java
+++
b/service/src/test/java/org/apache/griffin/core/metric/MetricServiceImplTest.java
@@ -33,6 +33,9 @@ import java.util.Map;
import org.apache.griffin.core.exception.GriffinException;
import org.apache.griffin.core.job.entity.AbstractJob;
+import org.apache.griffin.core.job.entity.JobInstanceBean;
+import org.apache.griffin.core.job.entity.LivySessionStates;
+import org.apache.griffin.core.job.repo.JobInstanceRepo;
import org.apache.griffin.core.job.repo.JobRepo;
import org.apache.griffin.core.measure.entity.Measure;
import org.apache.griffin.core.measure.repo.MeasureRepo;
@@ -63,6 +66,8 @@ public class MetricServiceImplTest {
private JobRepo<AbstractJob> jobRepo;
@Mock
private MetricStoreImpl metricStore;
+ @Mock
+ private JobInstanceRepo jobInstanceRepo;
@Autowired
private Environment env;
@@ -204,4 +209,43 @@ public class MetricServiceImplTest {
}
+ @Test
+ public void testFindMetricSuccess() throws IOException {
+ Long id = 1L;
+ String appId = "application";
+ MetricValue expectedMetric = new MetricValue(
+ "name", 1234L, Collections.singletonMap("applicationId",
appId), new HashMap<>());
+
+ given(jobInstanceRepo.findByInstanceId(id))
+ .willReturn(new
JobInstanceBean(LivySessionStates.State.RUNNING, 12L, 32L, appId));
+ given(metricStore.getMetric(appId))
+ .willReturn(expectedMetric);
+ MetricValue actualMetric = service.findMetric(id);
+
+ assertEquals(expectedMetric, actualMetric);
+ }
+
+ @Test(expected = GriffinException.NotFoundException.class)
+ public void testFailedToFindJobInstance() throws IOException {
+ Long id = 1L;
+ given(jobInstanceRepo.findByInstanceId(id))
+ .willReturn(null);
+ service.findMetric(id);
+
+ }
+
+ @Test(expected = GriffinException.ServiceException.class)
+ public void testFindMetricFailure() throws IOException {
+ Long id = 1L;
+ String appId = "application";
+
+ given(jobInstanceRepo.findByInstanceId(id))
+ .willReturn(new
JobInstanceBean(LivySessionStates.State.RUNNING, 12L, 32L, appId));
+ given(metricStore.getMetric(appId))
+ .willThrow(new GriffinException.ServiceException("", new
RuntimeException()));
+ service.findMetric(id);
+
+ }
+
+
}
diff --git
a/service/src/test/java/org/apache/griffin/core/metric/MetricStoreImplTest.java
b/service/src/test/java/org/apache/griffin/core/metric/MetricStoreImplTest.java
index d3cbfb0..b91f6ba 100644
---
a/service/src/test/java/org/apache/griffin/core/metric/MetricStoreImplTest.java
+++
b/service/src/test/java/org/apache/griffin/core/metric/MetricStoreImplTest.java
@@ -19,15 +19,55 @@ under the License.
package org.apache.griffin.core.metric;
-import static org.junit.Assert.assertTrue;
+import org.apache.griffin.core.metric.model.MetricValue;
+import org.apache.http.HttpEntity;
+import org.elasticsearch.client.Response;
+import org.elasticsearch.client.RestClient;
+import org.elasticsearch.client.RestClientBuilder;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import java.io.IOException;
+import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
-import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.BDDMockito.*;
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({RestClient.class, RestClientBuilder.class})
+@PowerMockIgnore("javax.management.*")
public class MetricStoreImplTest {
+ private static final String INDEX = "griffin";
+ private static final String TYPE = "accuracy";
+
+ private static final String urlBase = String.format("/%s/%s", INDEX, TYPE);
+ private static final String urlGet =
urlBase.concat("/_search?filter_path=hits.hits._source");
+
+ private RestClient restClientMock;
+
+ @Before
+ public void setup(){
+ PowerMockito.mockStatic(RestClient.class);
+ restClientMock = PowerMockito.mock(RestClient.class);
+ RestClientBuilder restClientBuilderMock =
PowerMockito.mock(RestClientBuilder.class);
+
+
given(RestClient.builder(anyVararg())).willReturn(restClientBuilderMock);
+ given(restClientBuilderMock.build()).willReturn(restClientMock);
+ }
+
@Test
public void testBuildBasicAuthString()
throws NoSuchMethodException, InvocationTargetException,
@@ -40,4 +80,39 @@ public class MetricStoreImplTest {
assertTrue(authStr.equals("Basic dXNlcjpwYXNzd29yZA=="));
}
+ @Test
+ public void testMetricGetting() throws IOException, URISyntaxException {
+ //given
+ Response responseMock = PowerMockito.mock(Response.class);
+ HttpEntity httpEntityMock = PowerMockito.mock(HttpEntity.class);
+ InputStream is = Thread.currentThread().getContextClassLoader()
+ .getResourceAsStream("metricvalue.json");
+ Map<String, String> map = new HashMap<>();
+ map.put("q", "metadata.applicationId:application_1549876136110_0018");
+
+ Map<String, Object> value = new HashMap<String, Object>(){{
+ put("total", 74);
+ put("miss", 0);
+ put("matched", 74);
+ put("matchedFraction", 1);
+ }};
+ MetricValue expectedMetric = new
MetricValue("de_demo_results_comparision",
+ 1549985089648L,
+ Collections.singletonMap("applicationId",
"application_1549876136110_0018"),
+ value);
+
+
+ given(restClientMock.performRequest(eq("GET"), eq(urlGet), eq(map),
anyVararg())).willReturn(responseMock);
+ given(responseMock.getEntity()).willReturn(httpEntityMock);
+ given(httpEntityMock.getContent()).willReturn(is);
+
+ //when
+ MetricStoreImpl metricStore = new MetricStoreImpl("", 0, "", "", "");
+ MetricValue metric =
metricStore.getMetric("application_1549876136110_0018");
+
+ //then
+ PowerMockito.verifyStatic();
+ assertEquals(expectedMetric, metric);
+ }
+
}
diff --git a/service/src/test/resources/metricvalue.json
b/service/src/test/resources/metricvalue.json
new file mode 100644
index 0000000..690c1c4
--- /dev/null
+++ b/service/src/test/resources/metricvalue.json
@@ -0,0 +1,51 @@
+{
+ "took": 47,
+ "timed_out": false,
+ "_shards": {
+ "total": 5,
+ "successful": 5,
+ "skipped": 0,
+ "failed": 0
+ },
+ "hits": {
+ "total": 17,
+ "max_score": 3.226844,
+ "hits": [
+ {
+ "_index": "griffin",
+ "_type": "accuracy",
+ "_id": "RZFP4mgBkZqzqlKSwWtJ",
+ "_score": 3.226844,
+ "_source": {
+ "name": "de_demo_results_comparision",
+ "tmst": 1549985089648,
+ "value": {
+ "total": 74,
+ "miss": 0,
+ "matched": 74,
+ "matchedFraction": 1
+ },
+ "metadata": {
+ "applicationId": "application_1549876136110_0018"
+ }
+ }
+ },
+ {
+ "_index": "griffin",
+ "_type": "accuracy",
+ "_id": "taMpvmgBfOpRJiYFj5Xg",
+ "_score": 2.4107988,
+ "_source": {
+ "name": "de_demo_results_comparision",
+ "tmst": 1549378607658,
+ "value": {
+ "total": 74,
+ "miss": 0,
+ "matched": 74,
+ "matchedFraction": 1
+ }
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file