[GRIFFIN-237] Implement service method get JobInstanceBean by id

Implement service method getting JobInstanceBean by JobInstanceBean id

Author: Randal Boyle <rboyle@hotels.com>
Author: jhsb25 <37844993+jhsb25@users.noreply.github.com>

Closes #486 from jhsb25/GRIFFIN-237.
diff --git a/service/src/main/java/org/apache/griffin/core/exception/GriffinExceptionMessage.java b/service/src/main/java/org/apache/griffin/core/exception/GriffinExceptionMessage.java
index edfe8e9..6a9b9da 100644
--- a/service/src/main/java/org/apache/griffin/core/exception/GriffinExceptionMessage.java
+++ b/service/src/main/java/org/apache/griffin/core/exception/GriffinExceptionMessage.java
@@ -74,6 +74,8 @@
 
     PREDICATE_TYPE_NOT_FOUND(40408, "Unknown predicate type"),
 
+    INSTANCE_ID_DOES_NOT_EXIST(40409, "Instance id does not exist"),
+
     //409, "Conflict"
     MEASURE_NAME_ALREADY_EXIST(40901, "Measure name already exists"),
 
diff --git a/service/src/main/java/org/apache/griffin/core/job/JobController.java b/service/src/main/java/org/apache/griffin/core/job/JobController.java
index b5274a8..7bd58bb 100644
--- a/service/src/main/java/org/apache/griffin/core/job/JobController.java
+++ b/service/src/main/java/org/apache/griffin/core/job/JobController.java
@@ -94,6 +94,11 @@
         return jobService.findInstancesOfJob(id, page, size);
     }
 
+    @RequestMapping(value = "/jobs/instances/{instanceId}", method = RequestMethod.GET)
+    public JobInstanceBean findInstanceByInstanceId(@PathVariable("instanceId") Long id) {
+        return jobService.findInstance(id);
+    }
+
     @RequestMapping(value = "/jobs/health", method = RequestMethod.GET)
     public JobHealth getHealthInfo() {
         return jobService.getHealthInfo();
diff --git a/service/src/main/java/org/apache/griffin/core/job/JobService.java b/service/src/main/java/org/apache/griffin/core/job/JobService.java
index 42415d9..87d27f6 100644
--- a/service/src/main/java/org/apache/griffin/core/job/JobService.java
+++ b/service/src/main/java/org/apache/griffin/core/job/JobService.java
@@ -46,5 +46,8 @@
 
     String getJobHdfsSinksPath(String jobName, long timestamp);
 
+    JobInstanceBean findInstance(Long id);
+
     void triggerJobById(Long id) throws SchedulerException;
+  
 }
diff --git a/service/src/main/java/org/apache/griffin/core/job/JobServiceImpl.java b/service/src/main/java/org/apache/griffin/core/job/JobServiceImpl.java
index a7fc546..a2ef010 100644
--- a/service/src/main/java/org/apache/griffin/core/job/JobServiceImpl.java
+++ b/service/src/main/java/org/apache/griffin/core/job/JobServiceImpl.java
@@ -69,13 +69,7 @@
 import static java.util.TimeZone.getTimeZone;
 import static org.apache.griffin.core.config.EnvConfig.ENV_BATCH;
 import static org.apache.griffin.core.config.EnvConfig.ENV_STREAMING;
-import static org.apache.griffin.core.exception.GriffinExceptionMessage.INVALID_MEASURE_ID;
-import static org.apache.griffin.core.exception.GriffinExceptionMessage.JOB_ID_DOES_NOT_EXIST;
-import static org.apache.griffin.core.exception.GriffinExceptionMessage.JOB_NAME_DOES_NOT_EXIST;
-import static org.apache.griffin.core.exception.GriffinExceptionMessage.JOB_TYPE_DOES_NOT_SUPPORT;
-import static org.apache.griffin.core.exception.GriffinExceptionMessage.MEASURE_TYPE_DOES_NOT_SUPPORT;
-import static org.apache.griffin.core.exception.GriffinExceptionMessage.NO_SUCH_JOB_ACTION;
-import static org.apache.griffin.core.exception.GriffinExceptionMessage.QUARTZ_JOB_ALREADY_EXIST;
+import static org.apache.griffin.core.exception.GriffinExceptionMessage.*;
 import static org.apache.griffin.core.job.entity.LivySessionStates.State.STARTING;
 import static org.apache.griffin.core.job.entity.LivySessionStates.State.UNKNOWN;
 import static org.apache.griffin.core.job.entity.LivySessionStates.State.NOT_STARTED;
@@ -281,6 +275,17 @@
         return updateState(instances);
     }
 
+    @Override
+    public JobInstanceBean findInstance(Long id) {
+        JobInstanceBean bean = instanceRepo.findByInstanceId(id);
+        if (bean == null) {
+            LOGGER.warn("Instance id {} does not exist.", id);
+            throw new GriffinException
+                .NotFoundException(INSTANCE_ID_DOES_NOT_EXIST);
+        }
+        return bean;
+    }
+
     private List<JobInstanceBean> updateState(List<JobInstanceBean> instances) {
         for (JobInstanceBean instance : instances) {
             State state = instance.getState();
diff --git a/service/src/main/java/org/apache/griffin/core/job/repo/JobInstanceRepo.java b/service/src/main/java/org/apache/griffin/core/job/repo/JobInstanceRepo.java
index aa932e9..997a79c 100644
--- a/service/src/main/java/org/apache/griffin/core/job/repo/JobInstanceRepo.java
+++ b/service/src/main/java/org/apache/griffin/core/job/repo/JobInstanceRepo.java
@@ -34,6 +34,9 @@
 
     JobInstanceBean findByPredicateName(String name);
 
+    @Query("select s from JobInstanceBean s where s.id = ?1")
+    JobInstanceBean findByInstanceId(Long id);
+
     @Query("select s from JobInstanceBean s where s.job.id = ?1")
     List<JobInstanceBean> findByJobId(Long jobId, Pageable pageable);
 
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 ab39b16..d9d5d80 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
@@ -19,6 +19,7 @@
 
 package org.apache.griffin.core.job;
 
+import static org.apache.griffin.core.exception.GriffinExceptionMessage.INSTANCE_ID_DOES_NOT_EXIST;
 import static org.apache.griffin.core.exception.GriffinExceptionMessage.JOB_ID_DOES_NOT_EXIST;
 import static org.apache.griffin.core.exception.GriffinExceptionMessage.JOB_NAME_DOES_NOT_EXIST;
 import static org.apache.griffin.core.util.EntityMocksHelper.createGriffinJob;
@@ -164,6 +165,27 @@
     }
 
     @Test
+    public void testFindInstance() throws Exception {
+        JobInstanceBean jobInstance = new JobInstanceBean(1L, LivySessionStates
+                .State.RUNNING, "", "", null, null);
+        given(service.findInstance(1L)).willReturn(jobInstance);
+
+        mvc.perform(get(URLHelper.API_VERSION_PATH + "/jobs/instances/1"))
+                .andExpect(status().isOk())
+                .andExpect(jsonPath("$.state", is("RUNNING")));
+    }
+
+    @Test
+    public void testFindInstanceForFailureWithNotFound() throws Exception {
+        Long id = 1L;
+        doThrow(new GriffinException.NotFoundException(INSTANCE_ID_DOES_NOT_EXIST))
+            .when(service).findInstance(id);
+
+        mvc.perform(get(URLHelper.API_VERSION_PATH + "/jobs/instances/1"))
+           .andExpect(status().isNotFound());
+    }
+
+    @Test
     public void testGetHealthInfo() throws Exception {
         JobHealth jobHealth = new JobHealth(1, 3);
         given(service.getHealthInfo()).willReturn(jobHealth);
diff --git a/service/src/test/java/org/apache/griffin/core/job/repo/JobInstanceRepoTest.java b/service/src/test/java/org/apache/griffin/core/job/repo/JobInstanceRepoTest.java
index 76b81df..508a663 100644
--- a/service/src/test/java/org/apache/griffin/core/job/repo/JobInstanceRepoTest.java
+++ b/service/src/test/java/org/apache/griffin/core/job/repo/JobInstanceRepoTest.java
@@ -31,8 +31,10 @@
 import static org.apache.griffin.core.job.entity.LivySessionStates.State.SUCCESS;
 import static org.assertj.core.api.Assertions.assertThat;
 
+import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.avro.generic.GenericData;
 import org.apache.griffin.core.config.EclipseLinkJpaConfigForTest;
 import org.apache.griffin.core.job.entity.BatchJob;
 import org.apache.griffin.core.job.entity.JobInstanceBean;
@@ -57,6 +59,8 @@
     @Autowired
     private JobInstanceRepo jobInstanceRepo;
 
+    private List<Long> entityIds;
+
     @Before
     public void setup() {
         entityManager.clear();
@@ -79,6 +83,12 @@
     }
 
     @Test
+    public void testFindByInstanceId() {
+        JobInstanceBean bean = jobInstanceRepo.findByInstanceId(entityIds.get(0));
+        assertThat(bean).isNotNull();
+    }
+
+    @Test
     public void testFindByExpireTmsLessThanEqual() {
         List<JobInstanceBean> beans = jobInstanceRepo
                 .findByExpireTmsLessThanEqual(1516004640092L);
@@ -128,5 +138,10 @@
         entityManager.persistAndFlush(bean2);
         entityManager.persistAndFlush(bean3);
         entityManager.persistAndFlush(bean4);
+        entityIds = new ArrayList<>();
+        entityIds.add(bean1.getId());
+        entityIds.add(bean2.getId());
+        entityIds.add(bean3.getId());
+        entityIds.add(bean4.getId());
     }
 }