package org.camunda.bpm.integrationtest.jobexecutor;

import java.util.List;
import java.util.Set;

import org.camunda.bpm.BpmPlatform;
import org.camunda.bpm.ProcessEngineService;
import org.camunda.bpm.application.ProcessApplicationDeploymentInfo;
import org.camunda.bpm.engine.ProcessEngine;
import org.camunda.bpm.engine.impl.ProcessEngineImpl;
import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.camunda.bpm.engine.impl.cmd.AcquireJobsCmd;
import org.camunda.bpm.engine.impl.interceptor.CommandExecutor;
import org.camunda.bpm.engine.impl.jobexecutor.AcquiredJobs;
import org.camunda.bpm.engine.impl.jobexecutor.JobExecutor;
import org.camunda.bpm.engine.runtime.Job;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.camunda.bpm.integrationtest.util.AbstractFoxPlatformIntegrationTest;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.OperateOnDeployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(Arquillian.class)
public class IndependentJobExecutionTest extends AbstractFoxPlatformIntegrationTest {
  
  private ProcessEngine engine1;
  private ProcessEngineConfigurationImpl engine1Configuration;
  
  @Before
  public void setEngines() {
    ProcessEngineService engineService = BpmPlatform.getProcessEngineService();
    engine1 = engineService.getProcessEngine("engine1");
    engine1Configuration = ((ProcessEngineImpl) engine1).getProcessEngineConfiguration();
  }

  @Deployment(order = 0, name="pa1")
  public static WebArchive processArchive1() {    
    
    return initWebArchiveDeployment("pa1.war", "org/camunda/bpm/integrationtest/jobexecutor/pa1.xml")
        .addAsResource("org/camunda/bpm/integrationtest/jobexecutor/archive1process.bpmn20.xml");
            
  }
  
  @Deployment(order = 1, name="pa2")
  public static WebArchive processArchive2() {    
    
    return initWebArchiveDeployment("pa2.war", "org/camunda/bpm/integrationtest/jobexecutor/pa2.xml")
        .addAsResource("org/camunda/bpm/integrationtest/jobexecutor/archive2process.bpmn20.xml");
  }
  
  @OperateOnDeployment("pa1")
  @Test
  public void testDeploymentRegistration() {
    Set<String> registeredDeploymentsForEngine1 = engine1.getManagementService().getRegisteredDeployments();
    Set<String> registeredDeploymentsForDefaultEngine = processEngine.getManagementService().getRegisteredDeployments();
    System.out.println(BpmPlatform.getProcessApplicationService().getProcessApplicationNames());
    List<ProcessApplicationDeploymentInfo> pa1DeploymentInfo = BpmPlatform.getProcessApplicationService().getProcessApplicationInfo("/pa1").getDeploymentInfo();
    
    Assert.assertEquals(1, pa1DeploymentInfo.size());
    Assert.assertTrue(registeredDeploymentsForEngine1.contains(pa1DeploymentInfo.get(0).getDeploymentId()));
    
    List<ProcessApplicationDeploymentInfo> pa2DeploymentInfo = BpmPlatform.getProcessApplicationService().getProcessApplicationInfo("/pa2").getDeploymentInfo();
    Assert.assertEquals(1, pa2DeploymentInfo.size());
    Assert.assertTrue(registeredDeploymentsForDefaultEngine.contains(pa2DeploymentInfo.get(0).getDeploymentId()));
  }
  
  @OperateOnDeployment("pa1")
  @Test
  public void testIndependentJobExecution() {
    JobExecutor jobExecutor1 = engine1Configuration.getJobExecutor();
    JobExecutor defaultJobExecutor = processEngineConfiguration.getJobExecutor();
    
    ProcessInstance instance1 = engine1.getRuntimeService().startProcessInstanceByKey("archive1Process");
    ProcessInstance instance2 = processEngine.getRuntimeService().startProcessInstanceByKey("archive2Process");
    
    Job job1 = managementService.createJobQuery().processInstanceId(instance1.getId()).singleResult();
    Job job2 = managementService.createJobQuery().processInstanceId(instance2.getId()).singleResult();
    
    
    // the deployment aware configuration should only return the jobs of the registered deployments
    CommandExecutor commandExecutor = engine1Configuration.getCommandExecutorTxRequired();
    AcquiredJobs acquiredJobs = commandExecutor.execute(new AcquireJobsCmd(jobExecutor1));
    
    Assert.assertEquals(1, acquiredJobs.size());
    Assert.assertTrue(acquiredJobs.contains(job1.getId()));
    Assert.assertFalse(acquiredJobs.contains(job2.getId()));
    
    // the deployment unaware configuration should return both jobs
    commandExecutor = processEngineConfiguration.getCommandExecutorTxRequired();
    acquiredJobs = commandExecutor.execute(new AcquireJobsCmd(defaultJobExecutor));
    
    Assert.assertEquals(2, acquiredJobs.size());
    Assert.assertTrue(acquiredJobs.contains(job1.getId()));
    Assert.assertTrue(acquiredJobs.contains(job2.getId()));
  }
}

@@ -3396,35 +3396,41 @@
 oid test
-IndependentJobExecu
+DeploymentAwareJobAcquisi
 tion() %7B
@@ -3504,90 +3504,8 @@
 ();%0A
-    JobExecutor defaultJobExecutor = processEngineConfiguration.getJobExecutor();%0A
     
@@ -4393,32 +4393,647 @@
 job2.getId()));%0A
+  %7D%0A  %0A  @OperateOnDeployment(%22pa1%22)%0A  @Test%0A  public void testDeploymentUnawareJobAcquisition() %7B%0A    JobExecutor defaultJobExecutor = processEngineConfiguration.getJobExecutor();%0A    %0A    ProcessInstance instance1 = engine1.getRuntimeService().startProcessInstanceByKey(%22archive1Process%22);%0A    ProcessInstance instance2 = processEngine.getRuntimeService().startProcessInstanceByKey(%22archive2Process%22);%0A    %0A    Job job1 = managementService.createJobQuery().processInstanceId(instance1.getId()).singleResult();%0A    Job job2 = managementService.createJobQuery().processInstanceId(instance2.getId()).singleResult();%0A
     %0A    // the 
@@ -5093,16 +5093,32 @@
 obs%0A    
+CommandExecutor 
 commandE
@@ -5190,16 +5190,29 @@
 ();%0A    
+AcquiredJobs 
 acquired

fix job acquisition test setup