@Override
 public final void execute(final JobExecutionContext context) throws JobExecutionException {
   log.debug("Elastic job: job execute begin, job execution context:{}.", context);
   shardingService.shardingIfNecessary();
   JobExecutionMultipleShardingContext shardingContext =
       executionContextService.getJobExecutionShardingContext();
   if (executionService.misfireIfNecessary(shardingContext.getShardingItems())) {
     log.info(
         "Previous job is still running, new job will start after previous job completed. Misfired job had recorded.");
     return;
   }
   executionService.cleanPreviousExecutionInfo();
   executeJobInternal(shardingContext);
   log.debug("Elastic job: execute normal completed, sharding context:{}.", shardingContext);
   while (!executionService.getMisfiredJobItems(shardingContext.getShardingItems()).isEmpty()
       && !stoped
       && !shardingService.isNeedSharding()) {
     log.debug("Elastic job: execute misfired job, sharding context:{}.", shardingContext);
     executionService.clearMisfire(shardingContext.getShardingItems());
     executeJobInternal(shardingContext);
     log.debug("Elastic job: misfired job completed, sharding context:{}.", shardingContext);
   }
   if (configService.isFailover() && !stoped) {
     failoverService.failoverIfNecessary();
   }
   log.debug("Elastic job: execute all completed, job execution context:{}.", context);
 }
 @Test
 public void assertFailoverIfUnnecessaryWhenItemsRootNodeNotExisted() {
   when(jobNodeStorage.isJobNodeExisted("leader/failover/items")).thenReturn(false);
   failoverService.failoverIfNecessary();
   verify(jobNodeStorage).isJobNodeExisted("leader/failover/items");
   verify(jobNodeStorage, times(0))
       .executeInLeader(
           eq("leader/failover/latch"), Matchers.<FailoverLeaderExecutionCallback>any());
 }
 @Test
 public void assertFailoverIfUnnecessaryWhenItemsRootNodeIsEmpty() {
   when(jobNodeStorage.isJobNodeExisted("leader/failover/items")).thenReturn(true);
   when(jobNodeStorage.getJobNodeChildrenKeys("leader/failover/items"))
       .thenReturn(Collections.<String>emptyList());
   failoverService.failoverIfNecessary();
   verify(jobNodeStorage).isJobNodeExisted("leader/failover/items");
   verify(jobNodeStorage).getJobNodeChildrenKeys("leader/failover/items");
   verify(jobNodeStorage, times(0))
       .executeInLeader(
           eq("leader/failover/latch"), Matchers.<FailoverLeaderExecutionCallback>any());
 }
 @Test
 public void assertFailoverIfNecessary() {
   when(jobNodeStorage.isJobNodeExisted("leader/failover/items")).thenReturn(true);
   when(jobNodeStorage.getJobNodeChildrenKeys("leader/failover/items"))
       .thenReturn(Arrays.asList("0", "1", "2"));
   when(serverService.isLocalhostServerReady()).thenReturn(true);
   failoverService.failoverIfNecessary();
   verify(jobNodeStorage).isJobNodeExisted("leader/failover/items");
   verify(jobNodeStorage).getJobNodeChildrenKeys("leader/failover/items");
   verify(serverService).isLocalhostServerReady();
   verify(jobNodeStorage)
       .executeInLeader(
           eq("leader/failover/latch"), Matchers.<FailoverLeaderExecutionCallback>any());
 }