This is an automated email from the ASF dual-hosted git repository.

guoyp pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/griffin.git


The following commit(s) were added to refs/heads/master by this push:
     new b2ed8f2  [GRIFFIN-240] trigger returns triggerkey
b2ed8f2 is described below

commit b2ed8f2b119f0ee35e6e1c4e07ab5b4585998666
Author: Rodion Gorkovenko <[email protected]>
AuthorDate: Sun Apr 14 09:20:45 2019 +0800

    [GRIFFIN-240] trigger returns triggerkey
    
    This PR requires updating tests and postman json yet, but I need it to show 
the proposed API before moving further. Triggering and searching by triggerKey 
- both works.
    
    Please look at the changes in `api-guide.md` for the proposed API additions.
    
    This is rework of #489 (in asynchronous way, without timeout)
    
    Author: Rodion Gorkovenko <[email protected]>
    Author: Rodion Gorkovenko <[email protected]>
    
    Closes #494 from RodionGork/GRIFFIN-240-trigger-returns-triggerkey.
---
 griffin-doc/service/api-guide.md                   | 42 ++++++++++-
 griffin-doc/service/postman/griffin.json           | 87 +++++++++++++++++++++-
 .../org/apache/griffin/core/job/JobController.java | 15 +++-
 .../org/apache/griffin/core/job/JobInstance.java   | 11 ++-
 .../org/apache/griffin/core/job/JobService.java    |  5 +-
 .../apache/griffin/core/job/JobServiceImpl.java    | 12 ++-
 .../griffin/core/job/entity/JobInstanceBean.java   | 13 ++++
 .../griffin/core/job/repo/JobInstanceRepo.java     |  2 +
 .../apache/griffin/core/job/JobControllerTest.java |  6 +-
 .../apache/griffin/core/job/JobInstanceTest.java   |  6 ++
 .../griffin/core/job/JobServiceImplTest.java       | 24 +++++-
 11 files changed, 203 insertions(+), 20 deletions(-)

diff --git a/griffin-doc/service/api-guide.md b/griffin-doc/service/api-guide.md
index 17bca5b..26435d6 100644
--- a/griffin-doc/service/api-guide.md
+++ b/griffin-doc/service/api-guide.md
@@ -36,10 +36,11 @@ Apache Griffin default `BASE_PATH` is `http://<your 
ip>:8080`.
 
 - [Griffin Jobs](#3)
     - [Add Job](#31)
-    - [Trigger job by id](37)
+    - [Trigger job by id](#37)
     - [Get Job](#32)
     - [Remove Job](#33)
     - [Get Job Instances](#34)
+    - [Get Job Instance by triggerKey](#38)
     - [Get Job Healthy Statistics](#35)
     - [Download Sample Records](#36)
     - [Get Job Instance by Id](#38)
@@ -549,9 +550,17 @@ curl -k -H "Content-Type: application/json" -H "Accept: 
application/json" \
 
 ### Trigger job by id
 `POST /api/v1/jobs/trigger/{job_id}`
+
+In the current version triggering the job in this way leads to scheduling of a 
single job instance. The method returns
+immediately even if starting it may take time. The response contains 
`triggerKey` by which the instance could be found
+when it is started (see [find instance by trigger key](#38)).
+
 #### API Example
 ```
-curl -k -X POST http://127.0.0.1:8080/api/v1/jobs/trigger/51
+curl -k -X POST http://127.0.0.1:8080/api/v1/jobs/trigger/101
+{
+    "triggerKey": "DEFAULT.6da64b5bd2ee-34e2cb23-11a2-4f92-9cbd-6cb3402cdb48",
+}
 ```
 
 <div id = "32"></div>
@@ -716,6 +725,35 @@ curl -k -G -X GET 
http://127.0.0.1:8080/api/v1/jobs/instances -d jobId=827 -d pa
 ]
 ```
 
+<div id = "38"></div>
+
+### Find job instance by triggerKey
+`GET /api/v1/jobs/triggerKeys/{triggerKey}`
+
+This could be used after [triggering the job by job id](#37) to find the job 
instance when it is scheduled.
+In the current version no more than one instance is triggered and thus the 
response is a list with single
+element (or empty list if not found).
+
+```
+curl 
http://127.0.0.1:8080/api/v1/jobs/triggerKeys/DEFAULT.6da64b5bd2ee-34e2cb23-11a2-4f92-9cbd-6cb3402cdb48
+[
+    {
+        "id":201,
+        "sessionId":1,
+        "state":"SUCCESS",
+        "type":"BATCH",
+        "appId":"application_1554199833471_0002",
+        
"appUri":"http://localhost:38088/cluster/app/application_1554199833471_0002";,
+        "predicateGroup":"PG",
+        "predicateName":"acc1a_name_predicate_1554202748883",
+        
"triggerKey":"DEFAULT.6da64b5bd2ee-34e2cb23-11a2-4f92-9cbd-6cb3402cdb49",
+        "timestamp":1554202748884,
+        "expireTimestamp":1554807548884
+    }
+]
+```
+
+
 <div id = "35"></div>
 
 ### Get job healthy statistics
diff --git a/griffin-doc/service/postman/griffin.json 
b/griffin-doc/service/postman/griffin.json
index 55d7bac..66445da 100644
--- a/griffin-doc/service/postman/griffin.json
+++ b/griffin-doc/service/postman/griffin.json
@@ -1598,7 +1598,7 @@
                                                "header": [],
                                                "body": {
                                                        "mode": "raw",
-                                                       "raw": ""
+                                                       "raw": "{\n\"timeout\": 
\"0\"\n}"
                                                },
                                                "url": {
                                                        "raw": 
"{{BASE_PATH}}/api/v1/jobs/trigger/:id",
@@ -1619,9 +1619,90 @@
                                                                }
                                                        ]
                                                },
-                                               "description": "`POST 
/api/v1/jobs/trigger/{id}`\n\n#### Path Variable\n- id -`required` `Long` job 
id\n\n#### Response\nThe response body should be empty if no error happens, and 
the HTTP status is (204, \"No Content\").\n\nIt may return failed messages. For 
example\n```\n{\n    \"timestamp\": 1517208792108,\n    \"status\": 404,\n    
\"error\": \"Not Found\",\n    \"code\": 40402,\n    \"message\": \"Job id does 
not exist\",\n    \"path\": \"/api/v1/jobs/trigger/2\"\n}\n```\nTher [...]
+                                               "description": "`POST 
/api/v1/jobs/trigger/{id}`\n\n#### Path Variable\n- id -`required` `Long` job 
id\n\n#### Response\nThe response body should be contains job instance fields 
if no error happens, and the HTTP status is (200, \"OK\").\n\nIt may return 
failed messages. For example\n```\n{\n    \"timestamp\": 1517208792108,\n    
\"status\": 404,\n    \"error\": \"Not Found\",\n    \"code\": 40402,\n    
\"message\": \"Job id does not exist\",\n    \"path\": 
\"/api/v1/jobs/trigger/2\ [...]
                                        },
-                                       "response": []
+                                       "response": [
+                                               {
+                                                       "name": "Trigger job by 
id example",
+                                                       "originalRequest": {
+                                                               "method": 
"POST",
+                                                               "header": [],
+                                                               "body": {
+                                                                       "mode": 
"raw",
+                                                                       "raw": 
"{\n\"timeout\": \"0\"\n}"
+                                                               },
+                                                               "url": {
+                                                                       "raw": 
"{{BASE_PATH}}/api/v1/jobs/trigger/:id",
+                                                                       "host": 
[
+                                                                               
"{{BASE_PATH}}"
+                                                                       ],
+                                                                       "path": 
[
+                                                                               
"api",
+                                                                               
"v1",
+                                                                               
"jobs",
+                                                                               
"trigger",
+                                                                               
":id"
+                                                                       ],
+                                                                       
"variable": [
+                                                                               
{
+                                                                               
        "key": "id",
+                                                                               
        "value": ""
+                                                                               
}
+                                                                       ]
+                                                               },
+                                                               "description": 
"`POST /api/v1/jobs/trigger/{id}`\n\n#### Path Variable\n- id -`required` 
`Long` job id\n\n#### Response\nThe response body should be contains job 
instance fields if no error happens, and the HTTP status is (200, 
\"OK\").\n\nIt may return failed messages. For example\n```\n{\n    
\"timestamp\": 1517208792108,\n    \"status\": 404,\n    \"error\": \"Not 
Found\",\n    \"code\": 40402,\n    \"message\": \"Job id does not exist\",\n   
 \"path\": \"/api/v1/jobs/trigger/ [...]
+                                                       },
+                                                       "status": "OK",
+                                                       "code": 200,
+                                                       
"_postman_previewlanguage": "json",
+                                                       "header": [
+                                                               {
+                                                                       "key": 
"access-control-allow-headers",
+                                                                       
"value": "X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept",
+                                                                       "name": 
"access-control-allow-headers",
+                                                                       
"description": "Used in response to a preflight request to indicate which HTTP 
headers can be used when making the actual request."
+                                                               },
+                                                               {
+                                                                       "key": 
"access-control-allow-methods",
+                                                                       
"value": "POST, GET, OPTIONS, DELETE,PUT",
+                                                                       "name": 
"access-control-allow-methods",
+                                                                       
"description": "Specifies the method or methods allowed when accessing the 
resource. This is used in response to a preflight request."
+                                                               },
+                                                               {
+                                                                       "key": 
"access-control-allow-origin",
+                                                                       
"value": "*",
+                                                                       "name": 
"access-control-allow-origin",
+                                                                       
"description": "Specifies a URI that may access the resource. For requests 
without credentials, the server may specify '*' as a wildcard, thereby allowing 
any origin to access the resource."
+                                                               },
+                                                               {
+                                                                       "key": 
"access-control-max-age",
+                                                                       
"value": "3600",
+                                                                       "name": 
"access-control-max-age",
+                                                                       
"description": "Indicates how long the results of a preflight request can be 
cached in seconds."
+                                                               },
+                                                               {
+                                                                       "key": 
"content-type",
+                                                                       
"value": "application/json;charset=UTF-8",
+                                                                       "name": 
"content-type",
+                                                                       
"description": "The mime type of this content"
+                                                               },
+                                                               {
+                                                                       "key": 
"date",
+                                                                       
"value": "Wed, 25 Oct 2017 01:43:23 GMT",
+                                                                       "name": 
"date",
+                                                                       
"description": "The date and time that the message was sent"
+                                                               },
+                                                               {
+                                                                       "key": 
"transfer-encoding",
+                                                                       
"value": "chunked",
+                                                                       "name": 
"transfer-encoding",
+                                                                       
"description": "The form of encoding used to safely transfer the entity to the 
user. Currently defined methods are: chunked, compress, deflate, gzip, 
identity."
+                                                               }
+                                                       ],
+                                                       "cookie": [],
+                                                       "body": "{\n        
\"id\": 1,\n        \"sessionId\": null,\n        \"state\": \"success\",\n     
   \"appId\": null,\n        \"appUri\": null,\n        \"predicateGroup\": 
\"PG\",\n        \"predicateName\": \"job_name_predicate_1515399840077\",\n     
   \"deleted\": true,\n        \"timestamp\": 1515399840092,\n        
\"expireTimestamp\": 1516004640092\n}"
+                                               }
+                                       ]
                                },
                                {
                                        "name": "Delete  job by name",
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 7bd58bb..1dfae81 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
@@ -19,13 +19,17 @@ under the License.
 
 package org.apache.griffin.core.job;
 
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.griffin.core.job.entity.AbstractJob;
 import org.apache.griffin.core.job.entity.JobHealth;
 import org.apache.griffin.core.job.entity.JobInstanceBean;
 import org.apache.griffin.core.util.FSUtil;
 import org.quartz.SchedulerException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.io.InputStreamResource;
 import org.springframework.core.io.Resource;
@@ -120,8 +124,13 @@ public class JobController {
     }
 
     @RequestMapping(value = "/jobs/trigger/{id}", method = RequestMethod.POST)
-    @ResponseStatus(HttpStatus.NO_CONTENT)
-    public void triggerJob(@PathVariable("id") Long id) throws 
SchedulerException {
-        jobService.triggerJobById(id);
+    @ResponseStatus(HttpStatus.OK)
+    public Map<String, Object> triggerJob(@PathVariable("id") Long id, 
@RequestBody(required = false) String request) throws SchedulerException {
+        return Collections.singletonMap("triggerKey", 
jobService.triggerJobById(id));
+    }
+
+    @RequestMapping(value = "jobs/triggerKeys/{triggerKey:.+}", method = 
RequestMethod.GET)
+    public List<JobInstanceBean> 
findInstanceByTriggerKey(@PathVariable("triggerKey") String triggerKey) {
+        return jobService.findInstancesByTriggerKey(triggerKey);
     }
 }
diff --git a/service/src/main/java/org/apache/griffin/core/job/JobInstance.java 
b/service/src/main/java/org/apache/griffin/core/job/JobInstance.java
index 47b42f3..0f34359 100644
--- a/service/src/main/java/org/apache/griffin/core/job/JobInstance.java
+++ b/service/src/main/java/org/apache/griffin/core/job/JobInstance.java
@@ -83,6 +83,7 @@ public class JobInstance implements Job {
     public static final String MEASURE_KEY = "measure";
     public static final String PREDICATES_KEY = "predicts";
     public static final String PREDICATE_JOB_NAME = "predicateJobName";
+    private static final String TRIGGER_KEY = "trigger";
     static final String JOB_NAME = "jobName";
     static final String PATH_CONNECTOR_CHARACTER = ",";
     public static final String INTERVAL = "interval";
@@ -127,6 +128,10 @@ public class JobInstance implements Job {
         Long measureId = job.getMeasureId();
         measure = measureRepo.findOne(measureId);
         setJobStartTime(jobDetail);
+        if (job.getConfigMap() == null) {
+            job.setConfigMap(new HashMap<>());
+        }
+        job.getConfigMap().put(TRIGGER_KEY, 
context.getTrigger().getKey().toString());
     }
 
     @SuppressWarnings("unchecked")
@@ -281,7 +286,8 @@ public class JobInstance implements Job {
             throw new GriffinException.ConflictException
                     (QUARTZ_JOB_ALREADY_EXIST);
         }
-        saveJobInstance(jobName, groupName);
+        String triggerKey = (String) confMap.get(TRIGGER_KEY);
+        saveJobInstance(jobName, groupName, triggerKey);
         createJobInstance(tk, interval, repeat, jobName);
     }
 
@@ -309,7 +315,7 @@ public class JobInstance implements Job {
         return confMap;
     }
 
-    private void saveJobInstance(String pName, String pGroup) {
+    private void saveJobInstance(String pName, String pGroup, String 
triggerKey) {
         ProcessType type = measure.getProcessType() == BATCH ? BATCH :
                 STREAMING;
         Long tms = System.currentTimeMillis();
@@ -319,6 +325,7 @@ public class JobInstance implements Job {
         JobInstanceBean instance = new JobInstanceBean(FINDING, pName, pGroup,
                 tms, expireTms, type);
         instance.setJob(job);
+        instance.setTriggerKey(triggerKey);
         instanceRepo.save(instance);
     }
 
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 87d27f6..d3492e8 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
@@ -42,12 +42,13 @@ public interface JobService {
 
     List<JobInstanceBean> findInstancesOfJob(Long jobId, int page, int size);
 
+    List<JobInstanceBean> findInstancesByTriggerKey(String triggerKey);
+
     JobHealth getHealthInfo();
 
     String getJobHdfsSinksPath(String jobName, long timestamp);
 
     JobInstanceBean findInstance(Long id);
 
-    void triggerJobById(Long id) throws SchedulerException;
-  
+    String 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 a2ef010..7492965 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
@@ -65,6 +65,8 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.TimeZone;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 import static java.util.TimeZone.getTimeZone;
 import static org.apache.griffin.core.config.EnvConfig.ENV_BATCH;
@@ -296,6 +298,11 @@ public class JobServiceImpl implements JobService {
         return instances;
     }
 
+    @Override
+    public List<JobInstanceBean> findInstancesByTriggerKey(String triggerKey) {
+        return instanceRepo.findByTriggerKey(triggerKey);
+    }
+
     /**
      * a job is regard as healthy job when its latest instance is in healthy
      * state.
@@ -661,7 +668,7 @@ public class JobServiceImpl implements JobService {
     }
 
     @Override
-    public void triggerJobById(Long id) throws SchedulerException {
+    public String triggerJobById(Long id) throws SchedulerException {
         AbstractJob job = jobRepo.findByIdAndDeleted(id, false);
         validateJobExist(job);
         Scheduler scheduler = factory.getScheduler();
@@ -672,8 +679,9 @@ public class JobServiceImpl implements JobService {
                     .startNow()
                     .build();
             scheduler.scheduleJob(trigger);
+            return trigger.getKey().toString();
         } else {
-            LOGGER.warn("Could not trigger job id {}.", id);
+            throw new 
GriffinException.NotFoundException(JOB_ID_DOES_NOT_EXIST);
         }
     }
 }
diff --git 
a/service/src/main/java/org/apache/griffin/core/job/entity/JobInstanceBean.java 
b/service/src/main/java/org/apache/griffin/core/job/entity/JobInstanceBean.java
index c3b0f1c..ef0b139 100644
--- 
a/service/src/main/java/org/apache/griffin/core/job/entity/JobInstanceBean.java
+++ 
b/service/src/main/java/org/apache/griffin/core/job/entity/JobInstanceBean.java
@@ -29,14 +29,17 @@ import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.EnumType;
 import javax.persistence.Enumerated;
+import javax.persistence.Index;
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
+import javax.persistence.Table;
 
 import org.apache.griffin.core.job.entity.LivySessionStates.State;
 import org.apache.griffin.core.measure.entity.AbstractAuditableEntity;
 import org.apache.griffin.core.measure.entity.GriffinMeasure.ProcessType;
 
 @Entity
+@Table(indexes = {@Index(columnList = "triggerKey")})
 public class JobInstanceBean extends AbstractAuditableEntity {
 
     private static final long serialVersionUID = -4748881017029815874L;
@@ -85,6 +88,8 @@ public class JobInstanceBean extends AbstractAuditableEntity {
     @JsonIgnore
     private AbstractJob job;
 
+    private String triggerKey;
+
     public AbstractJob getJob() {
         return job;
     }
@@ -183,6 +188,14 @@ public class JobInstanceBean extends 
AbstractAuditableEntity {
         this.deleted = deleted;
     }
 
+    public String getTriggerKey() {
+        return triggerKey;
+    }
+
+    public void setTriggerKey(String triggerKey) {
+        this.triggerKey = triggerKey;
+    }
+
     public JobInstanceBean() {
     }
 
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 997a79c..218717a 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
@@ -53,4 +53,6 @@ public interface JobInstanceRepo
 
     @Query("select DISTINCT s from JobInstanceBean s where s.state in ?1")
     List<JobInstanceBean> findByActiveState(State[] states);
+
+    List<JobInstanceBean> findByTriggerKey(String triggerKey);
 }
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 aa10cf2..6f94e0a 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
@@ -23,6 +23,7 @@ import static 
org.apache.griffin.core.exception.GriffinExceptionMessage.INSTANCE
 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;
+import static org.apache.griffin.core.util.EntityMocksHelper.createJobInstance;
 import static org.hamcrest.CoreMatchers.is;
 import static org.mockito.BDDMockito.given;
 import static org.mockito.Mockito.doNothing;
@@ -208,10 +209,11 @@ public class JobControllerTest {
 
     @Test
     public void testTriggerJobForSuccess() throws Exception {
-        doNothing().when(service).triggerJobById(1L);
+        Long id = 1L;
+        given(service.triggerJobById(id)).willReturn(null);
 
         mvc.perform(post(URLHelper.API_VERSION_PATH + "/jobs/trigger/1"))
-                .andExpect(status().isNoContent());
+                .andExpect(status().isOk());
     }
 
     @Test
diff --git 
a/service/src/test/java/org/apache/griffin/core/job/JobInstanceTest.java 
b/service/src/test/java/org/apache/griffin/core/job/JobInstanceTest.java
index 8e618de..af74600 100644
--- a/service/src/test/java/org/apache/griffin/core/job/JobInstanceTest.java
+++ b/service/src/test/java/org/apache/griffin/core/job/JobInstanceTest.java
@@ -30,6 +30,7 @@ import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Properties;
 
@@ -51,6 +52,7 @@ import org.quartz.JobKey;
 import org.quartz.Scheduler;
 import org.quartz.Trigger;
 import org.quartz.TriggerKey;
+import org.quartz.impl.triggers.AbstractTrigger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.boot.test.context.TestConfiguration;
@@ -115,6 +117,7 @@ public class JobInstanceTest {
         JobDetail jd = createJobDetail(JsonUtil.toJson(measure), "");
         BatchJob job = new BatchJob(1L, "jobName",
                 "qName", "qGroup", false);
+        job.setConfigMap(new HashMap<>());
         List<Trigger> triggers = Arrays.asList(createSimpleTrigger(2, 0));
         given(context.getJobDetail()).willReturn(jd);
         given(measureRepo.findOne(Matchers.anyLong())).willReturn(measure);
@@ -127,6 +130,9 @@ public class JobInstanceTest {
         given(jobRepo.save(Matchers.any(BatchJob.class))).willReturn(job);
         given(scheduler.checkExists(Matchers.any(JobKey.class)))
                 .willReturn(false);
+        Trigger trigger = mock(Trigger.class);
+        given(context.getTrigger()).willReturn(trigger);
+        given(trigger.getKey()).willReturn(new TriggerKey("test"));
         jobInstance.execute(context);
 
         verify(measureRepo, times(1)).findOne(Matchers.anyLong());
diff --git 
a/service/src/test/java/org/apache/griffin/core/job/JobServiceImplTest.java 
b/service/src/test/java/org/apache/griffin/core/job/JobServiceImplTest.java
index f5bd9b3..d48b824 100644
--- a/service/src/test/java/org/apache/griffin/core/job/JobServiceImplTest.java
+++ b/service/src/test/java/org/apache/griffin/core/job/JobServiceImplTest.java
@@ -21,20 +21,27 @@ package org.apache.griffin.core.job;
 
 import org.apache.griffin.core.exception.GriffinException;
 import org.apache.griffin.core.job.entity.AbstractJob;
+import org.apache.griffin.core.job.entity.JobInstanceBean;
+import org.apache.griffin.core.job.repo.JobInstanceRepo;
 import org.apache.griffin.core.job.repo.JobRepo;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
-import org.quartz.JobKey;
-import org.quartz.Scheduler;
-import org.quartz.SchedulerException;
+import org.quartz.*;
 import org.springframework.scheduling.quartz.SchedulerFactoryBean;
 import org.springframework.test.context.junit4.SpringRunner;
 
+import java.util.Collections;
+
 import static org.apache.griffin.core.util.EntityMocksHelper.createGriffinJob;
+import static org.apache.griffin.core.util.EntityMocksHelper.createJobInstance;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.BDDMockito.given;
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.internal.verification.VerificationModeFactory.times;
@@ -48,6 +55,9 @@ public class JobServiceImplTest {
     @Mock
     private SchedulerFactoryBean factory;
 
+    @Mock
+    private JobInstanceRepo instanceRepo;
+
     @InjectMocks
     private JobServiceImpl jobService;
 
@@ -59,9 +69,15 @@ public class JobServiceImplTest {
         given(jobRepo.findByIdAndDeleted(jobId,false)).willReturn(job);
         Scheduler scheduler = mock(Scheduler.class);
         given(scheduler.checkExists(any(JobKey.class))).willReturn(true);
+        ListenerManager listenerManager = mock(ListenerManager.class);
+        given(scheduler.getListenerManager()).willReturn(listenerManager);
         given(factory.getScheduler()).willReturn(scheduler);
-        jobService.triggerJobById(jobId);
+        JobInstanceBean jobInstanceBean = createJobInstance();
+        
given(instanceRepo.findByTriggerKey(anyString())).willReturn(Collections.singletonList(jobInstanceBean));
+
+        String result = jobService.triggerJobById(jobId);
 
+        assertTrue(result.matches("DEFAULT\\.[0-9a-f\\-]{49}"));
         verify(scheduler, times(1)).scheduleJob(any());
     }
 

Reply via email to