http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/service/src/test/java/org/apache/griffin/core/metastore/kafka/KafkaSchemaServiceImplTest.java
----------------------------------------------------------------------
diff --git 
a/service/src/test/java/org/apache/griffin/core/metastore/kafka/KafkaSchemaServiceImplTest.java
 
b/service/src/test/java/org/apache/griffin/core/metastore/kafka/KafkaSchemaServiceImplTest.java
new file mode 100644
index 0000000..5735cf5
--- /dev/null
+++ 
b/service/src/test/java/org/apache/griffin/core/metastore/kafka/KafkaSchemaServiceImplTest.java
@@ -0,0 +1,151 @@
+/*
+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.metastore.kafka;
+
+import com.sun.jersey.client.urlconnection.HTTPSProperties;
+import io.confluent.kafka.schemaregistry.client.rest.entities.Config;
+import io.confluent.kafka.schemaregistry.client.rest.entities.Schema;
+import io.confluent.kafka.schemaregistry.client.rest.entities.SchemaString;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.util.ReflectionTestUtils;
+import org.springframework.web.client.RestTemplate;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import static org.assertj.core.api.Assertions.fail;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(SpringRunner.class)
+@PropertySource("classpath:application.properties")
+public class KafkaSchemaServiceImplTest {
+    /*@TestConfiguration
+    public static class KafkaSchemaServiceConfiguration {
+        @Bean
+        public KafkaSchemaServiceImpl service() {
+            return new KafkaSchemaServiceImpl();
+        }
+    }*/
+
+    @InjectMocks
+    private KafkaSchemaServiceImpl service;
+
+    @Mock
+    private RestTemplate restTemplate;
+
+
+    @Before
+    public void setup() throws IOException {
+/*
+        Properties sparkJobProperties=new Properties();
+        sparkJobProperties.load(new FileInputStream(new 
ClassPathResource("sparkJob.properties").getFile()));
+        ReflectionTestUtils.setField(service, "url", 
sparkJobProperties.getProperty("kafka.schema.registry.url"));
+*/
+    }
+
+    @Test
+    public void testGetSchemaString(){
+        try {
+            String regUrl="null/schemas/ids/1";
+            when(restTemplate.getForEntity(regUrl, 
SchemaString.class)).thenReturn(new ResponseEntity<SchemaString>(new 
SchemaString(), HttpStatus.OK));
+            SchemaString tmp = service.getSchemaString(1);
+            assertTrue(true);
+        }catch (Throwable t){
+            fail("Cannot get all tables from all dbs");
+        }
+    }
+
+    @Test
+    public void testGetSubjects(){
+        try {
+            String regUrl="null/subjects";
+            when(restTemplate.getForEntity(regUrl, 
String[].class)).thenReturn(new ResponseEntity<String[]>(new String[2], 
HttpStatus.OK));
+            Iterable<String> tmp = service.getSubjects();
+            assertTrue(true);
+        }catch (Throwable t){
+            fail("Cannot get all tables from all dbs");
+        }
+    }
+
+    @Test
+    public void testGetSubjectVersions(){
+        try {
+            String regUrl="null/subjects/1.0/versions";
+            when(restTemplate.getForEntity(regUrl, 
Integer[].class)).thenReturn(new ResponseEntity<Integer[]>(new Integer[2], 
HttpStatus.OK));
+            Iterable<Integer> tmp = service.getSubjectVersions("1.0");
+            assertTrue(true);
+        }catch (Throwable t){
+            fail("Cannot get all tables from all dbs");
+        }
+    }
+
+    @Test
+    public void testGetSubjectSchema(){
+        try {
+            String regUrl="null/subjects/subject1/versions/version1";
+            when(restTemplate.getForEntity(regUrl, 
Schema.class)).thenReturn(new ResponseEntity<Schema>(new Schema("",0,0, ""), 
HttpStatus.OK));
+            Schema tmp = service.getSubjectSchema("subject1","version1");
+            assertTrue(true);
+        }catch (Throwable t){
+            fail("Cannot get all tables from all dbs");
+        }
+    }
+
+    @Test
+    public void testGetTopLevelConfig(){
+        try {
+            String regUrl="null/config";
+            when(restTemplate.getForEntity(regUrl, 
Config.class)).thenReturn(new ResponseEntity<Config>(new Config(), 
HttpStatus.OK));
+            Config tmp = service.getTopLevelConfig();
+            assertTrue(true);
+        }catch (Throwable t){
+            fail("Cannot get all tables from all dbs");
+        }
+    }
+
+    @Test
+    public void testGetSubjectLevelConfig(){
+        try {
+            String regUrl="null/config/";
+            when(restTemplate.getForEntity(regUrl, 
Config.class)).thenReturn(new ResponseEntity<Config>(new Config(), 
HttpStatus.OK));
+            Config tmp = service.getSubjectLevelConfig("");
+            assertTrue(true);
+        }catch (Throwable t){
+            fail("Cannot get all tables from all dbs");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/service/src/test/java/org/apache/griffin/core/metric/MetricControllerTest.java
----------------------------------------------------------------------
diff --git 
a/service/src/test/java/org/apache/griffin/core/metric/MetricControllerTest.java
 
b/service/src/test/java/org/apache/griffin/core/metric/MetricControllerTest.java
index 8308406..21655cc 100644
--- 
a/service/src/test/java/org/apache/griffin/core/metric/MetricControllerTest.java
+++ 
b/service/src/test/java/org/apache/griffin/core/metric/MetricControllerTest.java
@@ -57,7 +57,7 @@ public class MetricControllerTest {
 
         given(service.getOrgByMeasureName("m14")).willReturn("bullseye");
 
-        
mvc.perform(get("/metrics/m14/org").contentType(MediaType.APPLICATION_JSON))
+        
mvc.perform(get("/metrics/org?measureName=m14").contentType(MediaType.APPLICATION_JSON))
 //                .andDo(print())
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$").isString())

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/service/src/test/java/org/apache/griffin/core/schedule/SchedulerControllerTest.java
----------------------------------------------------------------------
diff --git 
a/service/src/test/java/org/apache/griffin/core/schedule/SchedulerControllerTest.java
 
b/service/src/test/java/org/apache/griffin/core/schedule/SchedulerControllerTest.java
deleted file mode 100644
index 6fd1aae..0000000
--- 
a/service/src/test/java/org/apache/griffin/core/schedule/SchedulerControllerTest.java
+++ /dev/null
@@ -1,122 +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.schedule;
-
-import org.apache.griffin.core.schedule.entity.JobHealth;
-import org.apache.griffin.core.schedule.entity.JobInstance;
-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.MockMvcResultMatchers.jsonPath;
-import static 
org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-@RunWith(SpringRunner.class)
-@WebMvcTest(value = SchedulerController.class,secure = false)
-public class SchedulerControllerTest {
-    @Autowired
-    private MockMvc mvc;
-
-    @MockBean
-    private SchedulerService service;
-
-    @Before
-    public void setup(){
-    }
-
-    @Test
-    public void testGetJobs() throws Exception {
-        Map<String, Serializable> map=new HashMap<String, Serializable>();
-        map.put("jobName", "job1");
-        map.put("groupName", "BA");
-        given(service.getJobs()).willReturn(Arrays.asList(map));
-
-        mvc.perform(get("/jobs/").contentType(MediaType.APPLICATION_JSON))
-                .andExpect(status().isOk())
-                .andExpect(jsonPath("$.[0].jobName",is("job1")))
-        ;
-    }
-
-    @Test
-    public void testAddJob() throws Exception {
-        String groupName="BA";
-        String jobName="job1";
-        String measureName="viewitem_hourly";
-        SchedulerRequestBody schedulerRequestBody=new 
SchedulerRequestBody("YYYYMMdd-HH","YYYYMMdd-HH","111","20170607","100");
-        ObjectMapper mapper=new ObjectMapper();
-        String 
schedulerRequestBodyJson=mapper.writeValueAsString(schedulerRequestBody);
-        
given(service.addJob(groupName,jobName,measureName,schedulerRequestBody)).willReturn(true);
-
-        
mvc.perform(post("/jobs/add/BA/job1/viewitem_hourly").contentType(MediaType.APPLICATION_JSON).content(schedulerRequestBodyJson))
-                .andExpect(status().isOk())
-                .andExpect(jsonPath("$",is(true)))
-        ;
-    }
-
-    @Test
-    public void testDeleteJob() throws Exception {
-        String groupName="BA";
-        String jobName="job1";
-        given(service.deleteJob(groupName,jobName)).willReturn(true);
-        
mvc.perform(delete("/jobs/del/BA/job1").contentType(MediaType.APPLICATION_JSON))
-                .andExpect(status().isOk())
-                .andExpect(jsonPath("$",is(true)))
-        ;
-    }
-
-    @Test
-    public void testFindInstancesOfJob() throws Exception {
-        String group="BA";
-        String job="job1";
-        int page=0;
-        int size=2;
-        JobInstance jobInstance=new JobInstance(group, job, 1, "NORMAL", "", 
System.currentTimeMillis());
-        
given(service.findInstancesOfJob(group,job,page,size)).willReturn(Arrays.asList(jobInstance));
-        
mvc.perform(get("/jobs/instances/BA/job1/0/2").contentType(MediaType.APPLICATION_JSON))
-                .andExpect(status().isOk())
-                .andExpect(jsonPath("$.[0].groupName",is("BA")))
-        ;
-    }
-
-    @Test
-    public void testGetHealthInfo() throws Exception {
-        JobHealth jobHealth=new JobHealth(1,2,3);
-        given(service.getHealthInfo()).willReturn(jobHealth);
-        
mvc.perform(get("/jobs/statics").contentType(MediaType.APPLICATION_JSON))
-                .andExpect(status().isOk())
-                .andExpect(jsonPath("$.health",is(1)))
-        ;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/service/src/test/java/org/apache/griffin/core/schedule/SchedulerServiceImplTest.java
----------------------------------------------------------------------
diff --git 
a/service/src/test/java/org/apache/griffin/core/schedule/SchedulerServiceImplTest.java
 
b/service/src/test/java/org/apache/griffin/core/schedule/SchedulerServiceImplTest.java
deleted file mode 100644
index cb1a9ad..0000000
--- 
a/service/src/test/java/org/apache/griffin/core/schedule/SchedulerServiceImplTest.java
+++ /dev/null
@@ -1,207 +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.schedule;
-
-import org.apache.griffin.core.schedule.entity.JobHealth;
-import org.apache.griffin.core.schedule.entity.JobInstance;
-import org.apache.griffin.core.schedule.repo.JobInstanceRepo;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-import org.quartz.*;
-import org.quartz.impl.matchers.GroupMatcher;
-import org.quartz.impl.triggers.CronTriggerImpl;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.TestConfiguration;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.scheduling.quartz.SchedulerFactoryBean;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import java.io.Serializable;
-import java.util.*;
-
-import static org.assertj.core.api.Assertions.fail;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.BDDMockito.given;
-
-@RunWith(SpringRunner.class)
-public class SchedulerServiceImplTest {
-    private static final Logger log = 
LoggerFactory.getLogger(SchedulerServiceImplTest.class);
-
-    @TestConfiguration
-    public static class SchedulerServiceConfiguration{
-        @Bean
-        public SchedulerServiceImpl service(){
-            return new SchedulerServiceImpl();
-        }
-        @Bean
-        public SchedulerFactoryBean factoryBean(){
-            return new SchedulerFactoryBean();
-        }
-    }
-
-    @MockBean
-    private JobInstanceRepo jobInstanceRepo;
-
-
-    @MockBean
-    private SchedulerFactoryBean factory;
-
-    @Autowired
-    private SchedulerServiceImpl service;
-
-    @Before
-    public void setup(){
-    }
-
-    @Test
-    public void testGetJobs(){
-        try {
-            Scheduler scheduler=Mockito.mock(Scheduler.class);
-            given(factory.getObject()).willReturn(scheduler);
-            List<Map<String, Serializable>> tmp = service.getJobs();
-            assertTrue(true);
-        }catch (Throwable t){
-            fail("Cannot get all jobs info from dbs");
-        }
-    }
-
-    @Test
-    public void testSetJobsByKey() throws SchedulerException {
-        List<Map<String, Serializable>> list=new ArrayList<Map<String, 
Serializable>>();
-        Scheduler scheduler=Mockito.mock(Scheduler.class);
-        JobKey jobKey= new JobKey("TEST");
-        List<Trigger> triggers=new ArrayList<Trigger>();
-        Trigger trigger=new CronTriggerImpl();
-        triggers.add(trigger);
-        given((List<Trigger>) 
scheduler.getTriggersOfJob(jobKey)).willReturn(triggers);
-
-        JobDetail jd=Mockito.mock(JobDetail.class);
-        given(scheduler.getJobDetail(jobKey)).willReturn(jd);
-
-        JobDataMap jobDataMap=Mockito.mock(JobDataMap.class);
-        given(jd.getJobDataMap()).willReturn(jobDataMap);
-
-        service.setJobsByKey(list,scheduler,jobKey);
-
-    }
-
-    @Test
-    public void testAddJob(){
-        try {
-            String groupName="BA";
-            String jobName="job1";
-            String measureName="m1";
-            SchedulerRequestBody schedulerRequestBody=new 
SchedulerRequestBody();
-            Scheduler scheduler=Mockito.mock(Scheduler.class);
-            given(factory.getObject()).willReturn(scheduler);
-            Boolean tmp = 
service.addJob(groupName,jobName,measureName,schedulerRequestBody);
-            assertEquals(tmp,false);
-            assertTrue(true);
-
-            SchedulerRequestBody schedulerRequestBody1=new 
SchedulerRequestBody("YYYYMMdd-HH","YYYYMMdd-HH",
-                    
System.currentTimeMillis()+"",System.currentTimeMillis()+"","1000");
-            Scheduler scheduler1=Mockito.mock(Scheduler.class);
-            given(factory.getObject()).willReturn(scheduler1);
-            Boolean tmp1 = 
service.addJob(groupName,jobName,measureName,schedulerRequestBody1);
-            assertEquals(tmp1,true);
-        }catch (Throwable t){
-            fail("Cannot add job ");
-        }
-    }
-
-    @Test
-    public void testDeleteJob(){
-        String groupName="BA";
-        String jobName="job1";
-        try {
-            Scheduler scheduler=Mockito.mock(Scheduler.class);
-            given(factory.getObject()).willReturn(scheduler);
-            Boolean tmp = service.deleteJob(groupName,jobName);
-            assertTrue(true);
-        }catch (Throwable t){
-            fail("Cannot delete job");
-        }
-        try {
-            given(factory.getObject()).willThrow(SchedulerException.class);
-            Boolean tmp = service.deleteJob(groupName,jobName);
-        } catch (Exception e) {
-            log.info("testGetAllTable: test catch "+e);
-        }
-    }
-
-    @Test
-    public void testFindInstancesOfJob(){
-        try {
-            String groupName="BA";
-            String jobName="job1";
-            int page=0;
-            int size=2;
-            List<JobInstance> tmp = 
service.findInstancesOfJob(groupName,jobName,page,size);
-            assertTrue(true);
-        }catch (Throwable t){
-            fail("Cannot find instances of Job");
-        }
-    }
-
-    @Test
-    public void testGetHealthInfo(){
-        try {
-            Scheduler scheduler=Mockito.mock(Scheduler.class);
-            given(factory.getObject()).willReturn(scheduler);
-            
given(scheduler.getJobGroupNames()).willReturn(Arrays.asList("BA"));
-            JobKey jobKey= new JobKey("TEST");
-            Set<JobKey> jobKeySet=new HashSet<JobKey>();
-            jobKeySet.add(jobKey);
-            
given(scheduler.getJobKeys(GroupMatcher.jobGroupEquals("BA"))).willReturn((jobKeySet));
-
-            Pageable pageRequest=new PageRequest(0,1, 
Sort.Direction.DESC,"timestamp");
-            List<JobInstance> scheduleStateList=new ArrayList<JobInstance>();
-            JobInstance jobInstance=new JobInstance();
-            jobInstance.setGroupName("BA");
-            jobInstance.setJobName("job1");
-            jobInstance.setSessionId(1);
-            jobInstance.setState("starting");
-            jobInstance.setAppId("ttt");
-            jobInstance.setTimestamp(System.currentTimeMillis());
-            scheduleStateList.add(jobInstance);
-            
given(jobInstanceRepo.findByGroupNameAndJobName(jobKey.getGroup(),jobKey.getName(),pageRequest)).willReturn(scheduleStateList);
-            JobHealth tmp = service.getHealthInfo();
-            assertTrue(true);
-
-            scheduleStateList.remove(0);
-            jobInstance.setState("down");
-            scheduleStateList.add(jobInstance);
-            
given(jobInstanceRepo.findByGroupNameAndJobName(jobKey.getGroup(),jobKey.getName(),pageRequest)).willReturn(scheduleStateList);
-            JobHealth tmp1 = service.getHealthInfo();
-        }catch (Throwable t){
-            fail("Cannot get Health info "+t);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/service/src/test/java/org/apache/griffin/core/schedule/SparkSubmitJobTest.java
----------------------------------------------------------------------
diff --git 
a/service/src/test/java/org/apache/griffin/core/schedule/SparkSubmitJobTest.java
 
b/service/src/test/java/org/apache/griffin/core/schedule/SparkSubmitJobTest.java
deleted file mode 100644
index 18e6677..0000000
--- 
a/service/src/test/java/org/apache/griffin/core/schedule/SparkSubmitJobTest.java
+++ /dev/null
@@ -1,187 +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.schedule;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import org.apache.griffin.core.measure.DataConnector;
-import org.apache.griffin.core.measure.EvaluateRule;
-import org.apache.griffin.core.measure.Measure;
-import org.apache.griffin.core.measure.repo.MeasureRepo;
-import org.apache.griffin.core.schedule.entity.SparkJobDO;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-import org.quartz.JobDataMap;
-import org.quartz.JobDetail;
-import org.quartz.JobExecutionContext;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.web.client.RestTemplate;
-
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.*;
-
-//@RunWith(PowerMockRunner.class)
-//@PrepareForTest(SparkSubmitJob.class)
-@RunWith(SpringRunner.class)
-public class SparkSubmitJobTest{
-
-    private SparkSubmitJob ssj;
-
-//    @Autowired
-    @MockBean
-    MeasureRepo measureRepo;
-
-    @Before
-    public void setUp() throws IOException {
-        ssj=new SparkSubmitJob();
-        ssj.measureRepo=mock(MeasureRepo.class);
-        ssj.restTemplate= mock(RestTemplate.class);
-    }
-
-    @Test
-    public void test_execute() throws Exception {
-        JobExecutionContext context=mock(JobExecutionContext.class);
-        JobDetail jd = mock(JobDetail.class);
-        when(context.getJobDetail()).thenReturn(jd);
-
-        JobDataMap jdmap = mock(JobDataMap.class);
-        when(jd.getJobDataMap()).thenReturn(jdmap);
-
-        when(jdmap.getString("measure")).thenReturn("bevssoj");
-        when(jdmap.getString("sourcePat")).thenReturn("YYYYMMDD-HH");
-        when(jdmap.getString("targetPat")).thenReturn("YYYYMMDD-HH");
-        
when(jdmap.getString("dataStartTimestamp")).thenReturn("1460174400000");
-        when(jdmap.getString("lastTime")).thenReturn("");
-        when(jdmap.getString("periodTime")).thenReturn("10");
-        Measure measure = createATestMeasure("viewitem_hourly","bullseye");
-        when(ssj.measureRepo.findByName("bevssoj")).thenReturn(measure);
-
-        RestTemplate restTemplate =Mockito.mock(RestTemplate.class);
-//        
PowerMockito.whenNew(RestTemplate.class).withAnyArguments().thenReturn(restTemplate);
-        String uri=ssj.uri;
-        SparkJobDO sparkJobDO= Mockito.mock(SparkJobDO.class);
-//        PowerMockito.when(restTemplate.postForObject(uri, sparkJobDO, 
String.class)).thenReturn(null);
-        when(restTemplate.postForObject(uri, sparkJobDO, 
String.class)).thenReturn(null);
-        ssj.execute(context);
-
-        long currentSystemTimestamp=System.currentTimeMillis();
-        long currentTimstamp = ssj.setCurrentTimestamp(currentSystemTimestamp);
-
-        verify(ssj.measureRepo).findByName("bevssoj");
-        verify(jdmap,atLeast(2)).put("lastTime",currentTimstamp+"");
-
-        when(ssj.measureRepo.findByName("bevssoj")).thenReturn(null);
-        ssj.execute(context);
-
-        when(ssj.measureRepo.findByName("bevssoj")).thenReturn(measure);
-        String 
result="{\"id\":8718,\"state\":\"starting\",\"appId\":null,\"appInfo\":{\"driverLogUrl\":null,\"sparkUiUrl\":null},\"log\":[]}";
-        when(restTemplate.postForObject(uri, sparkJobDO, 
String.class)).thenReturn(result);
-        ssj.execute(context);
-    }
-
-    private Measure createATestMeasure(String name,String org)throws 
IOException,Exception{
-        HashMap<String,String> configMap1=new HashMap<>();
-        configMap1.put("database","default");
-        configMap1.put("table.name","test_data_src");
-        HashMap<String,String> configMap2=new HashMap<>();
-        configMap2.put("database","default");
-        configMap2.put("table.name","test_data_tgt");
-        String configJson1 = new 
org.codehaus.jackson.map.ObjectMapper().writeValueAsString(configMap1);
-        String configJson2 = new 
org.codehaus.jackson.map.ObjectMapper().writeValueAsString(configMap2);
-
-        DataConnector source = new 
DataConnector(DataConnector.ConnectorType.HIVE, "1.2", configJson1);
-        DataConnector target = new 
DataConnector(DataConnector.ConnectorType.HIVE, "1.2", configJson2);
-
-        String rules = "$source.uage > 100 AND $source.uid = $target.uid AND 
$source.uage + 12 = $target.uage + 10 + 2 AND $source.udes + 11 = $target.udes 
+ 1 + 1";
-
-        EvaluateRule eRule = new EvaluateRule(1,rules);
-
-        Measure measure = new Measure(name,"bevssoj description", 
Measure.MearuseType.accuracy, org, source, target, eRule,"test1");
-
-        return measure;
-    }
-
-    @Test
-    public void test_genPartitions(){
-        String[] patternItemSet={"YYYYMMDD","HH"};
-        String[] partitionItemSet={"date","hour"};
-        long timestamp=System.currentTimeMillis();
-        Map<String,String> 
par=ssj.genPartitions(patternItemSet,partitionItemSet,timestamp);
-        Map<String,String> verifyMap=new HashMap<>();
-        SimpleDateFormat sdf = new SimpleDateFormat("YYYYMMdd");
-        verifyMap.put("date",sdf.format(new Date(timestamp)));
-        SimpleDateFormat sdf1 = new SimpleDateFormat("HH");
-        verifyMap.put("hour",sdf1.format(new Date(timestamp)));
-        assertEquals(verifyMap,par);
-    }
-
-    @Test
-    public void test_setDataConnectorPartitions(){
-        DataConnector dc=mock(DataConnector.class);
-        String[] patternItemSet={"YYYYMMDD","HH"};
-        String[] partitionItemSet={"date","hour"};
-        long timestamp=System.currentTimeMillis();
-        
ssj.setDataConnectorPartitions(dc,patternItemSet,partitionItemSet,timestamp);
-        Map<String,String> map=new HashMap<>();
-        SimpleDateFormat sdf = new SimpleDateFormat("YYYYMMdd");
-        SimpleDateFormat sdf1 = new SimpleDateFormat("HH");
-        map.put("partitions","date="+sdf.format(new Date(timestamp))+", 
hour="+sdf1.format(new Date(timestamp)));
-        try {
-            verify(dc).setConfig(map);
-        } catch (JsonProcessingException e) {
-            e.printStackTrace();
-        }
-    }
-
-    @Test
-    public void test_setCurrentTimestamp(){
-        long timestamp=System.currentTimeMillis();
-        ssj.eachJoblastTimestamp="";
-        System.out.println(ssj.setCurrentTimestamp(timestamp));
-        ssj.eachJoblastTimestamp=(timestamp-1000)+"";
-        ssj.periodTime="1000";
-        System.out.println(ssj.setCurrentTimestamp(timestamp));
-    }
-
-    @Test
-    public void test_setSparkJobDO(){
-        ssj=mock(SparkSubmitJob.class);
-        doNothing().when(ssj).setSparkJobDO();
-    }
-
-//    @Test
-//    public void test_getsparkJobProperties(){
-//        ssj=mock(SparkSubmitJob.class);
-//        try {
-//            when(ssj.getsparkJobProperties()).thenReturn(null);
-//        } catch (IOException e) {
-//            e.printStackTrace();
-//        }
-//    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/service/src/test/java/org/apache/griffin/core/service/GriffinControllerTest.java
----------------------------------------------------------------------
diff --git 
a/service/src/test/java/org/apache/griffin/core/service/GriffinControllerTest.java
 
b/service/src/test/java/org/apache/griffin/core/service/GriffinControllerTest.java
index 3e09fe8..fc83bef 100644
--- 
a/service/src/test/java/org/apache/griffin/core/service/GriffinControllerTest.java
+++ 
b/service/src/test/java/org/apache/griffin/core/service/GriffinControllerTest.java
@@ -20,9 +20,9 @@ under the License.
 package org.apache.griffin.core.service;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
-import org.apache.griffin.core.measure.DataConnector;
-import org.apache.griffin.core.measure.EvaluateRule;
-import org.apache.griffin.core.measure.Measure;
+import org.apache.griffin.core.measure.entity.DataConnector;
+import org.apache.griffin.core.measure.entity.EvaluateRule;
+import org.apache.griffin.core.measure.entity.Measure;
 import org.apache.griffin.core.measure.repo.MeasureRepo;
 import org.junit.Before;
 import org.junit.Test;
@@ -101,7 +101,7 @@ public class GriffinControllerTest {
         when(measureRepo.findOrganizations()).thenReturn(orgList);
 
         
when(measureRepo.findNameByOrganization(org)).thenReturn(Arrays.asList("viewitem_hourly"));
-        mockMvc.perform(get("/orgWithMetrics"))
+        mockMvc.perform(get("/orgWithMetricsName"))
                 .andExpect(status().isOk());
         verify(measureRepo).findOrganizations();
         verify(measureRepo).findNameByOrganization(org);
@@ -129,7 +129,7 @@ public class GriffinControllerTest {
         Measure measure2 = new Measure("search_hourly","test description", 
Measure.MearuseType.accuracy, "bullyeye", source2, target2, eRule2,"test1");
 
         
when(measureRepo.findAll()).thenReturn(Arrays.asList(measure,measure2));
-        mockMvc.perform(get("/dataAssetsWithMetrics"))
+        mockMvc.perform(get("/dataAssetsNameWithMetricsName"))
                 .andExpect(status().isOk())
                 .andDo(print());
         verify(measureRepo).findAll();

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/service/src/test/java/org/apache/griffin/core/util/GriffinUtilTest.java
----------------------------------------------------------------------
diff --git 
a/service/src/test/java/org/apache/griffin/core/util/GriffinUtilTest.java 
b/service/src/test/java/org/apache/griffin/core/util/GriffinUtilTest.java
new file mode 100644
index 0000000..a03548d
--- /dev/null
+++ b/service/src/test/java/org/apache/griffin/core/util/GriffinUtilTest.java
@@ -0,0 +1,71 @@
+/*
+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 com.fasterxml.jackson.core.type.TypeReference;
+import org.apache.griffin.core.job.entity.JobHealth;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Created by xiangrchen on 7/27/17.
+ */
+public class GriffinUtilTest {
+
+    @Before
+    public void setup(){
+    }
+
+    @Test
+    public void test_toJson(){
+        JobHealth jobHealth=new JobHealth(5,10);
+        String jobHealthStr=GriffinUtil.toJson(jobHealth);
+        assertEquals(jobHealthStr,"{\"healthyJobCount\":5,\"jobCount\":10}");
+    }
+
+    @Test
+    public void test_toEntity() throws IOException {
+        String str="{\"healthyJobCount\":5,\"jobCount\":10}";
+        JobHealth jobHealth=GriffinUtil.toEntity(str,JobHealth.class);
+        assertEquals(jobHealth.getJobCount(),10);
+        assertEquals(jobHealth.getHealthyJobCount(),5);
+    }
+
+    @Test
+    public void test_toEntity1() throws IOException {
+        String str="{\"aaa\":12, \"bbb\":13}";
+        TypeReference<HashMap<String,Integer>> type=new 
TypeReference<HashMap<String,Integer>>(){};
+        Map map=GriffinUtil.toEntity(str,type);
+        assertEquals(map.get("aaa"),12);
+    }
+
+    @Test
+    public void test_toJson2() throws IOException {
+//        LivySessionStateMap.State state=
+        System.out.println(GriffinOperationMessage.CREATE_JOB_FAIL);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/service/src/test/resources/Init_quartz-h2.sql
----------------------------------------------------------------------
diff --git a/service/src/test/resources/Init_quartz-h2.sql 
b/service/src/test/resources/Init_quartz-h2.sql
new file mode 100644
index 0000000..8537cca
--- /dev/null
+++ b/service/src/test/resources/Init_quartz-h2.sql
@@ -0,0 +1,190 @@
+
+-- 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 IF EXISTS QRTZ_FIRED_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
+DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
+DROP TABLE IF EXISTS QRTZ_LOCKS;
+DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_TRIGGERS;
+DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
+DROP TABLE IF EXISTS 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) NULL,
+  JOB_CLASS_NAME VARCHAR(250) NOT NULL,
+  IS_DURABLE VARCHAR(1) NOT NULL,
+  IS_NONCONCURRENT VARCHAR(1) NOT NULL,
+  IS_UPDATE_DATA VARCHAR(1) NOT NULL,
+  REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
+  JOB_DATA BLOB NULL,
+  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) NULL,
+  NEXT_FIRE_TIME BIGINT(13) NULL,
+  PREV_FIRE_TIME BIGINT(13) NULL,
+  PRIORITY INTEGER NULL,
+  TRIGGER_STATE VARCHAR(16) NOT NULL,
+  TRIGGER_TYPE VARCHAR(8) NOT NULL,
+  START_TIME BIGINT(13) NOT NULL,
+  END_TIME BIGINT(13) NULL,
+  CALENDAR_NAME VARCHAR(200) NULL,
+  MISFIRE_INSTR SMALLINT(2) NULL,
+  JOB_DATA BLOB NULL,
+  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(7) NOT NULL,
+  REPEAT_INTERVAL BIGINT(12) NOT NULL,
+  TIMES_TRIGGERED BIGINT(10) 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) NULL,
+  STR_PROP_2 VARCHAR(512) NULL,
+  STR_PROP_3 VARCHAR(512) NULL,
+  INT_PROP_1 INT NULL,
+  INT_PROP_2 INT NULL,
+  LONG_PROP_1 BIGINT NULL,
+  LONG_PROP_2 BIGINT NULL,
+  DEC_PROP_1 NUMERIC(13,4) NULL,
+  DEC_PROP_2 NUMERIC(13,4) NULL,
+  BOOL_PROP_1 VARCHAR(1) NULL,
+  BOOL_PROP_2 VARCHAR(1) 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_BLOB_TRIGGERS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  TRIGGER_NAME VARCHAR(200) NOT NULL,
+  TRIGGER_GROUP VARCHAR(200) NOT NULL,
+  BLOB_DATA BLOB NULL,
+  PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
+  INDEX (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_CALENDARS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  CALENDAR_NAME VARCHAR(200) NOT NULL,
+  CALENDAR BLOB NOT NULL,
+  PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
+  ENGINE=InnoDB;
+
+CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  TRIGGER_GROUP VARCHAR(200) NOT NULL,
+  PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
+  ENGINE=InnoDB;
+
+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(13) NOT NULL,
+  SCHED_TIME BIGINT(13) NOT NULL,
+  PRIORITY INTEGER NOT NULL,
+  STATE VARCHAR(16) NOT NULL,
+  JOB_NAME VARCHAR(200) NULL,
+  JOB_GROUP VARCHAR(200) NULL,
+  IS_NONCONCURRENT VARCHAR(1) NULL,
+  REQUESTS_RECOVERY VARCHAR(1) NULL,
+  PRIMARY KEY (SCHED_NAME,ENTRY_ID))
+  ENGINE=InnoDB;
+
+CREATE TABLE QRTZ_SCHEDULER_STATE (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  INSTANCE_NAME VARCHAR(200) NOT NULL,
+  LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
+  CHECKIN_INTERVAL BIGINT(13) NOT NULL,
+  PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
+  ENGINE=InnoDB;
+
+CREATE TABLE QRTZ_LOCKS (
+  SCHED_NAME VARCHAR(120) NOT NULL,
+  LOCK_NAME VARCHAR(40) NOT NULL,
+  PRIMARY KEY (SCHED_NAME,LOCK_NAME))
+  ENGINE=InnoDB;
+
+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/1cf0a99e/service/src/test/resources/application.properties
----------------------------------------------------------------------
diff --git a/service/src/test/resources/application.properties 
b/service/src/test/resources/application.properties
index d6c7851..1b9a14c 100644
--- a/service/src/test/resources/application.properties
+++ b/service/src/test/resources/application.properties
@@ -18,15 +18,23 @@
 #
 
 # spring.datasource.x
+
 spring.datasource.driver-class-name=org.h2.Driver
-spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
+spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
 spring.datasource.username=sa
 spring.datasource.password=sa
+#spring.datasource.url= 
jdbc:mysql://localhost:3306/quartz?autoReconnect=true&useSSL=false
+#spring.datasource.username =griffin
+#spring.datasource.password =123456
 
 # hibernate.X
 hibernate.dialect=org.hibernate.dialect.H2Dialect
+#spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
+
 hibernate.show_sql=true
-hibernate.hbm2ddl.auto=create-drop
+spring.jpa.hibernate.ddl-auto = create-drop
+
+#hibernate.hbm2ddl.auto=create-drop
 hibernate.cache.use_second_level_cache=true
 hibernate.cache.use_query_cache=true
 
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
@@ -34,6 +42,8 @@ 
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFa
 # hive metastore
 hive.metastore.uris = thrift://10.9.246.187:9083
 hive.metastore.dbname = default
+hive.hmshandler.retry.attempts = 15
+hive.hmshandler.retry.interval = 2000ms
 
 # kafka schema registry
 kafka.schema.registry.url = http://10.65.159.119:8081
@@ -43,4 +53,9 @@ logging.level.root=ERROR
 logging.level.org.hibernate=ERROR
 logging.level.org.springframework.test=ERROR
 logging.level.org.apache.griffin=ERROR
-logging.file=target/test.log
\ No newline at end of file
+logging.file=target/test.log
+
+
+jobInstance.fixedDelay.in.milliseconds=60000
+# spring cache
+cache.evict.hive.fixedRate=900000
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/service/src/test/resources/quartz-test.sql
----------------------------------------------------------------------
diff --git a/service/src/test/resources/quartz-test.sql 
b/service/src/test/resources/quartz-test.sql
new file mode 100644
index 0000000..3f5287a
--- /dev/null
+++ b/service/src/test/resources/quartz-test.sql
@@ -0,0 +1,26 @@
+INSERT INTO `QRTZ_FIRED_TRIGGERS` VALUES 
('schedulerFactoryBean','LM-SHC-0095021215027875413551502787541380','measure-test-BA-test-1502789449000','BA','LM-SHC-009502121502787541355',1502789505307,1502789520000,5,'ACQUIRED',NULL,NULL,'0','0');
+
+INSERT INTO `QRTZ_JOB_DETAILS` VALUES 
('schedulerFactoryBean','measure-test-BA-test-1502789449000','BA',NULL,'org.apache.griffin.core.job.SparkSubmitJob','1','1','1','0','#\n#Tue
 Aug 15 17:31:20 CST 
2017\ninterval=40\njobStartTime=1502640000000\nsourcePattern=YYYYMMdd-HH\nmeasureName=measure-test\njobName=measure-test-BA-test-1502789449000\nblockStartTimestamp=\nlastBlockStartTimestamp=1502789480023\ntargetPattern=YYYYMMdd-HH\ngroupName=BA\n');
+
+
+INSERT INTO `QRTZ_LOCKS` VALUES 
('schedulerFactoryBean','STATE_ACCESS'),('schedulerFactoryBean','TRIGGER_ACCESS');
+
+
+INSERT INTO `QRTZ_SCHEDULER_STATE` VALUES 
('schedulerFactoryBean','LM-SHC-009502121502787541355',1502789504423,20000);
+
+INSERT INTO `QRTZ_SIMPLE_TRIGGERS` VALUES 
('schedulerFactoryBean','measure-test-BA-test-1502789449000','BA',-1,40000,1);
+
+
+INSERT INTO `QRTZ_TRIGGERS` VALUES 
('schedulerFactoryBean','measure-test-BA-test-1502789449000','BA','measure-test-BA-test-1502789449000','BA',NULL,1502789520000,1502789480000,5,'ACQUIRED','SIMPLE',1502789480000,0,NULL,0,'');
+
+
+INSERT INTO `data_connector` VALUES (9,'2017-08-15 
17:30:32',NULL,'{\"database\":\"default\",\"table.name\":\"demo_src\"}','HIVE','1.2'),(10,'2017-08-15
 
17:30:32',NULL,'{\"database\":\"default\",\"table.name\":\"demo_tgt\"}','HIVE','1.2');
+
+
+INSERT INTO `evaluate_rule` VALUES (5,'2017-08-15 
17:30:32',NULL,'$source[''id''] == $target[''id''] AND $source[''age''] == 
$target[''age''] AND $source[''desc''] == $target[''desc'']',0);
+
+
+INSERT INTO `job_instance` VALUES (103,'2017-08-15 
17:31:21',NULL,'application_1500359928600_0025','BA','measure-test-BA-test-1502789449000',24,'success',1502789480660,'http://10.149.247.156:28088/cluster/app/application_1500359928600_0025');
+
+
+INSERT INTO `measure` VALUES (5,'2017-08-15 17:30:32',NULL,'Description of 
measure-test','measure-test','eBay','test','accuracy',5,9,10);

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/service/src/test/resources/sparkJob.properties
----------------------------------------------------------------------
diff --git a/service/src/test/resources/sparkJob.properties 
b/service/src/test/resources/sparkJob.properties
new file mode 100644
index 0000000..4e8aace
--- /dev/null
+++ b/service/src/test/resources/sparkJob.properties
@@ -0,0 +1,52 @@
+#
+# 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.
+#
+
+# spark required
+sparkJob.file=hdfs:///griffin/griffin-measure.jar
+sparkJob.className=org.apache.griffin.measure.Application
+sparkJob.args_1=hdfs:///griffin/json/env.json
+sparkJob.args_3=hdfs,raw
+
+sparkJob.name=griffin
+sparkJob.queue=default
+
+# options
+sparkJob.numExecutors=2
+sparkJob.executorCores=1
+sparkJob.driverMemory=1g
+sparkJob.executorMemory=1g
+
+# 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
+
+#partitionItem
+sparkJob.dateAndHour=dt,hour
+
+#livy
+#livy.uri=http://10.9.246.187:8998/batches
+livy.uri=http://localhost:8998/batches
+
+#spark-admin
+#spark.uri=http://10.149.247.156:28088
+#spark.uri=http://10.9.246.187:8088
+spark.uri=http://localhost:8088
+

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/service/src/test/resources/test.sql
----------------------------------------------------------------------
diff --git a/service/src/test/resources/test.sql 
b/service/src/test/resources/test.sql
new file mode 100644
index 0000000..b92296d
--- /dev/null
+++ b/service/src/test/resources/test.sql
@@ -0,0 +1,25 @@
+SET MODE MYSQL;
+-- ----------------------------
+-- Records of data_connector
+-- ----------------------------
+INSERT INTO `data_connector` VALUES ('1', '2017-07-12 11:06:47', null, 
'{\"database\":\"default\",\"table.name\":\"data_avr\"}', 'HIVE', '1.2');
+INSERT INTO `data_connector` VALUES ('2', '2017-07-12 11:06:47', null, 
'{\"database\":\"default\",\"table.name\":\"cout\"}', 'HIVE', '1.2');
+INSERT INTO `data_connector` VALUES ('3', '2017-07-12 17:40:30', null, 
'{\"database\":\"griffin\",\"table.name\":\"avr_in\"}', 'HIVE', '1.2');
+INSERT INTO `data_connector` VALUES ('4', '2017-07-12 17:40:30', null, 
'{\"database\":\"griffin\",\"table.name\":\"avr_out\"}', 'HIVE', '1.2');
+
+
+-- ----------------------------
+-- Records of evaluate_rule
+-- ----------------------------
+--INSERT INTO `evaluate_rule` VALUES ('1', '2017-07-12 11:06:47', null, 
'$source[\'uid\'] == $target[\'url\'] AND $source[\'uage\'] == 
$target[\'createdts\']', '0');
+INSERT INTO `evaluate_rule` VALUES ('1', '2017-07-12 11:06:47', null, 
'$source[''uid''] == $target[''url''] AND $source[''uage''] == 
$target[''createdts'']', '0');
+
+--INSERT INTO `evaluate_rule` VALUES ('2', '2017-07-12 17:40:30', null, 
'$source[\'id\'] == $target[\'id\'] AND $source[\'age\'] == $target[\'age\'] 
AND $source[\'desc\'] == $target[\'desc\']', '0');
+INSERT INTO `evaluate_rule` VALUES ('2', '2017-07-12 17:40:30', null, 
'$source[''id''] == $target[''id''] AND $source[''age''] == $target[''age''] 
AND $source[''desc''] == $target[''desc'']', '0');
+
+
+-- ----------------------------
+-- Records of measure
+-- ----------------------------
+INSERT INTO `measure` VALUES ('1', '2017-07-12 11:06:47', null, '0', 'desc1', 
'buy_rates_hourly', 'eBay', 'test', 'batch', 'accuracy', '1', '1', '2');
+INSERT INTO `measure` VALUES ('2', '2017-07-12 17:40:30', null, '0', 'desc2', 
'griffin_aver', 'eBay', 'test', 'batch', 'accuracy', '2', '3', '4');

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/ui/bower.json
----------------------------------------------------------------------
diff --git a/ui/bower.json b/ui/bower.json
index bd1f8ee..1b77945 100644
--- a/ui/bower.json
+++ b/ui/bower.json
@@ -4,6 +4,7 @@
   "private": true,
   "dependencies": {
     "jquery": "2.1.4",
+    "jquery-ui":"1.12.1",
     "bootswatch": "3.3.6",
     "font-awesome": "4.7.0",
     "angular": "1.6.4",

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/ui/css/main.css
----------------------------------------------------------------------
diff --git a/ui/css/main.css b/ui/css/main.css
index 971537e..47a2ad3 100644
--- a/ui/css/main.css
+++ b/ui/css/main.css
@@ -1048,4 +1048,77 @@ tbody {
   background-color: #2a9fd6;
   border-color: transparent;
   cursor: default;
-}
\ No newline at end of file
+}
+
+.normal{
+  background-color: #00C853;
+  border-radius: 5px; 
+  padding:3px 4px;
+}
+
+.unnormal{
+  background-color: #EF5350;
+  border-radius: 5px; 
+  padding:3px 4px;
+}
+
+
+#timePopup{
+  position: absolute;
+  z-index:1;
+  height:100px;
+  background-color:white; 
+  /*width:80%;*/
+  text-align: center;
+  border: 5px solid #c5c5c5;
+  border-radius: 3px;
+}
+
+#hourSelector{
+  width: 20%;
+  height: 100%;
+  display: inline-block;
+}
+
+#minuteSelector{
+  width:20%;
+  height:100%;
+  display: inline-block;
+
+}
+
+
+#secondSelector{
+  width:20%;
+  height:100%;
+  display: inline-block;
+
+}
+
+.division{
+  display: inline-block;
+  width:10%;
+  height:100%;
+  position:relative;
+  top: -30px;
+}
+
+.icon{
+  color: #fff;
+  position: absolute;
+  left: 50%;
+  top:20%;
+}
+
+
+
+.ng-cloak{display:none !important;}
+
+.mask{
+  width:100%;
+  height:100%;
+  position:fixed;
+  top:0;
+  left:0;
+  z-index:1;
+}

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/ui/img/logo.png
----------------------------------------------------------------------
diff --git a/ui/img/logo.png b/ui/img/logo.png
new file mode 100644
index 0000000..ee1a9e6
Binary files /dev/null and b/ui/img/logo.png differ

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/ui/img/spinner.gif
----------------------------------------------------------------------
diff --git a/ui/img/spinner.gif b/ui/img/spinner.gif
new file mode 100644
index 0000000..21b4b71
Binary files /dev/null and b/ui/img/spinner.gif differ

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/ui/index.html
----------------------------------------------------------------------
diff --git a/ui/index.html b/ui/index.html
index bf623c8..a5f9323 100644
--- a/ui/index.html
+++ b/ui/index.html
@@ -46,6 +46,8 @@ under the License.
     <link href="pages/measures/measure.css" rel="stylesheet">
     <link href="pages/metrics/metrics.css" rel="stylesheet">
     <link href="pages/template/bigchart.css" rel="stylesheet">
+    <link href="bower_components/jquery-ui/themes/base/jquery-ui.css" 
rel="stylesheet">
+
     <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media 
queries -->
     <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
     <!--[if lt IE 9]>
@@ -69,7 +71,7 @@ under the License.
                 <span class="icon-bar"></span>
                 <span class="icon-bar"></span>
             </button>
-            <a href="#!/" class="navbar-brand" 
style="padding-top:5px;padding-bottom:0;"><img src="/img/logo.gif" title="Data 
Quality Service" style="max-height:40px;"/></a>
+            <a href="#!/" class="navbar-brand" 
style="padding-top:5px;padding-bottom:0;"><img src="/img/logo.png" title="Data 
Quality Service" style="max-height:40px;"/></a>
         </div>
 
         <!-- Collect the nav links, forms, and other content for toggling -->
@@ -135,10 +137,10 @@ under the License.
 
     <div id="footerwrap" class="navbar-fixed-bottom" 
ng-controller="FooterCtrl">
         <!-- <footer class="clearfix"></footer> -->
-        <div class="container-fluid">
-            <div class="row ">
-                <p ng-show="!notifications">{{timestamp|date:'short'}} - 
Welcome <label>{{fullName}}</label>!</p>
-                <p ng-repeat="r in notifications">
+        <div class="container-fluid" class="ng-cloak">
+            <div class="row" ng-show="timestamp|date:'short'">
+                <p ng-show="!notifications" 
class="ng-cloak">{{timestamp|date:'short'}} - Welcome 
<label>{{fullName}}</label>!</p>
+                <p ng-repeat="r in notifications" class="ng-cloak">
                     {{r.timestamp|date:'short'}} - <label>{{r.owner}}</label> 
{{r.operation}}d a {{r.target}} named
                     <a ng-if="r.target=='model'" 
href="#!/viewrule/{{r.name}}">{{r.name}}</a>
                     <label ng-if="r.target=='dataasset'">"{{r.name}}"</label>

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/ui/js/bs.js
----------------------------------------------------------------------
diff --git a/ui/js/bs.js b/ui/js/bs.js
index 58ea793..c3d20c3 100644
--- a/ui/js/bs.js
+++ b/ui/js/bs.js
@@ -23,7 +23,8 @@ define([
     'bootstrap',
     'angular',
     'app',
-    'routes'
+    'routes',
+    'jquery-ui'
 ], function (require, $, bootstrap, angular) {
     'use strict';
 

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/ui/js/controllers/createjob-ac-ctrl.js
----------------------------------------------------------------------
diff --git a/ui/js/controllers/createjob-ac-ctrl.js 
b/ui/js/controllers/createjob-ac-ctrl.js
index e5e9457..1d0e688 100644
--- a/ui/js/controllers/createjob-ac-ctrl.js
+++ b/ui/js/controllers/createjob-ac-ctrl.js
@@ -20,39 +20,70 @@ under the License.
 
 define(['./module'], function(controllers) {
     'use strict';
-    controllers.controller('CreateJobACCtrl', ['$scope', '$http', '$config', 
'$location', 'toaster', '$timeout', '$route', '$filter', function($scope, 
$http, $config, $location, toaster, $timeout, $route, $filter) {
+    controllers.controller('CreateJobACCtrl', ['$scope', '$http', '$config', 
'$location', 'toaster', '$timeout', '$route', '$filter', 
'$barkChart',function($scope, $http, $config, $location, toaster, $timeout, 
$route, $filter,$barkChart) {
         console.log('Create job controller');
         $scope.currentStep = 1;
+        var echarts = require('echarts');
+        $( "#datepicker" ).datepicker();
 
         $scope.Times = ['seconds','minutes','hours'];
         $scope.timeType = 'seconds';
+        $scope.isOpen = false;
+        $scope.maskOpen = false;
+
+        $scope.hourDetail = '00';
+        $scope.minuteDetail = '00';
+        $scope.secondDetail = '00';
+        $scope.timeDetail = '00:00:00';
+
+        $scope.changeTime = function(min,max,increase,time,type){
+            time = parseInt(time);
+            if(increase){
+                if(time==max)
+                    time = min;
+                else time = time + 1;
+            }
+            else{
+                if(time==min)
+                    time = max;
+                else time = time - 1;
+            }
+            if(time < 10)
+                time = '0' + time;
+
+            if(type==1)
+                $scope.hourDetail = time;
+            else if(type==2)
+                $scope.minuteDetail = time;
+            else
+                $scope.secondDetail = time;
+            $scope.timeDetail = 
$scope.hourDetail+':'+$scope.minuteDetail+':'+$scope.secondDetail;
+
+        }
+
+        $scope.showTime = function(){
+            $scope.isOpen = !$scope.isOpen;
+            $scope.maskOpen = !$scope.maskOpen;
+        }
+
+        $scope.close = function(){
+            $scope.isOpen = false;
+            $scope.maskOpen = false;
+        }
 
         $scope.Measures = [];
         $scope.$on('$viewContentLoaded', function() {
-            // console.log($('#footerwrap').css('height'));
-            // console.log($('.formStep').offset());
             $scope.$emit('initReq');
             resizeWindow();
-
-            //  $('#confirm').on('hidden.bs.modal', function (e) {
-            //    console.log('hidden');
-            //   //  $('#confirm').off('hidden.bs.modal');
-            //    $location.path('/rules');
-            //   });
-
-            // $('.formStep').css({height: 800});
         });
         var getMeasureUrl = $config.uri.getMeasuresByOwner+$scope.ntAccount;
         $http.get(getMeasureUrl).then(function successCallback(res){
             angular.forEach(res.data,function(measure){
                 $scope.Measures.push(measure);
             })
-            console.log($scope.Measures);
             $scope.measure = 0;
         })
 
-
-
         $scope.$on('resizeHandler', function(e) {
             if ($route.current.$$route.controller == "CreateRuleACCtrl") {
                 $scope.$emit('initReq');
@@ -60,17 +91,19 @@ define(['./module'], function(controllers) {
             }
         });
 
-
         function resizeWindow() {
-                    var stepSelection = '.formStep[id=step-' + 
$scope.currentStep + ']';
-                    $(stepSelection).css({
-                        height: window.innerHeight - 
$(stepSelection).offset().top - $('#footerwrap').outerHeight()
-                    });
-                    $('fieldset').height($(stepSelection).height() - 
$(stepSelection + '>.stepDesc').height() - $('.btn-container').height() - 80);
-                    $('.y-scrollable').css({
-                        'max-height': $('fieldset').height()- 
$('.add-dataset').outerHeight()
-                    });
-
+            var stepSelection = '.formStep';
+            $(stepSelection).css({
+                height: window.innerHeight - $(stepSelection).offset().top - 
$('#footerwrap').outerHeight()
+            });
+            $('fieldset').height($(stepSelection).height() - $(stepSelection + 
'>.stepDesc').height() - $('.btn-container').height() - 80);
+            $('.y-scrollable').css({
+                'max-height': $('fieldset').height()- 
$('.add-dataset').outerHeight()
+            });
+            $('#data-asset-pie').css({
+                height: $('#data-asset-pie').parent().width(),
+                width: $('#data-asset-pie').parent().width()
+            });
         }
 
         // Initial Value
@@ -105,76 +138,63 @@ define(['./module'], function(controllers) {
                         period = $scope.periodTime * 3600;
                     else period = $scope.periodTime;
                     var rule = '';
-                    var startTime = '';
-                    var year = $scope.jobStartTime.substr(0,4);
-                    var month = $scope.jobStartTime.substr(4,2);
-                    var day = $scope.jobStartTime.substr(6,2);
-                    startTime = year +'-'+ month + '-'+ day + ' '+ 
$scope.jobStartTime.split(' ')[1];
+                    var startTime = $scope.jobStartTime;
+                    console.log(startTime);
+                    var year = $scope.jobStartTime.split('/')[2];
+                    var month = $scope.jobStartTime.split('/')[0];
+                    var day = $scope.jobStartTime.split('/')[1];
+                    startTime = year +'-'+ month + '-'+ day + ' '+ 
$scope.timeDetail;
+                    console.log(startTime);
                     startTime = Date.parse(startTime);
                     if(isNaN(startTime)){
                         toaster.pop('error','Please input the right format of 
start time');
                         return;
                     }
                     this.data={
-                      "sourcePat":$scope.sourcePat,
-                      "targetPat":$scope.targetPat,
-                      "jobStartTime":startTime,
-                      "periodTime":period,
-                      "groupName":'BA',
+                        "sourcePattern":$scope.sourcePat,
+                        "targetPattern":$scope.targetPat,
+                        "jobStartTime":startTime,
+                        "interval":period,
+                        "groupName":'BA',
                     };
                     $('#confirm-job').modal('show');
                 }
             },
 
             save: function() {
-
-
                 //::TODO: Need to save the data to backend with POST/PUT method
-                console.log(JSON.stringify($scope.form.data));
-
-//                var newModel = $config.uri.newAccuracyModel;
-//                var BACKEND_SERVER = '';
-               var date = new Date();
+                var date = new Date();
                 var month = date.getMonth()+1;
                 var timestamp = Date.parse(date);
-                // timestamp = timestamp / 1000;
-                // var time = date.toDateString()+' 
'+date.toLocaleTimeString();
-                var jobName = $scope.Measures[$scope.measure] + '-BA-' + 
$scope.ntAccount + '-' + timestamp;
+                var jobName = $scope.Measures[$scope.measure].name + '-BA-' + 
$scope.ntAccount + '-' + timestamp;
 
-                var newJob = $config.uri.addJobs + this.data.groupName + '/' + 
jobName + '/' + $scope.Measures[$scope.measure];
+                var newJob = $config.uri.addJobs + '?group=' + 
this.data.groupName + '&jobName=' + jobName + '&measureId=' + 
$scope.Measures[$scope.measure].id;
                 console.log(newJob);
                 console.log(this.data);
                 $http.post(newJob, this.data).then(function 
successCallback(data) {
-                       // if(data.status=='0')
-                       // {
-                         console.log(data);
-                      // if(data=='fail'){
-                      //     toaster.pop('error', 'Please modify the name of 
job, because there is already a same model in database ', data.message);
-                      //     return;
-                      // }
-
-                         $('#confirm-job').on('hidden.bs.modal', function(e) {
-                             $('#confirm-job').off('hidden.bs.modal');
-                             $location.path('/jobs').replace();
-                             $scope.$apply();
-                         });
-                               $('#confirm-job').modal('hide');
-                       // }
-                       // else
-                       // {
-                       //      errorMessage(0, data.result);
-                       // }
-
-                // }).error(function(data){
-                //   // errorMessage(0, 'Save model failed, please try 
again!');
-                //   toaster.pop('error', 'Save job failed, please try 
again!', data.message);
-                // });
-                      },function errorCallback(response) {
-                        toaster.pop('error', 'Error when creating job', 
response.message);
+                       $('#confirm-job').on('hidden.bs.modal', function(e) {
+                           $('#confirm-job').off('hidden.bs.modal');
+                           $location.path('/jobs').replace();
+                           $scope.$apply();
+                       });
+                       $('#confirm-job').modal('hide');
+                    var health_url = $config.uri.statistics;
+                    $scope.status = new Object();
+                    $http.get(health_url).then(function 
successCallback(response){
+                        response = response.data;
+                        $scope.status.health = response.healthyJobCount;
+                        $scope.status.invalid = response.jobCount - 
response.healthyJobCount;
+                        $('#data-asset-pie').css({
+                            height: $('#data-asset-pie').parent().width(),
+                            width: $('#data-asset-pie').parent().width()
                         });
-
+                        $scope.dataAssetPieChart = 
echarts.init($('#data-asset-pie')[0], 'dark');
+                        
$scope.dataAssetPieChart.setOption($barkChart.getOptionPie($scope.status));
+                    });
+                },function errorCallback(response) {
+                    toaster.pop('error', 'Error when creating job', 
response.message);
+                });
             },
-
         }
 
         var errorMessage = function(i, msg) {
@@ -187,6 +207,4 @@ define(['./module'], function(controllers) {
         };
     }
     ]);
-
-
 });

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/ui/js/controllers/createrule-ac-ctrl.js
----------------------------------------------------------------------
diff --git a/ui/js/controllers/createrule-ac-ctrl.js 
b/ui/js/controllers/createrule-ac-ctrl.js
index 1ddbcfe..6dc6d2b 100644
--- a/ui/js/controllers/createrule-ac-ctrl.js
+++ b/ui/js/controllers/createrule-ac-ctrl.js
@@ -37,62 +37,52 @@ define(['./module'], function(controllers) {
         var dbtreeUrl = $config.uri.dbtree;
         var schemaDefinitionUrl = $config.uri.schemadefinition;
 
-        $http.get(dbtreeUrl).then(function successCallback(data) {
-                    var dbList = [];
-                    if (data.data) {
-                        angular.forEach(data.data,function(db,key){
-                        console.log(db);
-                        var dbNode = {
-                            name: key,
-                            l1: true,
-                            children: []
-                        };
-                        dbList.push(dbNode);
-                        if (db) {
-                               angular.forEach(db,function(table){
-                                   // console.log(table);
-                                   // console.log(typeof(table));
-                                   var dsNode = {
-                                       name: table.tableName,
-                                       l2: true,
-                                       children: []
-                                   };
-                                   dbNode.children.push(dsNode);
-                                   dsNode.parent = db;
-
-                                   if (table.sd.cols) {
-                                       table.sd.cols.sort(function(a, b){
-                                         return 
(a.name<b.name?-1:(a.name>b.name?1:0));
-                                       });
-                                       
angular.forEach(table.sd.cols,function(col) {
-                                           var schemaNode = {
-                                               name: col.name,
-                                               type: col.type,
-                                               l3: true
-                                           };
-//                                           schemaNode.parent = dsNode;
-//                                           dsNode.children.push(schemaNode);
-                                       });
-                                   }
-
-                               });
-                          };
-                        });
-                    $scope.dbList = dbList;
-                    $scope.dbListTarget = angular.copy(dbList);
-                    }
-
+        $http.get(dbtreeUrl,{cache: true}).then(function successCallback(data) 
{
+            var dbList = [];
+            if (data.data) {
+                angular.forEach(data.data,function(db,key){
+                    var dbNode = {
+                        name: key,
+                        l1: true,
+                        children: []
+                    };
+                    dbList.push(dbNode);
+                    if (db) {
+                        angular.forEach(db,function(table){
+                            var dsNode = {
+                                name: table.tableName,
+                                l2: true,
+                                children: []
+                            };
+                            dbNode.children.push(dsNode);
+                            dsNode.parent = db;
+                            if (table.sd.cols) {
+                                table.sd.cols.sort(function(a, b){
+                                    return 
(a.name<b.name?-1:(a.name>b.name?1:0));
+                                });
+                                angular.forEach(table.sd.cols,function(col) {
+                                    var schemaNode = {
+                                        name: col.name,
+                                        type: col.type,
+                                        l3: true
+                                    };
+                                });
+                            }
+                         });
+                    };
                 });
+                $scope.dbList = dbList;
+                $scope.dbListTarget = angular.copy(dbList);
+            }
+        });
 
         //trigger after select schema for src
         $scope.$watch('currentNode', function(newValue) {
             console.log(newValue);
             $scope.selection = [];
             $scope.selectedAll = false;
-
-            // $scope.schemaCollection = null;
             if (newValue) {
-                $http.get(schemaDefinitionUrl+ '/' + 
newValue.parent[0].dbName+'/table/'+newValue.name).then(function 
successCallback(data) {
+                $http.get(schemaDefinitionUrl+ '?db=' + 
newValue.parent[0].dbName+'&table='+newValue.name).then(function 
successCallback(data) {
                 console.log(data);
                 $scope.schemaCollection = data.data.sd.cols;
                 console.log($scope.schemaCollection);
@@ -102,72 +92,33 @@ define(['./module'], function(controllers) {
         });
 
         $scope.selectNodeLabelTarget = function(selectedNode) {
-
             //remove highlight from previous node
             if ($scope.currentNodeTarget && $scope.currentNodeTarget.selected) 
{
                 $scope.currentNodeTarget.selected = undefined;
             }
-
             if (selectedNode.children && selectedNode.children.length > 0) {
                 $scope.selectNodeHead(selectedNode);
             } else {
                 //set highlight to selected node
                 selectedNode.selected = 'selected';
             }
-
             //set currentNode
             $scope.currentNodeTarget = selectedNode;
-            console.log('currentNodeTarget');
-            console.log($scope.currentNodeTarget);
             $scope.dataAsset = $scope.currentNodeTarget.name + ',' + 
$scope.currentNode.name;
-            console.log($scope.dataAsset);
-        }
-        ;
-
+        };
         //trigger after select schema
         $scope.$watch('currentNodeTarget', function(newValue) {
-            console.log('currentNodeTarget');
-            console.log($scope.currentNodeTarget);
-            console.log(newValue);
             $scope.selectionTarget = [];
             $scope.selectedAllTarget = false;
-
-            // $scope.schemaCollection = null;
-//            if (newValue) {
-//
-//                //retrieve the schema definition and display the table
-//                if(newValue.l3){//System selected
-//                  var sysName = newValue.parent.name;
-//                  $scope.form.basic.system = $filter('stridx')(sysName, 
'modelsystem') + '';
-//                  $http.get(schemaDefinitionUrl + '/' + 
newValue.id).success(function(data) {
-//
-//                      $scope.schemaCollectionTarget = data.schema;
-//                  });
-//                }
-//
-//
-//            }
             if (newValue) {
-                $http.get(schemaDefinitionUrl + '/' + 
newValue.parent[0].dbName+'/table/'+newValue.name).then(function 
successCallback(data) {
-                console.log(data);
+                $http.get(schemaDefinitionUrl + '?db=' + 
newValue.parent[0].dbName+'&table='+newValue.name).then(function 
successCallback(data) {
                 $scope.schemaCollectionTarget = data.data.sd.cols;
-                console.log($scope.schemaCollectionTarget);
                 });
             }
             if($scope.currentNodeTarget)
                 $scope.dataAsset = $scope.currentNodeTarget.name + ',' + 
$scope.currentNode.name;
-            console.log($scope.dataAsset);
         });
 
-        // $scope.$watch('selectionTarget', function(newValue) {
-        //     if (newValue && newValue.length > 0) {
-        //         $scope.pk = newValue[0];
-        //         // console.log('-----$scope.pk: ' + $scope.pk);
-        //     }
-        // });
-
-        //column selection
-
         $scope.toggleSelection = function toggleSelection($event) {
             var value = $event.target.value;
             var idx = $scope.selection.indexOf(value);
@@ -177,12 +128,10 @@ define(['./module'], function(controllers) {
                 $scope.selectedAll = false;
             }
             // is newly selected
-
             else {
                 $scope.selection.push(value);
             }
-        }
-        ;
+        };
 
         $scope.toggleAll = function() {
             if ($scope.selectedAll) {
@@ -190,7 +139,6 @@ define(['./module'], function(controllers) {
             } else {
                 $scope.selectedAll = false;
             }
-
             $scope.selection = [];
             angular.forEach($scope.schemaCollection, function(item) {
                 item.selected = $scope.selectedAll;
@@ -198,7 +146,6 @@ define(['./module'], function(controllers) {
                     $scope.selection.push($scope.currentNode.name + '.' + 
item.name);
                 }
             });
-
         }
 
         $scope.toggleSelectionTarget = function($event) {
@@ -209,8 +156,6 @@ define(['./module'], function(controllers) {
                 $scope.selectionTarget.splice(idx, 1);
                 $scope.selectedAllTarget = false;
             }
-            // is newly selected
-
             else {
                 $scope.selectionTarget.push(value);
             }
@@ -229,14 +174,8 @@ define(['./module'], function(controllers) {
                 item.selected = $scope.selectedAllTarget;
                 if ($scope.selectedAllTarget) {
                     $scope.selectionTarget.push($scope.currentNodeTarget.name 
+ '.' + item.name);
-                    console.log('currentNodeTarget');
-                    console.log($scope.currentNodeTarget);
-                    console.log($scope.currentNodeTarget.parent);
-
                 }
-
             });
-
         }
 
         $scope.toggleSelectionPK = function($event) {
@@ -267,18 +206,7 @@ define(['./module'], function(controllers) {
         };
 
         $scope.$on('$viewContentLoaded', function() {
-            // console.log($('#footerwrap').css('height'));
-            // console.log($('.formStep').offset());
-            $scope.$emit('initReq');
             resizeWindow();
-
-            //  $('#confirm').on('hidden.bs.modal', function (e) {
-            //    console.log('hidden');
-            //   //  $('#confirm').off('hidden.bs.modal');
-            //    $location.path('/rules');
-            //   });
-
-            // $('.formStep').css({height: 800});
         });
 
         $scope.$on('resizeHandler', function(e) {
@@ -288,8 +216,8 @@ define(['./module'], function(controllers) {
             }
         });
 
-
         function resizeWindow() {
+
                     var stepSelection = '.formStep[id=step-' + 
$scope.currentStep + ']';
                     $(stepSelection).css({
                         height: window.innerHeight - 
$(stepSelection).offset().top - $('#footerwrap').outerHeight()
@@ -301,6 +229,7 @@ define(['./module'], function(controllers) {
 //                        'max-height': $('fieldset').height()- 
$('.add-dataset').outerHeight()
 //                    });
 
+
         }
 
         $scope.ruleTypes = $filter('strarr')('modeltype');//['Accuracy', 
'Validity', 'Anomaly Detection', 'Publish Metrics'];
@@ -308,21 +237,6 @@ define(['./module'], function(controllers) {
         $scope.ruleSystems = $filter('strarr')('modelsystem');//['Bullseye', 
'GPS', 'Hadoop', 'PDS', 'IDLS', 'Pulsar', 'Kafka'];
         $scope.matchFunctions = ['==', '!==', '>', '>=','<',"<="];
 
-        // $scope.ruleType = function(index){
-        //   var types = ['', 'Accuracy', 'Validity', 'Anomaly Detection', 
'Publish Metrics'];
-        //   return types[index];
-        // }
-        //
-        // $scope.scheduleType = function(index){
-        //   var types = ['', 'Daily', 'Weekly', 'Monthly', 'Hourly'];
-        //   return types[index];
-        // }
-        //
-        // $scope.ruleSystem = function(index){
-        //   var sys = ['', 'Bullseye', 'GPS', 'Hadoop', 'PDS', 'IDLS', 
'Pulsar', 'Kafka'];
-        //   return sys[index];
-        // }
-
         // Initial Value
         $scope.form = {
 
@@ -433,16 +347,6 @@ define(['./module'], function(controllers) {
                     });
                     rule = rules.join(" AND ");
 
-//                    for(var i = 0;i<$scope.selectionTarget.length;i++){
-//                         console.log($scope.selection[i]);
-//                         var s =$scope.selection[i].split('.');
-//                         var t = $scope.selectionTarget[i].split('.');
-//
-//                         console.log( $scope.matches[i]);
-//                         rule += "${source}['" + s[1] + "'] "+ 
$scope.matches[i]+" ${target}['" + t[1] + "'];" ;
-//                    }
-
-
                     $scope.rules = rule;
                     this.data.evaluateRule.rules = rule;
                     for(var i =0; i < $scope.selectionTarget.length; i ++){
@@ -451,57 +355,29 @@ define(['./module'], function(controllers) {
                                       matchMethod: $scope.matches[i],
                                       isPk: 
($scope.selectionPK.indexOf($scope.selectionTarget[i])>-1)?true:false});
                     }
-
                     $('#confirm').modal('show');
                 }
             },
 
             save: function() {
-
-
                 //::TODO: Need to save the data to backend with POST/PUT method
-                console.log(JSON.stringify($scope.form.data));
-
                 var newModel = $config.uri.addModels;
                 $http.post(newModel, this.data).then(function 
successCallback(data) {
-                       // if(data.status=='0')
-                       // {
-                         console.log(data);
-                      if(data.data=='CREATE_MEASURE_FAIL_DUPLICATE'){
-                          toaster.pop('error', 'Please modify the name of 
measure, because there is already a same measure in database ', data.message);
-                          return;
-                      }
-
-                         $('#confirm').on('hidden.bs.modal', function(e) {
-                             $('#confirm').off('hidden.bs.modal');
-                             $location.path('/rules').replace();
-                             $scope.$apply();
-                         });
-                               $('#confirm').modal('hide');
-                       // }
-                       // else
-                       // {
-                       //      errorMessage(0, data.result);
-                       // }
-
-                // }).error(function(data){
-                //   // errorMessage(0, 'Save model failed, please try 
again!');
-                //   toaster.pop('error', 'Save measure failed, please try 
again!', data.message);
-                // });
-                      },function errorCallback(response) {
-                            toaster.pop('error', 'Save measure failed, please 
try again!', response.message);
+                    if(data.data.code=='408')
+                        toaster.pop('error','Create Measure Failed, duplicate 
records');
+                    $('#confirm').on('hidden.bs.modal', function(e) {
+                        $('#confirm').off('hidden.bs.modal');
+                        $location.path('/measures').replace();
+                        $scope.$apply();
                     });
-
+                    $('#confirm').modal('hide');
+                },function errorCallback(response) {
+                    toaster.pop('error', 'Error when creating measure', 
response.message);
+                }
+                );
             },
-
-            // reset: function() {
-            //
-            // },
-            //
-            // ruleType: 1
         }
 
-
         var nextStep = function() {
             $scope.currentStep++;
             $timeout(function(){

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/ui/js/controllers/dataassets-ctrl.js
----------------------------------------------------------------------
diff --git a/ui/js/controllers/dataassets-ctrl.js 
b/ui/js/controllers/dataassets-ctrl.js
index 64a33e0..7df1895 100644
--- a/ui/js/controllers/dataassets-ctrl.js
+++ b/ui/js/controllers/dataassets-ctrl.js
@@ -21,12 +21,23 @@ define(['./module'], function (controllers) {
     'use strict';
     controllers.controller('DataAssetsCtrl', ['$scope', '$http', '$config', 
'$location', 'toaster', '$timeout', '$route', '$filter', function ($scope, 
$http, $config, $location, toaster, $timeout, $route, $filter) {
 
-      var allModels = $config.uri.dataassetlist;
+      var allDataassets = $config.uri.dataassetlist;
       var ts = null;
       var start = 0;
       var number = 10;
       var originalRowCollection = undefined;
 
+      $scope.isIE = function() {
+            var ua = window.navigator.userAgent;
+            var msie = ua.indexOf("MSIE ");
+            if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)){
+               return true; 
+            }
+            else {
+               return false;
+            }
+        }
+
       $scope.paging = function(tableState){
         console.log(tableState);
         ts = tableState;
@@ -35,12 +46,7 @@ define(['./module'], function (controllers) {
         number = tableState.pagination.number || 10;
 
         if(start == 0 && !$scope.rowCollection){
-          $http.get(allModels).then(function successCallback(data) {
-            if(data.data){
-              // data.sort(function(a,b){
-              //   return -(a.timestamp - b.timestamp);
-              // });
-            }
+          $http.get(allDataassets,{cache: true}).then(function 
successCallback(data) {
             originalRowCollection = new Array();
             angular.forEach(data.data,function(db){
               angular.forEach(db,function(table){
@@ -48,14 +54,13 @@ define(['./module'], function (controllers) {
               });
             });
 
-            // originalRowCollection = angular.copy(data);
             $scope.rowCollection = angular.copy(originalRowCollection);
-            // $scope.rowCollection.sort(function(a,b){
-            //   return 
(a.assetName<b.assetName?-1:(a.assetName>b.assetName?1:0));
-            // });
 
             $scope.displayed = $scope.rowCollection.slice(start, start+number);
             tableState.pagination.numberOfPages = 
Math.ceil($scope.rowCollection.length/number);
+          },function errorCallback(data){
+            console.log(data);
+            toaster.pop('error','Get data assets failed',data.data.message);
           });
         }else{
           $scope.displayed = $scope.rowCollection.slice(start, start+number);

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/1cf0a99e/ui/js/controllers/detail-ctrl.js
----------------------------------------------------------------------
diff --git a/ui/js/controllers/detail-ctrl.js b/ui/js/controllers/detail-ctrl.js
index f03cba4..d0f3dc5 100644
--- a/ui/js/controllers/detail-ctrl.js
+++ b/ui/js/controllers/detail-ctrl.js
@@ -60,7 +60,7 @@ define(['./module'], function (controllers) {
 
         function pageInit() {
             $scope.$emit('initReq');
-            showBig($routeParams.modelname);
+            showBig($routeParams.modelname);            
         }
 
         $scope.$on('resizeHandler', function(e) {
@@ -70,6 +70,8 @@ define(['./module'], function (controllers) {
                 $scope.myChart.resize();
             }
         });
+        
+
 
         function resizeTreeMap() {
             $('#chart1').height( $('#mainWindow').height() - 
$('.bs-component').outerHeight() );


Reply via email to