http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/java/org/apache/griffin/core/measure/repo/DataConnectorRepo.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/measure/repo/DataConnectorRepo.java
 
b/service/src/main/java/org/apache/griffin/core/measure/repo/DataConnectorRepo.java
index 57e75ba..120a666 100644
--- 
a/service/src/main/java/org/apache/griffin/core/measure/repo/DataConnectorRepo.java
+++ 
b/service/src/main/java/org/apache/griffin/core/measure/repo/DataConnectorRepo.java
@@ -19,11 +19,14 @@ under the License.
 
 package org.apache.griffin.core.measure.repo;
 
-
 import org.apache.griffin.core.measure.entity.DataConnector;
+import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.CrudRepository;
-import org.springframework.stereotype.Repository;
 
-@Repository
+import java.util.List;
+
 public interface DataConnectorRepo extends CrudRepository<DataConnector, Long> 
{
+
+    @Query("select dc from DataConnector dc where name in ?1")
+    List<DataConnector> findByConnectorNames(List<String> names);
 }

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/java/org/apache/griffin/core/measure/repo/EvaluateRuleRepo.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/measure/repo/EvaluateRuleRepo.java
 
b/service/src/main/java/org/apache/griffin/core/measure/repo/EvaluateRuleRepo.java
index 9a676c5..a0be457 100644
--- 
a/service/src/main/java/org/apache/griffin/core/measure/repo/EvaluateRuleRepo.java
+++ 
b/service/src/main/java/org/apache/griffin/core/measure/repo/EvaluateRuleRepo.java
@@ -19,7 +19,6 @@ under the License.
 
 package org.apache.griffin.core.measure.repo;
 
-
 import org.apache.griffin.core.measure.entity.EvaluateRule;
 import org.springframework.data.repository.CrudRepository;
 

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/java/org/apache/griffin/core/measure/repo/ExternalMeasureRepo.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/measure/repo/ExternalMeasureRepo.java
 
b/service/src/main/java/org/apache/griffin/core/measure/repo/ExternalMeasureRepo.java
new file mode 100644
index 0000000..91f4fc1
--- /dev/null
+++ 
b/service/src/main/java/org/apache/griffin/core/measure/repo/ExternalMeasureRepo.java
@@ -0,0 +1,25 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package org.apache.griffin.core.measure.repo;
+
+import org.apache.griffin.core.measure.entity.ExternalMeasure;
+
+public interface ExternalMeasureRepo extends MeasureRepo<ExternalMeasure> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/java/org/apache/griffin/core/measure/repo/GriffinMeasureRepo.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/measure/repo/GriffinMeasureRepo.java
 
b/service/src/main/java/org/apache/griffin/core/measure/repo/GriffinMeasureRepo.java
new file mode 100644
index 0000000..f4058bd
--- /dev/null
+++ 
b/service/src/main/java/org/apache/griffin/core/measure/repo/GriffinMeasureRepo.java
@@ -0,0 +1,25 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package org.apache.griffin.core.measure.repo;
+
+import org.apache.griffin.core.measure.entity.GriffinMeasure;
+
+public interface GriffinMeasureRepo extends MeasureRepo<GriffinMeasure> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/java/org/apache/griffin/core/measure/repo/MeasureRepo.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/measure/repo/MeasureRepo.java 
b/service/src/main/java/org/apache/griffin/core/measure/repo/MeasureRepo.java
index b324f1e..976bec2 100644
--- 
a/service/src/main/java/org/apache/griffin/core/measure/repo/MeasureRepo.java
+++ 
b/service/src/main/java/org/apache/griffin/core/measure/repo/MeasureRepo.java
@@ -23,28 +23,27 @@ package org.apache.griffin.core.measure.repo;
 import org.apache.griffin.core.measure.entity.Measure;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.CrudRepository;
-import org.springframework.stereotype.Repository;
 
 import java.util.List;
 
-@Repository
-public interface MeasureRepo extends CrudRepository<Measure, Long> {
-    List<Measure> findByNameAndDeleted(String name, Boolean deleted);
+public interface MeasureRepo<T extends Measure> extends CrudRepository<T, 
Long> {
 
-    List<Measure> findByDeleted(Boolean deleted);
+    List<T> findByNameAndDeleted(String name, Boolean deleted);
 
-    List<Measure> findByOwnerAndDeleted(String owner, Boolean deleted);
+    List<T> findByDeleted(Boolean deleted);
 
-    Measure findByIdAndDeleted(Long id, Boolean deleted);
+    List<T> findByOwnerAndDeleted(String owner, Boolean deleted);
 
-    @Query("select DISTINCT m.organization from Measure m where m.deleted = 
?1")
+    T findByIdAndDeleted(Long id, Boolean deleted);
+
+    @Query("select DISTINCT m.organization from #{#entityName} m where 
m.deleted = ?1")
     List<String> findOrganizations(Boolean deleted);
 
-    @Query("select m.name from Measure m " +
+    @Query("select m.name from #{#entityName} m " +
             "where m.organization= ?1 and m.deleted= ?2")
     List<String> findNameByOrganization(String organization, Boolean deleted);
 
-    @Query("select m.organization from Measure m " +
+    @Query("select m.organization from #{#entityName} m " +
             "where m.name= ?1")
     String findOrgByName(String measureName);
 

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/java/org/apache/griffin/core/metastore/hive/HiveMetaStoreServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/metastore/hive/HiveMetaStoreServiceImpl.java
 
b/service/src/main/java/org/apache/griffin/core/metastore/hive/HiveMetaStoreServiceImpl.java
index 759e370..67f171f 100644
--- 
a/service/src/main/java/org/apache/griffin/core/metastore/hive/HiveMetaStoreServiceImpl.java
+++ 
b/service/src/main/java/org/apache/griffin/core/metastore/hive/HiveMetaStoreServiceImpl.java
@@ -41,7 +41,7 @@ import java.util.concurrent.TimeUnit;
 
 
 @Service
-@CacheConfig(cacheNames = "hive")
+@CacheConfig(cacheNames = "hive", keyGenerator = "cacheKeyGenerator")
 public class HiveMetaStoreServiceImpl implements HiveMetaStoreService {
 
     private static final Logger LOGGER = 
LoggerFactory.getLogger(HiveMetaStoreService.class);
@@ -55,7 +55,7 @@ public class HiveMetaStoreServiceImpl implements 
HiveMetaStoreService {
     private ThreadPoolExecutor singleThreadExecutor;
 
     public HiveMetaStoreServiceImpl() {
-        singleThreadExecutor = new ThreadPoolExecutor(1, 5, 3, 
TimeUnit.SECONDS, new ArrayBlockingQueue<>(3),new 
ThreadPoolExecutor.DiscardPolicy());
+        singleThreadExecutor = new ThreadPoolExecutor(1, 5, 3, 
TimeUnit.SECONDS, new ArrayBlockingQueue<>(3), new 
ThreadPoolExecutor.DiscardPolicy());
         LOGGER.info("HiveMetaStoreServiceImpl single thread pool created.");
     }
 
@@ -68,10 +68,14 @@ public class HiveMetaStoreServiceImpl implements 
HiveMetaStoreService {
     }
 
     @Override
-    @Cacheable(key = "#root.methodName")
+    @Cacheable
     public Iterable<String> getAllDatabases() {
         Iterable<String> results = null;
         try {
+            if (client == null) {
+                LOGGER.warn("Hive client is null.Please check your hive 
config.");
+                return new ArrayList<>();
+            }
             results = client.getAllDatabases();
         } catch (MetaException e) {
             reconnect();
@@ -82,10 +86,14 @@ public class HiveMetaStoreServiceImpl implements 
HiveMetaStoreService {
 
 
     @Override
-    @Cacheable(key = "#root.methodName.concat(#dbName)")
+    @Cacheable
     public Iterable<String> getAllTableNames(String dbName) {
         Iterable<String> results = null;
         try {
+            if (client == null) {
+                LOGGER.warn("Hive client is null.Please check your hive 
config.");
+                return new ArrayList<>();
+            }
             results = client.getAllTables(getUseDbName(dbName));
         } catch (Exception e) {
             reconnect();
@@ -96,20 +104,20 @@ public class HiveMetaStoreServiceImpl implements 
HiveMetaStoreService {
 
 
     @Override
-    @Cacheable(key = "#root.methodName.concat(#db)")
+    @Cacheable
     public List<Table> getAllTable(String db) {
         return getTables(db);
     }
 
 
     @Override
-    @Cacheable(key = "#root.methodName")
+    @Cacheable
     public Map<String, List<Table>> getAllTable() {
         Map<String, List<Table>> results = new HashMap<>();
         Iterable<String> dbs;
         // if hive.metastore.uris in application.properties configs wrong, 
client will be injected failure and will be null.
         if (client == null) {
-            LOGGER.error("hive client is null.Please check your hive config.");
+            LOGGER.warn("Hive client is null.Please check your hive config.");
             return results;
         }
         dbs = getAllDatabases();
@@ -123,10 +131,14 @@ public class HiveMetaStoreServiceImpl implements 
HiveMetaStoreService {
 
 
     @Override
-    @Cacheable(key = "#root.methodName.concat(#dbName).concat(#tableName)")
+    @Cacheable
     public Table getTable(String dbName, String tableName) {
         Table result = null;
         try {
+            if (client == null) {
+                LOGGER.warn("Hive client is null.Please check your hive 
config.");
+                return null;
+            }
             result = client.getTable(getUseDbName(dbName), tableName);
         } catch (Exception e) {
             reconnect();
@@ -140,6 +152,10 @@ public class HiveMetaStoreServiceImpl implements 
HiveMetaStoreService {
         String useDbName = getUseDbName(db);
         List<Table> allTables = new ArrayList<>();
         try {
+            if (client == null) {
+                LOGGER.warn("Hive client is null.Please check your hive 
config.");
+                return allTables;
+            }
             Iterable<String> tables = client.getAllTables(useDbName);
             for (String table : tables) {
                 Table tmp = client.getTable(db, table);

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/java/org/apache/griffin/core/metric/MetricController.java
----------------------------------------------------------------------
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 f4b97c4..981454c 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
@@ -19,27 +19,44 @@ under the License.
 
 package org.apache.griffin.core.metric;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.griffin.core.metric.model.Metric;
+import org.apache.griffin.core.metric.model.MetricValue;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
 
 /**
  * In griffin, metricName usually equals to measureName, and we only save 
measureName in server.
  */
 
 @RestController
-@RequestMapping("/api/v1/metrics")
+@RequestMapping("/api/v1")
 public class MetricController {
-    private static final Logger LOGGER = 
LoggerFactory.getLogger(MetricController.class);
+
     @Autowired
     private MetricService metricService;
 
-    @RequestMapping(value = "/org", method = RequestMethod.GET)
-    public String getOrgByMeasureName(@RequestParam("measureName") String 
measureName) {
-        return metricService.getOrgByMeasureName(measureName);
+    @RequestMapping(value = "/metrics", method = RequestMethod.GET)
+    public List<Metric> getAllMetrics() {
+        return metricService.getAllMetrics();
+    }
+
+    @RequestMapping(value = "/metrics/values", method = RequestMethod.GET)
+    public List<MetricValue> getMetricValues(@RequestParam("metricName") 
String metricName,
+                                             @RequestParam("size") int size,
+                                             @RequestParam(value = "offset", 
defaultValue = "0") int offset) {
+        return metricService.getMetricValues(metricName, offset, size);
+    }
+
+    @RequestMapping(value = "/metrics/values", method = RequestMethod.POST)
+    public ResponseEntity addMetricValues(@RequestBody List<MetricValue> 
values) {
+        return metricService.addMetricValues(values);
+    }
+
+    @RequestMapping(value = "/metrics/values", method = RequestMethod.DELETE)
+    public ResponseEntity deleteMetricValues(@RequestParam("metricName") 
String metricName) {
+        return metricService.deleteMetricValues(metricName);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/java/org/apache/griffin/core/metric/MetricService.java
----------------------------------------------------------------------
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 4d885df..6b00f1b 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
@@ -20,6 +20,19 @@ under the License.
 package org.apache.griffin.core.metric;
 
 
+import org.apache.griffin.core.metric.model.Metric;
+import org.apache.griffin.core.metric.model.MetricValue;
+import org.springframework.http.ResponseEntity;
+
+import java.util.List;
+
 public interface MetricService {
-    String getOrgByMeasureName(String measureName);
+
+    List<Metric> getAllMetrics();
+
+    List<MetricValue> getMetricValues(String metricName, int offset, int size);
+
+    ResponseEntity addMetricValues(List<MetricValue> values);
+
+    ResponseEntity deleteMetricValues(String metricName);
 }

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/java/org/apache/griffin/core/metric/MetricServiceImpl.java
----------------------------------------------------------------------
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 69a2b8c..1501f94 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
@@ -20,17 +20,82 @@ under the License.
 package org.apache.griffin.core.metric;
 
 
+import org.apache.griffin.core.job.entity.AbstractJob;
+import org.apache.griffin.core.job.repo.JobRepo;
+import org.apache.griffin.core.measure.entity.Measure;
 import org.apache.griffin.core.measure.repo.MeasureRepo;
+import org.apache.griffin.core.metric.model.Metric;
+import org.apache.griffin.core.metric.model.MetricValue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
 @Service
 public class MetricServiceImpl implements MetricService {
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(MetricServiceImpl.class);
+
+    @Autowired
+    private MeasureRepo<Measure> measureRepo;
+    @Autowired
+    private JobRepo<AbstractJob> jobRepo;
     @Autowired
-    private MeasureRepo measureRepo;
+    private MetricStore metricStore;
+
+    @Override
+    public List<Metric> getAllMetrics() {
+        List<Metric> metrics = new ArrayList<>();
+        List<AbstractJob> jobs = jobRepo.findByDeleted(false);
+        List<Measure> measures = measureRepo.findByDeleted(false);
+        Map<Long, Measure> measureMap = 
measures.stream().collect(Collectors.toMap(Measure::getId, 
Function.identity()));
+        for (AbstractJob job : jobs) {
+            List<MetricValue> metricValues = 
getMetricValues(job.getMetricName(), 0, 300);
+            Measure measure = measureMap.get(job.getMeasureId());
+            metrics.add(new Metric(job.getJobName(), measure.getDescription(), 
measure.getOrganization(), measure.getOwner(), metricValues));
+        }
+        return metrics;
+    }
+
+    @Override
+    public List<MetricValue> getMetricValues(String metricName, int offset, 
int size) {
+        try {
+            return metricStore.getMetricValues(metricName, offset, size);
+        } catch (Exception e) {
+            LOGGER.error("Failed to get metric values named {}. {}", 
metricName, e.getMessage());
+        }
+        return Collections.emptyList();
+    }
+
+    @Override
+    public ResponseEntity addMetricValues(List<MetricValue> values) {
+        try {
+            for (MetricValue value : values) {
+                metricStore.addMetricValue(value);
+            }
+            return new ResponseEntity("Add Metric Values Success", 
HttpStatus.CREATED);
+        } catch (Exception e) {
+            LOGGER.error("Failed to add metric values. {}", e.getMessage());
+            return new ResponseEntity("Add Metric Values Failed", 
HttpStatus.INTERNAL_SERVER_ERROR);
+        }
+    }
 
     @Override
-    public String getOrgByMeasureName(String measureName) {
-        return measureRepo.findOrgByName(measureName);
+    public ResponseEntity deleteMetricValues(String metricName) {
+        try {
+            metricStore.deleteMetricValues(metricName);
+            return ResponseEntity.ok("Delete Metric Values Success");
+        } catch (Exception e) {
+            LOGGER.error("Failed to delete metric values named {}. {}", 
metricName, e.getMessage());
+            return new ResponseEntity("Delete Metric Values Failed", 
HttpStatus.INTERNAL_SERVER_ERROR);
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/java/org/apache/griffin/core/metric/MetricStore.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..12068f6
--- /dev/null
+++ b/service/src/main/java/org/apache/griffin/core/metric/MetricStore.java
@@ -0,0 +1,33 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package org.apache.griffin.core.metric;
+
+import org.apache.griffin.core.metric.model.MetricValue;
+
+import java.util.List;
+
+public interface MetricStore {
+
+    List<MetricValue> getMetricValues(String metricName, int from, int size) 
throws Exception;
+
+    void addMetricValue(MetricValue metricValue) throws Exception;
+
+    void deleteMetricValues(String metricName) throws Exception;
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/java/org/apache/griffin/core/metric/MetricStoreImpl.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..1a81aee
--- /dev/null
+++ b/service/src/main/java/org/apache/griffin/core/metric/MetricStoreImpl.java
@@ -0,0 +1,90 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package org.apache.griffin.core.metric;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.griffin.core.metric.model.MetricValue;
+import org.apache.griffin.core.util.JsonUtil;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.nio.entity.NStringEntity;
+import org.apache.http.util.EntityUtils;
+import org.elasticsearch.client.Response;
+import org.elasticsearch.client.RestClient;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+
+@Component
+public class MetricStoreImpl implements MetricStore {
+
+    private RestClient client;
+
+    private ObjectMapper mapper = new ObjectMapper();
+
+    public MetricStoreImpl(@Value("${elasticsearch.host}") String host, 
@Value("${elasticsearch.port}") int port) {
+        client = RestClient.builder(new HttpHost(host, port, "http")).build();
+    }
+
+    @Override
+    public List<MetricValue> getMetricValues(String metricName, int from, int 
size) throws Exception {
+        Map<String, Object> map = new HashMap<>();
+        Map queryParam = Collections.singletonMap("term", 
Collections.singletonMap("name.keyword", metricName));
+        Map sortParam = Collections.singletonMap("tmst", 
Collections.singletonMap("order", "desc"));
+        map.put("query", queryParam);
+        map.put("sort", sortParam);
+        map.put("from", from);
+        map.put("size", size);
+        List<MetricValue> metricValues = new ArrayList<>();
+        HttpEntity entity = new NStringEntity(JsonUtil.toJson(map), 
ContentType.APPLICATION_JSON);
+        Response response = client.performRequest("GET", 
"/griffin/accuracy/_search?filter_path=hits.hits._source",
+                Collections.emptyMap(), entity, new 
BasicHeader("Content-Type", "application/json"));
+        JsonNode jsonNode = 
mapper.readTree(EntityUtils.toString(response.getEntity()));
+        if (jsonNode.hasNonNull("hits") && 
jsonNode.get("hits").hasNonNull("hits")) {
+            for (JsonNode node : jsonNode.get("hits").get("hits")) {
+                JsonNode sourceNode = node.get("_source");
+                metricValues.add(new 
MetricValue(sourceNode.get("name").asText(), 
Long.parseLong(sourceNode.get("tmst").asText()),
+                        JsonUtil.toEntity(sourceNode.get("value").toString(), 
Map.class)));
+            }
+        }
+        return metricValues;
+    }
+
+    @Override
+    public void addMetricValue(MetricValue metricValue) throws Exception {
+        HttpEntity entity = new NStringEntity(JsonUtil.toJson(metricValue), 
ContentType.APPLICATION_JSON);
+        client.performRequest("POST", "/griffin/accuracy", 
Collections.emptyMap(), entity,
+                new BasicHeader("Content-Type", "application/json"));
+
+    }
+
+    @Override
+    public void deleteMetricValues(String metricName) throws Exception {
+        Map param = Collections.singletonMap("query",
+                Collections.singletonMap("term", 
Collections.singletonMap("name.keyword", metricName)));
+        HttpEntity entity = new NStringEntity(JsonUtil.toJson(param), 
ContentType.APPLICATION_JSON);
+        client.performRequest("POST", "/griffin/accuracy/_delete_by_query", 
Collections.emptyMap(),
+                entity, new BasicHeader("Content-Type", "application/json"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/java/org/apache/griffin/core/metric/model/Metric.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/metric/model/Metric.java 
b/service/src/main/java/org/apache/griffin/core/metric/model/Metric.java
new file mode 100644
index 0000000..517c175
--- /dev/null
+++ b/service/src/main/java/org/apache/griffin/core/metric/model/Metric.java
@@ -0,0 +1,82 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package org.apache.griffin.core.metric.model;
+
+import java.util.List;
+
+public class Metric {
+
+    private String name;
+    private String description;
+    private String organization;
+    private String owner;
+    private List<MetricValue> metricValues;
+
+    public Metric() {
+    }
+
+    public Metric(String name, String description, String organization, String 
owner, List<MetricValue> metricValues) {
+        this.name = name;
+        this.description = description;
+        this.organization = organization;
+        this.owner = owner;
+        this.metricValues = metricValues;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getOrganization() {
+        return organization;
+    }
+
+    public void setOrganization(String organization) {
+        this.organization = organization;
+    }
+
+    public String getOwner() {
+        return owner;
+    }
+
+    public void setOwner(String owner) {
+        this.owner = owner;
+    }
+
+    public List<MetricValue> getMetricValues() {
+        return metricValues;
+    }
+
+    public void setMetricValues(List<MetricValue> metricValues) {
+        this.metricValues = metricValues;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/java/org/apache/griffin/core/metric/model/MetricValue.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..4839f9f
--- /dev/null
+++ 
b/service/src/main/java/org/apache/griffin/core/metric/model/MetricValue.java
@@ -0,0 +1,64 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package org.apache.griffin.core.metric.model;
+
+import java.util.Map;
+
+public class MetricValue {
+
+    private String name;
+
+    private Long tmst;
+
+    private Map<String, Object> value;
+
+    public MetricValue() {
+    }
+
+    public MetricValue(String name, Long tmst, Map<String, Object> value) {
+        this.name = name;
+        this.tmst = tmst;
+        this.value = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Long getTmst() {
+        return tmst;
+    }
+
+    public void setTmst(Long tmst) {
+        this.tmst = tmst;
+    }
+
+    public Map<String, Object> getValue() {
+        return value;
+    }
+
+    public void setValue(Map<String, Object> value) {
+        this.value = value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/java/org/apache/griffin/core/util/FSUtil.java
----------------------------------------------------------------------
diff --git a/service/src/main/java/org/apache/griffin/core/util/FSUtil.java 
b/service/src/main/java/org/apache/griffin/core/util/FSUtil.java
new file mode 100644
index 0000000..d7eedca
--- /dev/null
+++ b/service/src/main/java/org/apache/griffin/core/util/FSUtil.java
@@ -0,0 +1,161 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package org.apache.griffin.core.util;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+@Component
+public class FSUtil {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(FSUtil.class);
+
+    private static String fsDefaultName;
+
+    private static FileSystem fileSystem;
+
+    private static FileSystem getFileSystem() {
+        if (fileSystem == null) {
+            initFileSystem();
+        }
+        return fileSystem;
+    }
+
+    public FSUtil(@Value("${fs.defaultFS}") String defaultName) {
+        fsDefaultName = defaultName;
+    }
+
+
+    private static void initFileSystem() {
+        Configuration conf = new Configuration();
+        if (!StringUtils.isEmpty(fsDefaultName)) {
+            conf.set("fs.defaultFS", fsDefaultName);
+            LOGGER.info("Setting fs.defaultFS:{}", fsDefaultName);
+        }
+        if (StringUtils.isEmpty(conf.get("fs.hdfs.impl"))) {
+            LOGGER.info("Setting fs.hdfs.impl:{}", 
org.apache.hadoop.hdfs.DistributedFileSystem.class.getName());
+            conf.set("fs.hdfs.impl", 
org.apache.hadoop.hdfs.DistributedFileSystem.class.getName());
+        }
+        if (StringUtils.isEmpty(conf.get("fs.file.impl"))) {
+            LOGGER.info("Setting fs.file.impl:{}", 
org.apache.hadoop.fs.LocalFileSystem.class.getName());
+            conf.set("fs.file.impl", 
org.apache.hadoop.fs.LocalFileSystem.class.getName());
+        }
+        try {
+            fileSystem = FileSystem.get(conf);
+        } catch (Exception e) {
+            LOGGER.error("Can not get hdfs file system. {}", e.getMessage());
+        }
+
+    }
+
+
+    /**
+     * list all sub dir of a dir
+     */
+    public static List<String> listSubDir(String dir) throws IOException {
+        if (getFileSystem() == null) {
+            throw new NullPointerException("FileSystem is null.Please check 
your hdfs config default name.");
+        }
+        List<String> fileList = new ArrayList<>();
+        Path path = new Path(dir);
+        if (fileSystem.isFile(path)) {
+            return fileList;
+        }
+        FileStatus[] statuses = fileSystem.listStatus(path);
+        for (FileStatus fileStatus : statuses) {
+            if (fileStatus.isDirectory()) {
+                fileList.add(fileStatus.getPath().toString());
+            }
+        }
+        return fileList;
+
+    }
+
+    /**
+     * get all file status of a dir.
+     */
+    public static List<FileStatus> listFileStatus(String dir) throws 
IOException {
+        if (getFileSystem() == null) {
+            throw new NullPointerException("FileSystem is null.Please check 
your hdfs config default name.");
+        }
+        List<FileStatus> fileStatusList = new ArrayList<>();
+        Path path = new Path(dir);
+        if (fileSystem.isFile(path)) {
+            return fileStatusList;
+        }
+        FileStatus[] statuses = fileSystem.listStatus(path);
+        for (FileStatus fileStatus : statuses) {
+            if (!fileStatus.isDirectory()) {
+                fileStatusList.add(fileStatus);
+            }
+        }
+        return fileStatusList;
+    }
+
+    /**
+     * touch file
+     */
+    public static void touch(String filePath) throws IOException {
+        if (getFileSystem() == null) {
+            throw new NullPointerException("FileSystem is null.Please check 
your hdfs config default name.");
+        }
+        Path path = new Path(filePath);
+        FileStatus st;
+        if (fileSystem.exists(path)) {
+            st = fileSystem.getFileStatus(path);
+            if (st.isDirectory()) {
+                throw new IOException(filePath + " is a directory");
+            } else if (st.getLen() != 0) {
+                throw new IOException(filePath + " must be a zero-length 
file");
+            }
+        }
+        FSDataOutputStream out = null;
+        try {
+            out = fileSystem.create(path);
+        } finally {
+            if (out != null) {
+                out.close();
+            }
+        }
+
+    }
+
+
+    public static boolean isFileExist(String path) throws IOException {
+        if (getFileSystem() == null) {
+            throw new NullPointerException("FileSystem is null.Please check 
your hdfs config default name.");
+        }
+        Path hdfsPath = new Path(path);
+        return fileSystem.isFile(hdfsPath) || fileSystem.isDirectory(hdfsPath);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/java/org/apache/griffin/core/util/JsonUtil.java
----------------------------------------------------------------------
diff --git a/service/src/main/java/org/apache/griffin/core/util/JsonUtil.java 
b/service/src/main/java/org/apache/griffin/core/util/JsonUtil.java
index 8a3f686..442901e 100644
--- a/service/src/main/java/org/apache/griffin/core/util/JsonUtil.java
+++ b/service/src/main/java/org/apache/griffin/core/util/JsonUtil.java
@@ -21,8 +21,10 @@ package org.apache.griffin.core.util;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectWriter;
+import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.config.PropertiesFactoryBean;
@@ -34,40 +36,29 @@ import java.util.Properties;
 public class JsonUtil {
     private static final Logger LOGGER = 
LoggerFactory.getLogger(JsonUtil.class);
 
-    public static String toJson(Object obj) {
+    public static String toJson(Object obj) throws JsonProcessingException {
         ObjectMapper mapper = new ObjectMapper();
-        String jsonStr = null;
-        try {
-            jsonStr = mapper.writeValueAsString(obj);
-        } catch (JsonProcessingException e) {
-            LOGGER.error("convert to json failed. {}", obj);
-        }
-        return jsonStr;
+        return mapper.writeValueAsString(obj);
     }
 
-    public static String toJsonWithFormat(Object obj) {
+    public static String toJsonWithFormat(Object obj) throws 
JsonProcessingException {
         ObjectWriter mapper = new 
ObjectMapper().writer().withDefaultPrettyPrinter();
-        String jsonStr = null;
-        try {
-            jsonStr = mapper.writeValueAsString(obj);
-        } catch (JsonProcessingException e) {
-            LOGGER.error("convert to json failed. {}", obj);
-        }
-        return jsonStr;
+        return mapper.writeValueAsString(obj);
     }
 
     public static <T> T toEntity(String jsonStr, Class<T> type) throws 
IOException {
-        if (jsonStr == null || jsonStr.length() == 0) {
-            LOGGER.warn("jsonStr {} is empty!", type);
+        if (StringUtils.isEmpty(jsonStr)) {
+            LOGGER.warn("Json string {} is empty!", type);
             return null;
         }
         ObjectMapper mapper = new ObjectMapper();
+        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, 
false);
         return mapper.readValue(jsonStr, type);
     }
 
     public static <T> T toEntity(String jsonStr, TypeReference type) throws 
IOException {
-        if (jsonStr == null || jsonStr.length() == 0) {
-            LOGGER.warn("jsonStr {} is empty!", type);
+        if (StringUtils.isEmpty(jsonStr)) {
+            LOGGER.warn("Json string {} is empty!", type);
             return null;
         }
         ObjectMapper mapper = new ObjectMapper();

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/java/org/apache/griffin/core/util/PropertiesUtil.java
----------------------------------------------------------------------
diff --git 
a/service/src/main/java/org/apache/griffin/core/util/PropertiesUtil.java 
b/service/src/main/java/org/apache/griffin/core/util/PropertiesUtil.java
index ee57ddd..728ee9e 100644
--- a/service/src/main/java/org/apache/griffin/core/util/PropertiesUtil.java
+++ b/service/src/main/java/org/apache/griffin/core/util/PropertiesUtil.java
@@ -22,23 +22,24 @@ package org.apache.griffin.core.util;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.config.PropertiesFactoryBean;
-import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
 
 import java.io.IOException;
 import java.util.Properties;
 
 public class PropertiesUtil {
     private static final Logger LOGGER = 
LoggerFactory.getLogger(PropertiesUtil.class);
-    
-    public static Properties getProperties(String propertiesPath) {
-        PropertiesFactoryBean propertiesFactoryBean = new 
PropertiesFactoryBean();
-        propertiesFactoryBean.setLocation(new 
ClassPathResource(propertiesPath));
+
+    public static Properties getProperties(String path, Resource resource) {
+        PropertiesFactoryBean propFactoryBean = new PropertiesFactoryBean();
         Properties properties = null;
         try {
-            propertiesFactoryBean.afterPropertiesSet();
-            properties = propertiesFactoryBean.getObject();
+            propFactoryBean.setLocation(resource);
+            propFactoryBean.afterPropertiesSet();
+            properties = propFactoryBean.getObject();
+            LOGGER.info("Read properties successfully from {}.", path);
         } catch (IOException e) {
-            LOGGER.error("get properties from {} failed. {}", propertiesPath, 
e.getMessage());
+            LOGGER.error("Get properties from {} failed. {}", path, e);
         }
         return properties;
     }

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/java/org/apache/griffin/core/util/TimeUtil.java
----------------------------------------------------------------------
diff --git a/service/src/main/java/org/apache/griffin/core/util/TimeUtil.java 
b/service/src/main/java/org/apache/griffin/core/util/TimeUtil.java
new file mode 100644
index 0000000..859fe5b
--- /dev/null
+++ b/service/src/main/java/org/apache/griffin/core/util/TimeUtil.java
@@ -0,0 +1,119 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package org.apache.griffin.core.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.IllegalFormatException;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class TimeUtil {
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(TimeUtil.class);
+
+    public static Long str2Long(String timeStr) {
+        if (timeStr == null) {
+            LOGGER.error("Time string can not be empty.");
+            return 0L;
+        }
+        String trimTimeStr = timeStr.trim();
+        boolean positive = true;
+        if (trimTimeStr.startsWith("-")) {
+            trimTimeStr = trimTimeStr.substring(1);
+            positive = false;
+        }
+
+        String timePattern = "(?i)\\d+(ms|s|m|h|d)";
+        Pattern pattern = Pattern.compile(timePattern);
+        Matcher matcher = pattern.matcher(trimTimeStr);
+        List<String> list = new ArrayList<>();
+        while (matcher.find()) {
+            String group = matcher.group();
+            list.add(group.toLowerCase());
+        }
+        long time = 0;
+        for (int i = 0; i < list.size(); i++) {
+            long t = milliseconds(list.get(i).toLowerCase());
+            if (positive) {
+                time += t;
+            } else {
+                time -= t;
+            }
+        }
+        return time;
+    }
+
+    private static Long milliseconds(String str) {
+        try {
+            if (str.endsWith("ms")) {
+                return milliseconds(Long.parseLong(str.substring(0, 
str.length() - 2)), TimeUnit.MILLISECONDS);
+            } else if (str.endsWith("s")) {
+                return milliseconds(Long.parseLong(str.substring(0, 
str.length() - 1)), TimeUnit.SECONDS);
+            } else if (str.endsWith("m")) {
+                return milliseconds(Long.parseLong(str.substring(0, 
str.length() - 1)), TimeUnit.MINUTES);
+            } else if (str.endsWith("h")) {
+                return milliseconds(Long.parseLong(str.substring(0, 
str.length() - 1)), TimeUnit.HOURS);
+            } else if (str.endsWith("d")) {
+                return milliseconds(Long.parseLong(str.substring(0, 
str.length() - 1)), TimeUnit.DAYS);
+            } else {
+                LOGGER.error("Time string format error.It only supports 
d(day),h(hour),m(minute),s(second),ms(millsecond).Please check your time 
format.)");
+                throw new IllegalArgumentException();
+            }
+        } catch (Exception e) {
+            LOGGER.error("Parse exception occur. {}",e);
+            return 0L;
+        }
+    }
+
+    private static Long milliseconds(long duration, TimeUnit unit) {
+        return unit.toMillis(duration);
+    }
+
+    public static String format(String timeFormat, long time) {
+        String timePattern = "#(?:\\\\#|[^#])*#";
+        Date t = new Date(time);
+        Pattern ptn = Pattern.compile(timePattern);
+        Matcher matcher = ptn.matcher(timeFormat);
+        StringBuffer sb = new StringBuffer();
+        while (matcher.find()) {
+            String group = matcher.group();
+            String content = group.substring(1, group.length() - 1);
+            String pattern = refreshEscapeHashTag(content);
+            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+            matcher.appendReplacement(sb, sdf.format(t));
+        }
+        matcher.appendTail(sb);
+        String endString = refreshEscapeHashTag(sb.toString());
+        return endString;
+    }
+
+    private static String refreshEscapeHashTag(String str) {
+        String escapeHashTagPattern = "\\\\#";
+        String hashTag = "#";
+        return str.replaceAll(escapeHashTagPattern, hashTag);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/resources/Init_quartz_derby.sql
----------------------------------------------------------------------
diff --git a/service/src/main/resources/Init_quartz_derby.sql 
b/service/src/main/resources/Init_quartz_derby.sql
new file mode 100644
index 0000000..ba517db
--- /dev/null
+++ b/service/src/main/resources/Init_quartz_derby.sql
@@ -0,0 +1,187 @@
+
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership.  The ASF licenses this file
+-- to you under the Apache License, Version 2.0 (the
+-- "License"); you may not use this file except in compliance
+-- with the License.  You may obtain a copy of the License at
+-- 
+--   http://www.apache.org/licenses/LICENSE-2.0
+-- 
+-- Unless required by applicable law or agreed to in writing,
+-- software distributed under the License is distributed on an
+-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+-- KIND, either express or implied.  See the License for the
+-- specific language governing permissions and limitations
+-- under the License.
+
+
+DROP TABLE QRTZ_FIRED_TRIGGERS;
+DROP TABLE QRTZ_PAUSED_TRIGGER_GRPS;
+DROP TABLE QRTZ_SCHEDULER_STATE;
+DROP TABLE QRTZ_LOCKS;
+DROP TABLE QRTZ_SIMPLE_TRIGGERS;
+DROP TABLE QRTZ_SIMPROP_TRIGGERS;
+DROP TABLE QRTZ_CRON_TRIGGERS;
+DROP TABLE QRTZ_BLOB_TRIGGERS;
+DROP TABLE QRTZ_TRIGGERS;
+DROP TABLE QRTZ_JOB_DETAILS;
+DROP TABLE QRTZ_CALENDARS;
+
+CREATE TABLE QRTZ_JOB_DETAILS(
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  JOB_NAME VARCHAR(200) NOT NULL,
+  JOB_GROUP VARCHAR(200) NOT NULL,
+  DESCRIPTION VARCHAR(250),
+  JOB_CLASS_NAME VARCHAR(250) NOT NULL,
+  IS_DURABLE BOOLEAN NOT NULL,
+  IS_NONCONCURRENT BOOLEAN NOT NULL,
+  IS_UPDATE_DATA BOOLEAN NOT NULL,
+  REQUESTS_RECOVERY BOOLEAN NOT NULL,
+  JOB_DATA BLOB,
+  PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP));
+--   ENGINE=InnoDB;
+
+CREATE TABLE QRTZ_TRIGGERS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  TRIGGER_NAME VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP VARCHAR(200) NOT NULL,
+  JOB_NAME VARCHAR(200) NOT NULL,
+  JOB_GROUP VARCHAR(200) NOT NULL,
+  DESCRIPTION VARCHAR(250),
+  NEXT_FIRE_TIME BIGINT,
+  PREV_FIRE_TIME BIGINT,
+  PRIORITY INTEGER,
+  TRIGGER_STATE VARCHAR(16) NOT NULL,
+  TRIGGER_TYPE VARCHAR(8) NOT NULL,
+  START_TIME BIGINT NOT NULL,
+  END_TIME BIGINT,
+  CALENDAR_NAME VARCHAR(200),
+  MISFIRE_INSTR SMALLINT,
+  JOB_DATA BLOB,
+  PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+  FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
+  REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP));
+--   ENGINE=InnoDB;
+
+CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  TRIGGER_NAME VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP VARCHAR(200) NOT NULL,
+  REPEAT_COUNT BIGINT NOT NULL,
+  REPEAT_INTERVAL BIGINT NOT NULL,
+  TIMES_TRIGGERED BIGINT NOT NULL,
+  PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+  FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+  REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP));
+--   ENGINE=InnoDB;
+
+CREATE TABLE QRTZ_CRON_TRIGGERS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  TRIGGER_NAME VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP VARCHAR(200) NOT NULL,
+  CRON_EXPRESSION VARCHAR(120) NOT NULL,
+  TIME_ZONE_ID VARCHAR(80),
+  PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+  FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+  REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP));
+--   ENGINE=InnoDB;
+
+CREATE TABLE QRTZ_SIMPROP_TRIGGERS
+(
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  TRIGGER_NAME VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP VARCHAR(200) NOT NULL,
+  STR_PROP_1 VARCHAR(512),
+  STR_PROP_2 VARCHAR(512),
+  STR_PROP_3 VARCHAR(512),
+  INT_PROP_1 INT,
+  INT_PROP_2 INT,
+  LONG_PROP_1 BIGINT,
+  LONG_PROP_2 BIGINT,
+  DEC_PROP_1 NUMERIC(13,4),
+  DEC_PROP_2 NUMERIC(13,4),
+  BOOL_PROP_1 BOOLEAN,
+  BOOL_PROP_2 BOOLEAN,
+  PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+  FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+  REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP));
+--   ENGINE=InnoDB;
+
+CREATE TABLE QRTZ_BLOB_TRIGGERS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  TRIGGER_NAME VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP VARCHAR(200) NOT NULL,
+  BLOB_DATA BLOB,
+  PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+  FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
+  REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP));
+
+CREATE INDEX SCHED_NAME ON QRTZ_BLOB_TRIGGERS(SCHED_NAME);
+CREATE INDEX TRIGGER_NAME ON QRTZ_BLOB_TRIGGERS(TRIGGER_NAME);
+CREATE INDEX TRIGGER_GROUP ON QRTZ_BLOB_TRIGGERS(TRIGGER_GROUP);
+
+CREATE TABLE QRTZ_CALENDARS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  CALENDAR_NAME VARCHAR(200) NOT NULL,
+  CALENDAR BLOB NOT NULL,
+  PRIMARY KEY (SCHED_NAME,CALENDAR_NAME));
+
+CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  TRIGGER_GROUP VARCHAR(200) NOT NULL,
+  PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP));
+
+CREATE TABLE QRTZ_FIRED_TRIGGERS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  ENTRY_ID VARCHAR(95) NOT NULL,
+  TRIGGER_NAME VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP VARCHAR(200) NOT NULL,
+  INSTANCE_NAME VARCHAR(200) NOT NULL,
+  FIRED_TIME BIGINT NOT NULL,
+  SCHED_TIME BIGINT NOT NULL,
+  PRIORITY INTEGER NOT NULL,
+  STATE VARCHAR(16) NOT NULL,
+  JOB_NAME VARCHAR(200),
+  JOB_GROUP VARCHAR(200),
+  IS_NONCONCURRENT BOOLEAN,
+  REQUESTS_RECOVERY BOOLEAN,
+  PRIMARY KEY (SCHED_NAME,ENTRY_ID));
+
+CREATE TABLE QRTZ_SCHEDULER_STATE (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  INSTANCE_NAME VARCHAR(200) NOT NULL,
+  LAST_CHECKIN_TIME BIGINT NOT NULL,
+  CHECKIN_INTERVAL BIGINT NOT NULL,
+  PRIMARY KEY (SCHED_NAME,INSTANCE_NAME));
+
+CREATE TABLE QRTZ_LOCKS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  LOCK_NAME VARCHAR(40) NOT NULL,
+  PRIMARY KEY (SCHED_NAME,LOCK_NAME));
+
+CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON 
QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
+CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);
+
+CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
+CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
+CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_N_STATE ON 
QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_N_G_STATE ON 
QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON 
QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
+CREATE INDEX IDX_QRTZ_T_NFT_ST ON 
QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
+CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON 
QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
+CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON 
QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
+CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON 
QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
+
+CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON 
QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
+CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON 
QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
+CREATE INDEX IDX_QRTZ_FT_J_G ON 
QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
+CREATE INDEX IDX_QRTZ_FT_T_G ON 
QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
+CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
+
+commit;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/resources/application.properties
----------------------------------------------------------------------
diff --git a/service/src/main/resources/application.properties 
b/service/src/main/resources/application.properties
index 15f9db1..3e8d600 100644
--- a/service/src/main/resources/application.properties
+++ b/service/src/main/resources/application.properties
@@ -17,15 +17,15 @@
 # under the License.
 #
 
-spring.datasource.url= 
jdbc:mysql://localhost:3306/quartz?autoReconnect=true&useSSL=false
-spring.datasource.username =griffin
-spring.datasource.password =123456
-spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+spring.datasource.url = 
jdbc:mysql://localhost:3306/quartz?autoReconnect=true&useSSL=false
+spring.datasource.username = griffin
+spring.datasource.password = 123456
+spring.datasource.driver-class-name = com.mysql.jdbc.Driver
 
 # Hibernate ddl auto (validate,create, create-drop, update)
 spring.jpa.hibernate.ddl-auto = update
-spring.jpa.show-sql=true
-spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
+spring.jpa.show-sql = true
+spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
 # Naming strategy
 spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
 
@@ -39,10 +39,19 @@ hive.hmshandler.retry.interval = 2000ms
 kafka.schema.registry.url = http://localhost:8081
 
 # jobInstance
-jobInstance.fixedDelay.in.milliseconds=60000
+jobInstance.fixedDelay.in.milliseconds = 60000
+# default job instance expired time is 7 days that is 604800000 milliseconds
+jobInstance.expired.milliseconds = 604800000
 
 # spring cache
-cache.evict.hive.fixedRate.in.milliseconds=900000
+cache.evict.hive.fixedRate.in.milliseconds = 900000
+
+# predicate job
+predicate.job.interval = 5m
+predicate.job.repeat.count = 12
+
+# external properties directory location
+external.config.location =
 
 #login strategy
 login.strategy = default
@@ -52,4 +61,11 @@ ldap.url=ldap://<ldap url>
 ldap.domain=<account domain>
 ldap.dc=<domain components config>
 ldap.connect-timeout=<connect timeout config>
-ldap.read-timeout=<read timeout config>
\ No newline at end of file
+ldap.read-timeout=<read timeout config>
+
+#hdfs
+fs.defaultFS = hdfs://hdfs-default-name
+
+# elasticsearch
+elasticsearch.host = localhost
+elasticsearch.port = 9200
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/main/resources/sparkJob.properties
----------------------------------------------------------------------
diff --git a/service/src/main/resources/sparkJob.properties 
b/service/src/main/resources/sparkJob.properties
index 7e0e48c..f9fd2f9 100644
--- a/service/src/main/resources/sparkJob.properties
+++ b/service/src/main/resources/sparkJob.properties
@@ -18,28 +18,27 @@
 #
 
 # spark required
-sparkJob.file=hdfs:///griffin/griffin-measure.jar
+sparkJob.file=hdfs://apollo-phx-nn-ha/apps/hdmi-technology/b_des/griffin/jar/griffin-measure.jar
 sparkJob.className=org.apache.griffin.measure.Application
-sparkJob.args_1=hdfs:///griffin/json/env.json
+sparkJob.args_1=hdfs://apollo-phx-nn-ha/apps/hdmi-technology/b_des/griffin/conf/env.json
 sparkJob.args_3=hdfs,raw
 
 sparkJob.name=griffin
-sparkJob.queue=default
+sparkJob.queue=hdlq-gdi-sla
 
 # options
-sparkJob.numExecutors=2
+sparkJob.numExecutors=10
 sparkJob.executorCores=1
-sparkJob.driverMemory=1g
-sparkJob.executorMemory=1g
+sparkJob.driverMemory=2g
+sparkJob.executorMemory=2g
 
 # shouldn't config in server, but in
-sparkJob.spark.jars.packages=com.databricks:spark-avro_2.10:2.0.1
-sparkJob.jars_1=hdfs:///livy/datanucleus-api-jdo-3.2.6.jar
-sparkJob.jars_2=hdfs:///livy/datanucleus-core-3.2.10.jar
-sparkJob.jars_3=hdfs:///livy/datanucleus-rdbms-3.2.9.jar
+sparkJob.jars = 
hdfs://apollo-phx-nn-ha/apps/hdmi-technology/b_des/griffin/livy/spark-avro_2.11-2.0.1.jar;\
+  
hdfs://apollo-phx-nn-ha/apps/hdmi-technology/b_des/griffin/livy/datanucleus-api-jdo-3.2.6.jar;\
+  
hdfs://apollo-phx-nn-ha/apps/hdmi-technology/b_des/griffin/livy/datanucleus-core-3.2.10.jar;\
+  
hdfs://apollo-phx-nn-ha/apps/hdmi-technology/b_des/griffin/livy/datanucleus-rdbms-3.2.9.jar
 
-# partitionItem
-sparkJob.dateAndHour=dt,hour
+spark.yarn.dist.files = 
hdfs://apollo-phx-nn-ha/apps/hdmi-technology/b_des/griffin/livy/hive-site.xml
 
 # livy
 # livy.uri=http://10.9.246.187:8998/batches

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/test/java/org/apache/griffin/core/job/JobControllerTest.java
----------------------------------------------------------------------
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 a73ba73..d3fdd97 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
@@ -1,163 +1,148 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-package org.apache.griffin.core.job;
-
-import org.apache.griffin.core.job.entity.JobHealth;
-import org.apache.griffin.core.job.entity.JobInstance;
-import org.apache.griffin.core.job.entity.JobRequestBody;
-import org.apache.griffin.core.job.entity.LivySessionStates;
-import org.apache.griffin.core.util.GriffinOperationMessage;
-import org.apache.griffin.core.util.URLHelper;
-import org.codehaus.jackson.map.ObjectMapper;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.http.MediaType;
-import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.test.web.servlet.MockMvc;
-
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.mockito.BDDMockito.given;
-import static 
org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
-import static 
org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
-import static 
org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-import static 
org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-@RunWith(SpringRunner.class)
-@WebMvcTest(value = JobController.class, secure = false)
-public class JobControllerTest {
-    @Autowired
-    private MockMvc mvc;
-
-    @MockBean
-    private JobService service;
-
-    @Before
-    public void setup() {
-    }
-
-
-    @Test
-    public void testGetJobs() throws Exception {
-        Map<String, Serializable> map = new HashMap<>();
-        map.put("jobName", "job1");
-        map.put("groupName", "BA");
-        given(service.getAliveJobs()).willReturn(Arrays.asList(map));
-
-        mvc.perform(get(URLHelper.API_VERSION_PATH + 
"/jobs/").contentType(MediaType.APPLICATION_JSON))
-                .andExpect(status().isOk())
-                .andExpect(jsonPath("$.[0].jobName", is("job1")));
-    }
-
-    @Test
-    public void testAddJobForSuccess() throws Exception {
-        String groupName = "BA";
-        String jobName = "job1";
-        long measureId = 0;
-        JobRequestBody jobRequestBody = new JobRequestBody("YYYYMMdd-HH", 
"YYYYMMdd-HH", "111", "20170607", "100");
-        String schedulerRequestBodyJson = new 
ObjectMapper().writeValueAsString(jobRequestBody);
-        given(service.addJob(groupName, jobName, measureId, 
jobRequestBody)).willReturn(GriffinOperationMessage.CREATE_JOB_SUCCESS);
-
-        mvc.perform(post(URLHelper.API_VERSION_PATH + "/jobs").param("group", 
groupName).param("jobName", jobName)
-                .param("measureId", String.valueOf(measureId))
-                .contentType(MediaType.APPLICATION_JSON)
-                .content(schedulerRequestBodyJson))
-                .andExpect(status().isOk())
-                .andExpect(jsonPath("$.code", is(205)))
-                .andExpect(jsonPath("$.description", is("Create Job Succeed")))
-                .andDo(print());
-    }
-
-    @Test
-    public void testAddJobForFail() throws Exception {
-        String groupName = "BA";
-        String jobName = "job1";
-        long measureId = 0;
-        JobRequestBody jobRequestBody = new JobRequestBody("YYYYMMdd-HH", 
"YYYYMMdd-HH", "111", "20170607", "100");
-        String schedulerRequestBodyJson = new 
ObjectMapper().writeValueAsString(jobRequestBody);
-        given(service.addJob(groupName, jobName, measureId, 
jobRequestBody)).willReturn(GriffinOperationMessage.CREATE_JOB_FAIL);
-
-        mvc.perform(post(URLHelper.API_VERSION_PATH + "/jobs").param("group", 
groupName).param("jobName", jobName)
-                .param("measureId", String.valueOf(measureId))
-                .contentType(MediaType.APPLICATION_JSON)
-                .content(schedulerRequestBodyJson))
-                .andExpect(status().isOk())
-                .andExpect(jsonPath("$.code", is(405)))
-                .andExpect(jsonPath("$.description", is("Create Job Failed")))
-                .andDo(print());
-    }
-
-    @Test
-    public void testDeleteJobForSuccess() throws Exception {
-        String groupName = "BA";
-        String jobName = "job1";
-        given(service.deleteJob(groupName, 
jobName)).willReturn(GriffinOperationMessage.DELETE_JOB_SUCCESS);
-
-        mvc.perform(delete(URLHelper.API_VERSION_PATH + 
"/jobs").param("group", groupName).param("jobName", jobName))
-                .andExpect(status().isOk())
-                .andExpect(jsonPath("$.code", is(206)))
-                .andExpect(jsonPath("$.description", is("Delete Job 
Succeed")));
-    }
-
-    @Test
-    public void testDeleteJobForFail() throws Exception {
-        String groupName = "BA";
-        String jobName = "job1";
-        given(service.deleteJob(groupName, 
jobName)).willReturn(GriffinOperationMessage.DELETE_JOB_FAIL);
-
-        mvc.perform(delete(URLHelper.API_VERSION_PATH + 
"/jobs").param("group", groupName).param("jobName", jobName))
-                .andExpect(status().isOk())
-                .andExpect(jsonPath("$.code", is(406)))
-                .andExpect(jsonPath("$.description", is("Delete Job Failed")));
-    }
-
-    @Test
-    public void testFindInstancesOfJob() throws Exception {
-        String groupName = "BA";
-        String jobName = "job1";
-        int page = 0;
-        int size = 2;
-        JobInstance jobInstance = new JobInstance(groupName, jobName, 1, 
LivySessionStates.State.running, "", "", System.currentTimeMillis());
-        given(service.findInstancesOfJob(groupName, jobName, page, 
size)).willReturn(Arrays.asList(jobInstance));
-
-        mvc.perform(get(URLHelper.API_VERSION_PATH + 
"/jobs/instances").param("group", groupName).param("jobName", jobName)
-                .param("page", String.valueOf(page)).param("size", 
String.valueOf(size)))
-                .andExpect(status().isOk())
-                .andExpect(jsonPath("$.[0].groupName", is("BA")));
-    }
-
-    @Test
-    public void testGetHealthInfo() throws Exception {
-        JobHealth jobHealth = new JobHealth(1, 3);
-        given(service.getHealthInfo()).willReturn(jobHealth);
-
-        mvc.perform(get(URLHelper.API_VERSION_PATH + "/jobs/health"))
-                .andExpect(status().isOk())
-                .andExpect(jsonPath("$.healthyJobCount", is(1)));
-    }
-}
+///*
+//Licensed to the Apache Software Foundation (ASF) under one
+//or more contributor license agreements.  See the NOTICE file
+//distributed with this work for additional information
+//regarding copyright ownership.  The ASF licenses this file
+//to you under the Apache License, Version 2.0 (the
+//"License"); you may not use this file except in compliance
+//with the License.  You may obtain a copy of the License at
+//
+//  http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing,
+//software distributed under the License is distributed on an
+//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+//KIND, either express or implied.  See the License for the
+//specific language governing permissions and limitations
+//under the License.
+//*/
+//
+//package org.apache.griffin.core.job;
+//
+//import org.apache.griffin.core.job.entity.*;
+//import org.apache.griffin.core.util.GriffinOperationMessage;
+//import org.apache.griffin.core.util.JsonUtil;
+//import org.apache.griffin.core.util.URLHelper;
+//import org.junit.Before;
+//import org.junit.Test;
+//import org.junit.runner.RunWith;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+//import org.springframework.boot.test.mock.mockito.MockBean;
+//import org.springframework.http.MediaType;
+//import org.springframework.test.context.junit4.SpringRunner;
+//import org.springframework.test.web.servlet.MockMvc;
+//
+//import java.io.Serializable;
+//import java.util.Arrays;
+//import java.util.HashMap;
+//import java.util.Map;
+//
+//import static org.hamcrest.CoreMatchers.is;
+//import static org.mockito.BDDMockito.given;
+//import static 
org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+//import static 
org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+//import static 
org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+//import static 
org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+//
+//@RunWith(SpringRunner.class)
+//@WebMvcTest(value = JobController.class, secure = false)
+//public class JobControllerTest {
+//    @Autowired
+//    private MockMvc mvc;
+//
+//    @MockBean
+//    private JobService service;
+//
+//    @Before
+//    public void setup() {
+//    }
+//
+//
+//    @Test
+//    public void testGetJobs() throws Exception {
+//        JobDataBean jobBean = new JobDataBean();
+//        jobBean.setJobName("job1");
+//        given(service.getAliveJobs()).willReturn(Arrays.asList(jobBean));
+//
+//        mvc.perform(get(URLHelper.API_VERSION_PATH + 
"/jobs/").contentType(MediaType.APPLICATION_JSON))
+//                .andExpect(status().isOk())
+//                .andExpect(jsonPath("$.[0].jobName", is("job1")));
+//    }
+//
+//    @Test
+//    public void testAddJobForSuccess() throws Exception {
+//        JobSchedule jobSchedule = new JobSchedule(1L, "jobName","0 0/4 * * * 
?", null,null);
+//        
given(service.addJob(jobSchedule)).willReturn(GriffinOperationMessage.CREATE_JOB_SUCCESS);
+//
+//        mvc.perform(post(URLHelper.API_VERSION_PATH + "/job")
+//                .contentType(MediaType.APPLICATION_JSON)
+//                .content("{\"measure.id\": 1,\"cron.expression\": \"0 0/4 * 
* * ?\"}"))
+//                .andExpect(status().isOk())
+//                .andExpect(jsonPath("$.code", is(205)))
+//                .andExpect(jsonPath("$.description", is("Create Job 
Succeed")))
+//                .andDo(print());
+//    }
+//
+//    @Test
+//    public void testAddJobForFail() throws Exception {
+//        Map configMap = new HashMap();
+//        configMap.put("interval", "1m");
+//        configMap.put("repeat", "2");
+//        JobSchedule jobSchedule = new JobSchedule(1L, "jobName","0 0/4 * * * 
?", configMap,null);
+//        
given(service.addJob(jobSchedule)).willReturn(GriffinOperationMessage.CREATE_JOB_FAIL);
+//
+//        mvc.perform(post(URLHelper.API_VERSION_PATH + "/job")
+//                .contentType(MediaType.APPLICATION_JSON)
+//                .content(JsonUtil.toJson(jobSchedule)))
+//                .andExpect(status().isOk())
+//                .andExpect(jsonPath("$.code", is(405)))
+//                .andExpect(jsonPath("$.description", is("Create Job 
Failed")))
+//                .andDo(print());
+//    }
+//
+//    @Test
+//    public void testDeleteJobForSuccess() throws Exception {
+//        String jobName = "job1";
+//        
given(service.deleteJob(jobName)).willReturn(GriffinOperationMessage.DELETE_JOB_SUCCESS);
+//
+//        mvc.perform(delete(URLHelper.API_VERSION_PATH + 
"/job").param("jobName", jobName))
+//                .andExpect(status().isOk())
+//                .andExpect(jsonPath("$.code", is(206)))
+//                .andExpect(jsonPath("$.description", is("Delete Job 
Succeed")));
+//    }
+//
+//    @Test
+//    public void testDeleteJobForFail() throws Exception {
+//        String jobName = "job1";
+//        
given(service.deleteJob(jobName)).willReturn(GriffinOperationMessage.DELETE_JOB_FAIL);
+//
+//        mvc.perform(delete(URLHelper.API_VERSION_PATH + 
"/job").param("jobName", jobName))
+//                .andExpect(status().isOk())
+//                .andExpect(jsonPath("$.code", is(406)))
+//                .andExpect(jsonPath("$.description", is("Delete Job 
Failed")));
+//    }
+//
+//    @Test
+//    public void testFindInstancesOfJob() throws Exception {
+//        int page = 0;
+//        int size = 2;
+//        JobInstanceBean jobInstance = new JobInstanceBean(1L,  
LivySessionStates.State.running, "", "", 
System.currentTimeMillis(),System.currentTimeMillis());
+//        given(service.findInstancesOfJob(1L, page, 
size)).willReturn(Arrays.asList(jobInstance));
+//
+//        mvc.perform(get(URLHelper.API_VERSION_PATH + 
"/jobs/instances").param("jobId",String.valueOf(1L))
+//                .param("page", String.valueOf(page)).param("size", 
String.valueOf(size)))
+//                .andExpect(status().isOk())
+//                .andExpect(jsonPath("$.[0].jobId", is(1)));
+//    }
+//
+//    @Test
+//    public void testGetHealthInfo() throws Exception {
+////        JobHealth jobHealth = new JobHealth(1, 3);
+////        given(service.getHealthInfo()).willReturn(jobHealth);
+////
+////        mvc.perform(get(URLHelper.API_VERSION_PATH + "/jobs/health"))
+////                .andExpect(status().isOk())
+////                .andExpect(jsonPath("$.healthyJobCount", is(1)));
+//    }
+//}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/test/java/org/apache/griffin/core/job/JobInstanceBeanRepoTest.java
----------------------------------------------------------------------
diff --git 
a/service/src/test/java/org/apache/griffin/core/job/JobInstanceBeanRepoTest.java
 
b/service/src/test/java/org/apache/griffin/core/job/JobInstanceBeanRepoTest.java
new file mode 100644
index 0000000..cdfbe45
--- /dev/null
+++ 
b/service/src/test/java/org/apache/griffin/core/job/JobInstanceBeanRepoTest.java
@@ -0,0 +1,87 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package org.apache.griffin.core.job;
+
+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.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+
+@RunWith(SpringRunner.class)
+@PropertySource("classpath:application.properties")
+@DataJpaTest
+public class JobInstanceBeanRepoTest {
+
+    @Autowired
+    private TestEntityManager entityManager;
+
+    @Autowired
+    private JobInstanceRepo jobInstanceRepo;
+
+    @Before
+    public void setUp() {
+        setEntityManager();
+    }
+
+//    @Test
+//    public void testFindByJobIdWithPageable() {
+//        Pageable pageRequest = new PageRequest(0, 10, Sort.Direction.DESC, 
"timestamp");
+//        List<JobInstanceBean> instances = jobInstanceRepo.findByJobId(1L, 
pageRequest);
+//        assertThat(instances.size()).isEqualTo(1);
+//        assertEquals(instances.get(0).getAppId(), "appId1");
+//    }
+
+
+    @Test
+    public void testFindByActiveState() {
+        List<JobInstanceBean> list = jobInstanceRepo.findByActiveState();
+        assertThat(list.size()).isEqualTo(1);
+    }
+
+
+
+
+    private void setEntityManager() {
+        JobInstanceBean instance1 = new JobInstanceBean(1L,  
LivySessionStates.State.success,
+                "appId1", "http://domain.com/uri1";, 
System.currentTimeMillis(),System.currentTimeMillis());
+        JobInstanceBean instance2 = new JobInstanceBean(2L,  
LivySessionStates.State.error,
+                "appId2", "http://domain.com/uri2";, 
System.currentTimeMillis(),System.currentTimeMillis());
+        JobInstanceBean instance3 = new JobInstanceBean(2L,  
LivySessionStates.State.starting,
+                "appId3", "http://domain.com/uri3";, 
System.currentTimeMillis(),System.currentTimeMillis());
+        entityManager.persistAndFlush(instance1);
+        entityManager.persistAndFlush(instance2);
+        entityManager.persistAndFlush(instance3);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/e7e4c3a7/service/src/test/java/org/apache/griffin/core/job/JobInstanceRepoTest.java
----------------------------------------------------------------------
diff --git 
a/service/src/test/java/org/apache/griffin/core/job/JobInstanceRepoTest.java 
b/service/src/test/java/org/apache/griffin/core/job/JobInstanceRepoTest.java
deleted file mode 100644
index f36c370..0000000
--- a/service/src/test/java/org/apache/griffin/core/job/JobInstanceRepoTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-package org.apache.griffin.core.job;
-
-import org.apache.griffin.core.job.entity.JobInstance;
-import org.apache.griffin.core.job.entity.LivySessionStates;
-import org.apache.griffin.core.job.repo.JobInstanceRepo;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
-import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
-import org.springframework.context.annotation.PropertySource;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import java.util.List;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertEquals;
-
-@RunWith(SpringRunner.class)
-@PropertySource("classpath:application.properties")
-@DataJpaTest
-public class JobInstanceRepoTest {
-
-    @Autowired
-    private TestEntityManager entityManager;
-
-    @Autowired
-    private JobInstanceRepo jobInstanceRepo;
-
-    @Before
-    public void setUp() {
-        setEntityManager();
-    }
-
-    @Test
-    public void testFindByGroupNameAndJobNameWithPageable() {
-        Pageable pageRequest = new PageRequest(0, 10, Sort.Direction.DESC, 
"timestamp");
-        List<JobInstance> instances = 
jobInstanceRepo.findByGroupNameAndJobName("BA", "job3", pageRequest);
-        assertThat(instances.size()).isEqualTo(1);
-        assertEquals(instances.get(0).getAppId(), "appId3");
-    }
-
-    @Test
-    public void testFindByGroupNameAndJobName() {
-        List<JobInstance> instances = 
jobInstanceRepo.findByGroupNameAndJobName("BA", "job1");
-        assertThat(instances.size()).isEqualTo(1);
-        assertEquals(instances.get(0).getAppId(), "appId1");
-    }
-
-    @Test
-    public void testFindGroupWithJobName() {
-        List<Object> list = jobInstanceRepo.findGroupWithJobName();
-        assertThat(list.size()).isEqualTo(3);
-    }
-
-    @Test
-    public void testDeleteByGroupAndJobName() {
-        jobInstanceRepo.deleteByGroupAndJobName("BA", "job1");
-        assertThat(jobInstanceRepo.count()).isEqualTo(2);
-    }
-
-    @Test
-    public void testUpdate() {
-        Iterable iterable = jobInstanceRepo.findAll();
-        JobInstance instance = (JobInstance) iterable.iterator().next();
-        jobInstanceRepo.update(instance.getId(), LivySessionStates.State.dead, 
"appIdChanged", "appUriChanged");
-        //you must refresh updated JobInstance, otherwise there will not 
update.
-        entityManager.refresh(jobInstanceRepo.findOne(instance.getId()));
-        assertEquals(jobInstanceRepo.findOne(instance.getId()).getState(), 
LivySessionStates.State.dead);
-    }
-
-
-    private void setEntityManager() {
-        JobInstance instance1 = new JobInstance("BA", "job1", 0, 
LivySessionStates.State.success,
-                "appId1", "http://domain.com/uri1";, 
System.currentTimeMillis());
-        JobInstance instance2 = new JobInstance("BA", "job2", 1, 
LivySessionStates.State.error,
-                "appId2", "http://domain.com/uri2";, 
System.currentTimeMillis());
-        JobInstance instance3 = new JobInstance("BA", "job3", 2, 
LivySessionStates.State.starting,
-                "appId3", "http://domain.com/uri3";, 
System.currentTimeMillis());
-        entityManager.persistAndFlush(instance1);
-        entityManager.persistAndFlush(instance2);
-        entityManager.persistAndFlush(instance3);
-    }
-}

Reply via email to