Package org.camunda.bpm.engine.test.api.mgmt

Source Code of org.camunda.bpm.engine.test.api.mgmt.ManagementServiceTest

/* Licensed 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.camunda.bpm.engine.test.api.mgmt;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import junit.framework.Assert;

import org.camunda.bpm.engine.ProcessEngineException;
import org.camunda.bpm.engine.history.HistoricIncident;
import org.camunda.bpm.engine.impl.ProcessEngineImpl;
import org.camunda.bpm.engine.impl.cmd.AcquireJobsCmd;
import org.camunda.bpm.engine.impl.incident.FailedJobIncidentHandler;
import org.camunda.bpm.engine.impl.interceptor.Command;
import org.camunda.bpm.engine.impl.interceptor.CommandContext;
import org.camunda.bpm.engine.impl.interceptor.CommandExecutor;
import org.camunda.bpm.engine.impl.persistence.entity.HistoricIncidentEntity;
import org.camunda.bpm.engine.impl.persistence.entity.HistoricIncidentManager;
import org.camunda.bpm.engine.impl.persistence.entity.JobEntity;
import org.camunda.bpm.engine.impl.persistence.entity.JobManager;
import org.camunda.bpm.engine.impl.persistence.entity.MessageEntity;
import org.camunda.bpm.engine.impl.test.PluggableProcessEngineTestCase;
import org.camunda.bpm.engine.impl.util.ClockUtil;
import org.camunda.bpm.engine.management.JobDefinition;
import org.camunda.bpm.engine.management.TableMetaData;
import org.camunda.bpm.engine.runtime.Job;
import org.camunda.bpm.engine.runtime.JobQuery;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.camunda.bpm.engine.test.Deployment;


/**
* @author Frederik Heremans
* @author Falko Menge
* @author Saeid Mizaei
* @author Joram Barrez
*/
public class ManagementServiceTest extends PluggableProcessEngineTestCase {

  public void testGetMetaDataForUnexistingTable() {
    TableMetaData metaData = managementService.getTableMetaData("unexistingtable");
    assertNull(metaData);
  }

  public void testGetMetaDataNullTableName() {
    try {
      managementService.getTableMetaData(null);
      fail("ProcessEngineException expected");
    } catch (ProcessEngineException re) {
      assertTextPresent("tableName is null", re.getMessage());
    }
  }

  public void testExecuteJobNullJobId() {
    try {
      managementService.executeJob(null);
      fail("ProcessEngineException expected");
    } catch (ProcessEngineException re) {
      assertTextPresent("jobId is null", re.getMessage());
    }
  }

  public void testExecuteJobUnexistingJob() {
    try {
      managementService.executeJob("unexistingjob");
      fail("ProcessEngineException expected");
    } catch (ProcessEngineException ae) {
      assertTextPresent("No job found with id", ae.getMessage());
    }
  }


  @Deployment
  public void testGetJobExceptionStacktrace() {
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("exceptionInJobExecution");

    // The execution is waiting in the first usertask. This contains a boundry
    // timer event which we will execute manual for testing purposes.
    Job timerJob = managementService.createJobQuery()
      .processInstanceId(processInstance.getId())
      .singleResult();

    assertNotNull("No job found for process instance", timerJob);

    try {
      managementService.executeJob(timerJob.getId());
      fail("RuntimeException from within the script task expected");
    } catch(RuntimeException re) {
      assertTextPresent("This is an exception thrown from scriptTask", re.getMessage());
    }

    // Fetch the task to see that the exception that occurred is persisted
    timerJob = managementService.createJobQuery()
    .processInstanceId(processInstance.getId())
    .singleResult();

    Assert.assertNotNull(timerJob);
    Assert.assertNotNull(timerJob.getExceptionMessage());
    assertTextPresent("This is an exception thrown from scriptTask", timerJob.getExceptionMessage());

    // Get the full stacktrace using the managementService
    String exceptionStack = managementService.getJobExceptionStacktrace(timerJob.getId());
    Assert.assertNotNull(exceptionStack);
    assertTextPresent("This is an exception thrown from scriptTask", exceptionStack);
  }

  public void testgetJobExceptionStacktraceUnexistingJobId() {
    try {
      managementService.getJobExceptionStacktrace("unexistingjob");
      fail("ProcessEngineException expected");
    } catch (ProcessEngineException re) {
      assertTextPresent("No job found with id unexistingjob", re.getMessage());
    }
  }

  public void testgetJobExceptionStacktraceNullJobId() {
    try {
      managementService.getJobExceptionStacktrace(null);
      fail("ProcessEngineException expected");
    } catch (ProcessEngineException re) {
      assertTextPresent("jobId is null", re.getMessage());
    }
  }

  @Deployment(resources = {"org/camunda/bpm/engine/test/api/mgmt/ManagementServiceTest.testGetJobExceptionStacktrace.bpmn20.xml"})
  public void testSetJobRetries() {
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("exceptionInJobExecution");

    // The execution is waiting in the first usertask. This contains a boundary
    // timer event.
    Job timerJob = managementService.createJobQuery()
      .processInstanceId(processInstance.getId())
      .singleResult();

    assertNotNull("No job found for process instance", timerJob);
    assertEquals(JobEntity.DEFAULT_RETRIES, timerJob.getRetries());

    managementService.setJobRetries(timerJob.getId(), 5);

    timerJob = managementService.createJobQuery()
      .processInstanceId(processInstance.getId())
      .singleResult();
    assertEquals(5, timerJob.getRetries());
  }

  @Deployment(resources = {"org/camunda/bpm/engine/test/api/mgmt/ManagementServiceTest.testGetJobExceptionStacktrace.bpmn20.xml"})
  public void testSetJobRetriesNullCreatesIncident() {

    // initially there is no incident
    assertEquals(0, runtimeService.createIncidentQuery().count());

    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("exceptionInJobExecution");

    // The execution is waiting in the first usertask. This contains a boundary
    // timer event.
    Job timerJob = managementService.createJobQuery()
      .processInstanceId(processInstance.getId())
      .singleResult();

    assertNotNull("No job found for process instance", timerJob);
    assertEquals(JobEntity.DEFAULT_RETRIES, timerJob.getRetries());

    managementService.setJobRetries(timerJob.getId(), 0);

    timerJob = managementService.createJobQuery()
      .processInstanceId(processInstance.getId())
      .singleResult();
    assertEquals(0, timerJob.getRetries());

    assertEquals(1, runtimeService.createIncidentQuery().count());

  }

  public void testSetJobRetriesUnexistingJobId() {
    try {
      managementService.setJobRetries("unexistingjob", 5);
      fail("ProcessEngineException expected");
    } catch (ProcessEngineException re) {
      assertTextPresent("No job found with id 'unexistingjob'.", re.getMessage());
    }
  }

  public void testSetJobRetriesEmptyJobId() {
    try {
      managementService.setJobRetries("", 5);
      fail("ProcessEngineException expected");
    } catch (ProcessEngineException re) {
      assertTextPresent("Either job definition id or job id has to be provided as parameter.", re.getMessage());
    }
  }

  public void testSetJobRetriesJobIdNull() {
    try {
      managementService.setJobRetries(null, 5);
      fail("ProcessEngineException expected");
    } catch (ProcessEngineException re) {
      assertTextPresent("Either job definition id or job id has to be provided as parameter.", re.getMessage());
    }
  }

  public void testSetJobRetriesNegativeNumberOfRetries() {
    try {
      managementService.setJobRetries("unexistingjob", -1);
      fail("ProcessEngineException expected");
    } catch (ProcessEngineException re) {
      assertTextPresent("The number of job retries must be a non-negative Integer, but '-1' has been provided.", re.getMessage());
    }
  }

  @Deployment(resources = {"org/camunda/bpm/engine/test/api/mgmt/ManagementServiceTest.testGetJobExceptionStacktrace.bpmn20.xml"})
  public void testSetJobRetriesByJobDefinitionId() {
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("exceptionInJobExecution");
    executeAvailableJobs();

    JobQuery query = managementService.createJobQuery()
        .processInstanceId(processInstance.getId());

    JobDefinition jobDefinition = managementService
        .createJobDefinitionQuery()
        .singleResult();

    Job timerJob = query.singleResult();

    assertNotNull("No job found for process instance", timerJob);
    assertEquals(0, timerJob.getRetries());

    managementService.setJobRetriesByJobDefinitionId(jobDefinition.getId(), 5);

    timerJob = query.singleResult();
    assertEquals(5, timerJob.getRetries());
  }

  public void testSetJobRetriesByJobDefinitionIdEmptyJobDefinitionId() {
    try {
      managementService.setJobRetriesByJobDefinitionId("", 5);
      fail("ProcessEngineException expected");
    } catch (ProcessEngineException re) {
      assertTextPresent("Either job definition id or job id has to be provided as parameter.", re.getMessage());
    }
  }

  public void testSetJobRetriesByJobDefinitionIdNull() {
    try {
      managementService.setJobRetriesByJobDefinitionId(null, 5);
      fail("ProcessEngineException expected");
    } catch (ProcessEngineException re) {
      assertTextPresent("Either job definition id or job id has to be provided as parameter.", re.getMessage());
    }
  }

  public void testSetJobRetriesByJobDefinitionIdNegativeNumberOfRetries() {
    try {
      managementService.setJobRetries("unexistingjob", -1);
      fail("ProcessEngineException expected");
    } catch (ProcessEngineException re) {
      assertTextPresent("The number of job retries must be a non-negative Integer, but '-1' has been provided.", re.getMessage());
    }
  }

  public void testSetJobRetriesUnlocksInconsistentJob() {
    // case 1
    // given an inconsistent job that is never again picked up by a job executor
    createJob(0, "owner", ClockUtil.getCurrentTime());

    // when the job retries are reset
    JobEntity job = (JobEntity) managementService.createJobQuery().singleResult();
    managementService.setJobRetries(job.getId(), 3);

    // then the job can be picked up again
    job = (JobEntity) managementService.createJobQuery().singleResult();
    assertNotNull(job);
    assertNull(job.getLockOwner());
    assertNull(job.getLockExpirationTime());
    assertEquals(3, job.getRetries());

    deleteJobAndIncidents(job);

    // case 2
    // given an inconsistent job that is never again picked up by a job executor
    createJob(2, "owner", null);

    // when the job retries are reset
    job = (JobEntity) managementService.createJobQuery().singleResult();
    managementService.setJobRetries(job.getId(), 3);

    // then the job can be picked up again
    job = (JobEntity) managementService.createJobQuery().singleResult();
    assertNotNull(job);
    assertNull(job.getLockOwner());
    assertNull(job.getLockExpirationTime());
    assertEquals(3, job.getRetries());

    deleteJobAndIncidents(job);

    // case 3
    // given a consistent job
    createJob(2, "owner", ClockUtil.getCurrentTime());

    // when the job retries are reset
    job = (JobEntity) managementService.createJobQuery().singleResult();
    managementService.setJobRetries(job.getId(), 3);

    // then the lock owner and expiration should not change
    job = (JobEntity) managementService.createJobQuery().singleResult();
    assertNotNull(job);
    assertNotNull(job.getLockOwner());
    assertNotNull(job.getLockExpirationTime());
    assertEquals(3, job.getRetries());

    deleteJobAndIncidents(job);
  }

  protected void createJob(final int retries, final String owner, final Date lockExpirationTime) {
    CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutorTxRequired();
    commandExecutor.execute(new Command<Void>() {
      public Void execute(CommandContext commandContext) {
        JobManager jobManager = commandContext.getJobManager();
        MessageEntity job = new MessageEntity();
        job.setJobHandlerType("any");
        job.setLockOwner(owner);
        job.setLockExpirationTime(lockExpirationTime);
        job.setRetries(retries);

        jobManager.send(job);
        return null;
      }
    });
  }

  @Deployment(resources = {"org/camunda/bpm/engine/test/api/mgmt/ManagementServiceTest.testGetJobExceptionStacktrace.bpmn20.xml"})
  public void testSetJobRetriesByDefinitionUnlocksInconsistentJobs() {
    // given a job definition
    final JobDefinition jobDefinition = managementService.createJobDefinitionQuery().singleResult();

    // and an inconsistent job that is never again picked up by a job executor
    CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutorTxRequired();
    commandExecutor.execute(new Command<Void>() {
      public Void execute(CommandContext commandContext) {
        JobManager jobManager = commandContext.getJobManager();
        MessageEntity job = new MessageEntity();
        job.setJobDefinitionId(jobDefinition.getId());
        job.setJobHandlerType("any");
        job.setLockOwner("owner");
        job.setLockExpirationTime(ClockUtil.getCurrentTime());
        job.setRetries(0);

        jobManager.send(job);
        return null;
      }
    });

    // when the job retries are reset
    managementService.setJobRetriesByJobDefinitionId(jobDefinition.getId(), 3);

    // then the job can be picked up again
    JobEntity job = (JobEntity) managementService.createJobQuery().singleResult();
    assertNotNull(job);
    assertNull(job.getLockOwner());
    assertNull(job.getLockExpirationTime());
    assertEquals(3, job.getRetries());

    deleteJobAndIncidents(job);
  }

  protected void deleteJobAndIncidents(final Job job) {
    final List<HistoricIncident> incidents =
        historyService.createHistoricIncidentQuery()
        .incidentType(FailedJobIncidentHandler.INCIDENT_HANDLER_TYPE).list();

    CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutorTxRequired();
    commandExecutor.execute(new Command<Void>() {
      public Void execute(CommandContext commandContext) {
        ((JobEntity) job).delete();

        HistoricIncidentManager historicIncidentManager = commandContext.getHistoricIncidentManager();
        for (HistoricIncident incident : incidents) {
          HistoricIncidentEntity incidentEntity = (HistoricIncidentEntity) incident;
          historicIncidentManager.delete(incidentEntity);
        }
        return null;
      }
    });
  }

  public void testDeleteJobNullJobId() {
    try {
      managementService.deleteJob(null);
      fail("ProcessEngineException expected");
    } catch (ProcessEngineException re) {
      assertTextPresent("jobId is null", re.getMessage());
    }
  }

  public void testDeleteJobUnexistingJob() {
    try {
      managementService.deleteJob("unexistingjob");
      fail("ProcessEngineException expected");
    } catch (ProcessEngineException ae) {
      assertTextPresent("No job found with id", ae.getMessage());
    }
  }

  @Deployment(resources = { "org/camunda/bpm/engine/test/api/mgmt/timerOnTask.bpmn20.xml" })
  public void testDeleteJobDeletion() {
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("timerOnTask");
    Job timerJob = managementService.createJobQuery().processInstanceId(processInstance.getId()).singleResult();

    assertNotNull("Task timer should be there", timerJob);
    managementService.deleteJob(timerJob.getId());

    timerJob = managementService.createJobQuery().processInstanceId(processInstance.getId()).singleResult();
    assertNull("There should be no job now. It was deleted", timerJob);
  }

  @Deployment(resources = { "org/camunda/bpm/engine/test/api/mgmt/timerOnTask.bpmn20.xml" })
  public void testDeleteJobThatWasAlreadyAcquired() {
    ClockUtil.setCurrentTime(new Date());

    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("timerOnTask");
    Job timerJob = managementService.createJobQuery().processInstanceId(processInstance.getId()).singleResult();

    // We need to move time at least one hour to make the timer executable
    ClockUtil.setCurrentTime(new Date(ClockUtil.getCurrentTime().getTime() + 7200000L));

    // Acquire job by running the acquire command manually
    ProcessEngineImpl processEngineImpl = (ProcessEngineImpl) processEngine;
    AcquireJobsCmd acquireJobsCmd = new AcquireJobsCmd(processEngineImpl.getProcessEngineConfiguration().getJobExecutor());
    CommandExecutor commandExecutor = processEngineImpl.getProcessEngineConfiguration().getCommandExecutorTxRequired();
    commandExecutor.execute(acquireJobsCmd);

    // Try to delete the job. This should fail.
    try {
      managementService.deleteJob(timerJob.getId());
      fail();
    } catch (ProcessEngineException e) {
      // Exception is expected
    }

    // Clean up
    managementService.executeJob(timerJob.getId());
  }

  @Deployment(resources = {"org/camunda/bpm/engine/test/api/mgmt/ManagementServiceTest.testGetJobExceptionStacktrace.bpmn20.xml"})
  public void testSetJobDuedate() {
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("exceptionInJobExecution");

    // The execution is waiting in the first usertask. This contains a boundary
    // timer event.
    Job timerJob = managementService.createJobQuery()
      .processInstanceId(processInstance.getId())
      .singleResult();

    assertNotNull("No job found for process instance", timerJob);
    assertNotNull(timerJob.getDuedate());

    Calendar cal = Calendar.getInstance();
    cal.setTime(new Date());
    cal.add(Calendar.DATE, 3); // add 3 days on the actual date
    managementService.setJobDuedate(timerJob.getId(), cal.getTime());

    Job newTimerJob = managementService.createJobQuery()
      .processInstanceId(processInstance.getId())
      .singleResult();

    // normalize date for mysql dropping fractional seconds in time values
    int SECOND = 1000;
    assertEquals((cal.getTime().getTime() / SECOND) * SECOND,
                 (newTimerJob.getDuedate().getTime() / SECOND) * SECOND);
  }

  @Deployment(resources = {"org/camunda/bpm/engine/test/api/mgmt/ManagementServiceTest.testGetJobExceptionStacktrace.bpmn20.xml"})
  public void testSetJobDuedateDateNull() {
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("exceptionInJobExecution");

    // The execution is waiting in the first usertask. This contains a boundary
    // timer event.
    Job timerJob = managementService.createJobQuery()
      .processInstanceId(processInstance.getId())
      .singleResult();

    assertNotNull("No job found for process instance", timerJob);
    assertNotNull(timerJob.getDuedate());

    managementService.setJobDuedate(timerJob.getId(), null);

    timerJob = managementService.createJobQuery()
      .processInstanceId(processInstance.getId())
      .singleResult();

    assertNull(timerJob.getDuedate());
  }


  public void testSetJobDuedateJobIdNull() {
    try {
      managementService.setJobDuedate(null, new Date());
      fail("ProcessEngineException expected");
    } catch (ProcessEngineException re) {
      assertTextPresent("The job id is mandatory, but 'null' has been provided.", re.getMessage());
    }
  }

  public void testSetJobDuedateEmptyJobId() {
    try {
      managementService.setJobDuedate("", new Date());
      fail("ProcessEngineException expected");
    } catch (ProcessEngineException re) {
      assertTextPresent("The job id is mandatory, but '' has been provided.", re.getMessage());
    }
  }

  public void testSetJobDuedateUnexistingJobId() {
    try {
      managementService.setJobDuedate("unexistingjob", new Date());
      fail("ProcessEngineException expected");
    } catch (ProcessEngineException re) {
      assertTextPresent("No job found with id 'unexistingjob'.", re.getMessage());
    }
  }

  public void testGetProperties() {
    Map<String, String> properties = managementService.getProperties();
    assertNotNull(properties);
    assertFalse(properties.isEmpty());
  }

  public void  testSetProperty() {
    final String name = "testProp";
    final String value = "testValue";
    managementService.setProperty(name, value);

    Map<String, String> properties = managementService.getProperties();
    assertTrue(properties.containsKey(name));
    String storedValue = properties.get(name);
    assertEquals(value, storedValue);

    managementService.deleteProperty(name);
  }

  public void  testDeleteProperty() {
    final String name = "testProp";
    final String value = "testValue";
    managementService.setProperty(name, value);

    Map<String, String> properties = managementService.getProperties();
    assertTrue(properties.containsKey(name));
    String storedValue = properties.get(name);
    assertEquals(value, storedValue);

    managementService.deleteProperty(name);
    properties = managementService.getProperties();
    assertFalse(properties.containsKey(name));

  }

  public void  testDeleteNonexistingProperty() {

    managementService.deleteProperty("non existing");

  }

  public void testGetHistoryLevel() {
    int historyLevel = managementService.getHistoryLevel();
    assertEquals(processEngineConfiguration.getHistoryLevel().getId(), historyLevel);
  }

}
TOP

Related Classes of org.camunda.bpm.engine.test.api.mgmt.ManagementServiceTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.