@Test
  public void testDeploymentAndExecutionOfProcessWithImports() {

    assertNotNull(deploymentService);

    DeploymentUnit deploymentUnit = new KModuleDeploymentUnit(GROUP_ID, ARTIFACT_ID, VERSION);
    deploymentService.deploy(deploymentUnit);
    units.add(deploymentUnit);
    DeployedUnit deployedGeneral =
        deploymentService.getDeployedUnit(deploymentUnit.getIdentifier());
    assertNotNull(deployedGeneral);
    assertNotNull(deployedGeneral.getDeploymentUnit());
    assertNotNull(deployedGeneral.getRuntimeManager());

    RuntimeManager manager = deploymentService.getRuntimeManager(deploymentUnit.getIdentifier());
    assertNotNull(manager);

    RuntimeEngine engine = manager.getRuntimeEngine(EmptyContext.get());
    assertNotNull(engine);

    Map<String, Object> params = new HashMap<String, Object>();

    ProcessInstance processInstance = engine.getKieSession().startProcess("Import", params);

    assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState());
  }
  @Test
  public void testDeploymentOfProcessesKieConteinerInjection() {

    assertNotNull(deploymentService);

    KModuleDeploymentUnit deploymentUnit =
        new KModuleDeploymentUnit(GROUP_ID, ARTIFACT_ID, VERSION, "KBase-test", "ksession-test-2");

    deploymentService.deploy(deploymentUnit);
    units.add(deploymentUnit);

    assertNotNull(deploymentUnit.getDeploymentDescriptor());

    DeployedUnit deployed = deploymentService.getDeployedUnit(deploymentUnit.getIdentifier());
    assertNotNull(deployed);
    assertNotNull(deployed.getDeploymentUnit());
    assertNotNull(deployed.getRuntimeManager());
    assertNull(deployed.getDeployedAssetLocation("customtask"));
    assertEquals(
        GROUP_ID + ":" + ARTIFACT_ID + ":" + VERSION + ":" + "KBase-test" + ":" + "ksession-test-2",
        deployed.getDeploymentUnit().getIdentifier());

    RuntimeManager manager = deploymentService.getRuntimeManager(deploymentUnit.getIdentifier());
    assertNotNull(manager);

    RuntimeEngine engine = manager.getRuntimeEngine(EmptyContext.get());
    assertNotNull(engine);

    Map<String, Object> params = new HashMap<String, Object>();
    params.put("id", "test");
    ProcessInstance processInstance = engine.getKieSession().startProcess("customtask", params);

    assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState());
    manager.disposeRuntimeEngine(engine);
  }
  public void commonDeploy(
      DeploymentUnit unit,
      DeployedUnitImpl deployedUnit,
      RuntimeEnvironment environemnt,
      KieContainer kieContainer) {

    synchronized (this) {
      if (deploymentsMap.containsKey(unit.getIdentifier())) {
        DeployedUnit deployed = deploymentsMap.remove(unit.getIdentifier());
        RuntimeManager manager = deployed.getRuntimeManager();
        manager.close();
      }
      RuntimeManager manager = null;
      deploymentsMap.put(unit.getIdentifier(), deployedUnit);
      ((SimpleRuntimeEnvironment) environemnt)
          .addToEnvironment("IdentityProvider", identityProvider);
      try {
        switch (unit.getStrategy()) {
          case SINGLETON:
            manager = managerFactory.newSingletonRuntimeManager(environemnt, unit.getIdentifier());
            break;
          case PER_REQUEST:
            manager = managerFactory.newPerRequestRuntimeManager(environemnt, unit.getIdentifier());
            break;

          case PER_PROCESS_INSTANCE:
            manager =
                managerFactory.newPerProcessInstanceRuntimeManager(
                    environemnt, unit.getIdentifier());
            break;
          default:
            throw new IllegalArgumentException("Invalid strategy " + unit.getStrategy());
        }
        ((InternalRuntimeManager) manager).setKieContainer(kieContainer);
        deployedUnit.setRuntimeManager(manager);
        DeploymentDescriptor descriptor =
            ((InternalRuntimeManager) manager).getDeploymentDescriptor();
        List<String> requiredRoles = descriptor.getRequiredRoles(DeploymentDescriptor.TYPE_EXECUTE);
        if (requiredRoles != null && !requiredRoles.isEmpty()) {
          ((InternalRuntimeManager) manager)
              .setSecurityManager(
                  new IdentityRolesSecurityManager(identityProvider, requiredRoles));
        }
        notifyOnDeploy(unit, deployedUnit);

      } catch (Throwable e) {
        deploymentsMap.remove(unit.getIdentifier());
        if (manager != null) {
          manager.close();
        }
        notifyOnUnDeploy(unit, deployedUnit);
        throw new RuntimeException(e);
      }
    }
  }
  @Override
  public void deactivate(String deploymentId) {
    DeployedUnit deployed = getDeployedUnit(deploymentId);
    if (deployed != null) {
      ((DeployedUnitImpl) deployed).setActive(false);

      ((InternalRuntimeManager) deployed.getRuntimeManager()).deactivate();

      notifyOnDeactivate(deployed.getDeploymentUnit(), deployed);
    }
  }
  @Test
  public void testDeploymentOfProcesses() {

    assertNotNull(deploymentService);

    KModuleDeploymentUnit deploymentUnit =
        new KModuleDeploymentUnit(GROUP_ID, ARTIFACT_ID, VERSION, "KBase-test", "ksession-test");

    deploymentService.deploy(deploymentUnit);
    units.add(deploymentUnit);

    assertNotNull(deploymentUnit.getDeploymentDescriptor());

    DeployedUnit deployed = deploymentService.getDeployedUnit(deploymentUnit.getIdentifier());
    assertNotNull(deployed);
    assertNotNull(deployed.getDeploymentUnit());
    assertNotNull(deployed.getRuntimeManager());
    assertNull(deployed.getDeployedAssetLocation("customtask"));
    assertEquals(
        GROUP_ID + ":" + ARTIFACT_ID + ":" + VERSION + ":" + "KBase-test" + ":" + "ksession-test",
        deployed.getDeploymentUnit().getIdentifier());

    assertNotNull(runtimeDataService);
    Collection<ProcessDefinition> processes = runtimeDataService.getProcesses(new QueryContext());
    assertNotNull(processes);
    assertEquals(3, processes.size());

    processes = runtimeDataService.getProcessesByFilter("custom", new QueryContext());
    assertNotNull(processes);
    assertEquals(1, processes.size());

    processes =
        runtimeDataService.getProcessesByDeploymentId(
            deploymentUnit.getIdentifier(), new QueryContext());
    assertNotNull(processes);
    assertEquals(3, processes.size());

    ProcessDefinition process = runtimeDataService.getProcessById("customtask");
    assertNotNull(process);

    RuntimeManager manager = deploymentService.getRuntimeManager(deploymentUnit.getIdentifier());
    assertNotNull(manager);

    RuntimeEngine engine = manager.getRuntimeEngine(EmptyContext.get());
    assertNotNull(engine);

    Map<String, Object> params = new HashMap<String, Object>();
    params.put("id", "test");
    ProcessInstance processInstance = engine.getKieSession().startProcess("customtask", params);

    assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState());
  }
  public void shutdown() {
    Collection<DeployedUnit> deployedUnits = getDeployedUnits();

    for (DeployedUnit deployed : deployedUnits) {
      try {
        deployed.getRuntimeManager().close();
      } catch (Exception e) {
        logger.warn(
            "Error encountered while shutting down deplyment {} due to {}",
            deployed.getDeploymentUnit().getIdentifier(),
            e.getMessage());
      }
    }
  }
  @Test(expected = RuntimeException.class)
  public void testDuplicatedDeployment() {

    assertNotNull(deploymentService);

    DeploymentUnit deploymentUnit = new KModuleDeploymentUnit(GROUP_ID, ARTIFACT_ID, VERSION);
    deploymentService.deploy(deploymentUnit);
    units.add(deploymentUnit);
    DeployedUnit deployedGeneral =
        deploymentService.getDeployedUnit(deploymentUnit.getIdentifier());
    assertNotNull(deployedGeneral);
    assertNotNull(deployedGeneral.getDeploymentUnit());
    assertNotNull(deployedGeneral.getRuntimeManager());
    // duplicated deployment of the same deployment unit should fail
    deploymentService.deploy(deploymentUnit);
  }
 @Override
 public void undeploy(DeploymentUnit unit) {
   List<Integer> states = new ArrayList<Integer>();
   states.add(ProcessInstance.STATE_ACTIVE);
   states.add(ProcessInstance.STATE_PENDING);
   states.add(ProcessInstance.STATE_SUSPENDED);
   Collection<ProcessInstanceDesc> activeProcesses =
       runtimeDataService.getProcessInstancesByDeploymentId(
           unit.getIdentifier(), states, new QueryContext());
   if (!activeProcesses.isEmpty()) {
     throw new IllegalStateException(
         "Undeploy forbidden - there are active processes instances for deployment "
             + unit.getIdentifier());
   }
   synchronized (this) {
     DeployedUnit deployed = deploymentsMap.remove(unit.getIdentifier());
     if (deployed != null) {
       RuntimeManager manager = deployed.getRuntimeManager();
       ((AbstractRuntimeManager) manager).close(true);
     }
     notifyOnUnDeploy(unit, deployed);
   }
 }
  @Test
  public void testUnDeploymentWithActiveProcesses() {

    assertNotNull(deploymentService);

    DeploymentUnit deploymentUnit = new KModuleDeploymentUnit(GROUP_ID, ARTIFACT_ID, VERSION);
    deploymentService.deploy(deploymentUnit);
    units.add(deploymentUnit);
    DeployedUnit deployedGeneral =
        deploymentService.getDeployedUnit(deploymentUnit.getIdentifier());
    assertNotNull(deployedGeneral);
    assertNotNull(deployedGeneral.getDeploymentUnit());
    assertNotNull(deployedGeneral.getRuntimeManager());

    RuntimeManager manager = deploymentService.getRuntimeManager(deploymentUnit.getIdentifier());
    assertNotNull(manager);

    RuntimeEngine engine = manager.getRuntimeEngine(EmptyContext.get());
    assertNotNull(engine);

    Map<String, Object> params = new HashMap<String, Object>();

    ProcessInstance processInstance =
        engine.getKieSession().startProcess("org.jbpm.writedocument", params);

    assertEquals(ProcessInstance.STATE_ACTIVE, processInstance.getState());
    try {
      // undeploy should fail due to active process instances
      deploymentService.undeploy(deploymentUnit);
      fail("Should fail due to active process instance");
    } catch (IllegalStateException e) {

    }

    engine.getKieSession().abortProcessInstance(processInstance.getId());
  }
  @Test
  public void testDeploymentOfProcessWithDescriptorKieConteinerInjection() {

    assertNotNull(deploymentService);

    KieServices ks = KieServices.Factory.get();
    ReleaseId releaseId = ks.newReleaseId(GROUP_ID, "kjar-with-dd", VERSION);
    List<String> processes = new ArrayList<String>();
    processes.add("repo/processes/general/customtask.bpmn");
    processes.add("repo/processes/general/humanTask.bpmn");
    processes.add("repo/processes/general/import.bpmn");

    DeploymentDescriptor customDescriptor = new DeploymentDescriptorImpl("org.jbpm.domain");
    customDescriptor
        .getBuilder()
        .runtimeStrategy(RuntimeStrategy.PER_REQUEST)
        .addWorkItemHandler(
            new NamedObjectModel(
                "mvel",
                "Log",
                "new org.jbpm.kie.services.test.objects.KieConteinerSystemOutWorkItemHandler(kieContainer)"));

    Map<String, String> resources = new HashMap<String, String>();
    resources.put(
        "src/main/resources/" + DeploymentDescriptor.META_INF_LOCATION, customDescriptor.toXml());

    InternalKieModule kJar1 = createKieJar(ks, releaseId, processes, resources);
    File pom = new File("target/kmodule", "pom.xml");
    pom.getParentFile().mkdir();
    try {
      FileOutputStream fs = new FileOutputStream(pom);
      fs.write(getPom(releaseId).getBytes());
      fs.close();
    } catch (Exception e) {

    }
    MavenRepository repository = getMavenRepository();
    repository.deployArtifact(releaseId, kJar1, pom);

    DeploymentUnit deploymentUnit =
        new KModuleDeploymentUnit(
            GROUP_ID, "kjar-with-dd", VERSION, "KBase-test", "ksession-test2");
    deploymentService.deploy(deploymentUnit);
    units.add(deploymentUnit);
    DeployedUnit deployedGeneral =
        deploymentService.getDeployedUnit(deploymentUnit.getIdentifier());
    assertNotNull(deployedGeneral);
    assertNotNull(deployedGeneral.getDeploymentUnit());
    assertNotNull(deployedGeneral.getRuntimeManager());

    DeploymentDescriptor descriptor =
        ((InternalRuntimeManager) deployedGeneral.getRuntimeManager()).getDeploymentDescriptor();
    assertNotNull(descriptor);
    assertEquals("org.jbpm.domain", descriptor.getPersistenceUnit());
    assertEquals("org.jbpm.domain", descriptor.getAuditPersistenceUnit());
    assertEquals(AuditMode.JPA, descriptor.getAuditMode());
    assertEquals(PersistenceMode.JPA, descriptor.getPersistenceMode());
    assertEquals(RuntimeStrategy.PER_REQUEST, descriptor.getRuntimeStrategy());
    assertEquals(0, descriptor.getMarshallingStrategies().size());
    assertEquals(0, descriptor.getConfiguration().size());
    assertEquals(0, descriptor.getEnvironmentEntries().size());
    assertEquals(0, descriptor.getEventListeners().size());
    assertEquals(0, descriptor.getGlobals().size());
    assertEquals(0, descriptor.getTaskEventListeners().size());
    assertEquals(1, descriptor.getWorkItemHandlers().size());
    assertEquals(0, descriptor.getRequiredRoles().size());

    RuntimeManager manager = deploymentService.getRuntimeManager(deploymentUnit.getIdentifier());
    assertNotNull(manager);

    RuntimeEngine engine = manager.getRuntimeEngine(EmptyContext.get());
    assertNotNull(engine);

    Map<String, Object> params = new HashMap<String, Object>();

    ProcessInstance processInstance = engine.getKieSession().startProcess("customtask", params);

    assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState());
    manager.disposeRuntimeEngine(engine);
  }
  /**
   * This creates and fills a {@link RuntimeEnvironmentBuilder} instance, which is later used when
   * creating services. A lot of the logic here is used to process the information in the {@link
   * DeploymentDescriptor} instance, which is part of the {@link DeploymentUnit}.
   *
   * @param deploymentUnit The {@link KModuleDeploymentUnit}, which is filled by the method
   * @param deployedUnit The {@link DeployedUnit}, which is also filled by the method
   * @param kieContainer The {@link KieContainer}, which contains information needed to fill the
   *     above two arguments
   * @param mode The {@link MergeMode} used to resolve conflicts in the {@link
   *     DeploymentDescriptor}.
   * @return A {@link RuntimeEnvironmentBuilder} instance ready for use
   */
  protected RuntimeEnvironmentBuilder boostrapRuntimeEnvironmentBuilder(
      KModuleDeploymentUnit deploymentUnit,
      DeployedUnit deployedUnit,
      KieContainer kieContainer,
      MergeMode mode) {
    DeploymentDescriptor descriptor = deploymentUnit.getDeploymentDescriptor();
    if (descriptor == null
        || ((DeploymentDescriptorImpl) descriptor)
            .isEmpty()) { // skip empty descriptors as its default can override settings
      DeploymentDescriptorManager descriptorManager =
          new DeploymentDescriptorManager("org.jbpm.domain");
      List<DeploymentDescriptor> descriptorHierarchy =
          descriptorManager.getDeploymentDescriptorHierarchy(kieContainer);

      descriptor = merger.merge(descriptorHierarchy, mode);
      deploymentUnit.setDeploymentDescriptor(descriptor);
    } else if (descriptor != null && !deploymentUnit.isDeployed()) {
      DeploymentDescriptorManager descriptorManager =
          new DeploymentDescriptorManager("org.jbpm.domain");
      List<DeploymentDescriptor> descriptorHierarchy =
          descriptorManager.getDeploymentDescriptorHierarchy(kieContainer);

      descriptorHierarchy.add(0, descriptor);
      descriptor = merger.merge(descriptorHierarchy, mode);
      deploymentUnit.setDeploymentDescriptor(descriptor);
    }

    // first set on unit the strategy
    deploymentUnit.setStrategy(descriptor.getRuntimeStrategy());

    // setting up runtime environment via builder
    RuntimeEnvironmentBuilder builder = null;
    if (descriptor.getPersistenceMode() == PersistenceMode.NONE) {
      builder = RuntimeEnvironmentBuilder.Factory.get().newDefaultInMemoryBuilder();
    } else {
      builder = RuntimeEnvironmentBuilder.Factory.get().newDefaultBuilder();
    }
    // populate various properties of the builder
    EntityManagerFactory emf =
        EntityManagerFactoryManager.get().getOrCreate(descriptor.getPersistenceUnit());
    builder.entityManagerFactory(emf);

    Map<String, Object> contaxtParams = new HashMap<String, Object>();
    contaxtParams.put("entityManagerFactory", emf);
    contaxtParams.put("classLoader", kieContainer.getClassLoader());
    // process object models that are globally configured (environment entries, session
    // configuration)
    for (NamedObjectModel model : descriptor.getEnvironmentEntries()) {
      Object entry = getInstanceFromModel(model, kieContainer, contaxtParams);
      builder.addEnvironmentEntry(model.getName(), entry);
    }

    for (NamedObjectModel model : descriptor.getConfiguration()) {
      Object entry = getInstanceFromModel(model, kieContainer, contaxtParams);
      builder.addConfiguration(model.getName(), (String) entry);
    }
    ObjectMarshallingStrategy[] mStrategies =
        new ObjectMarshallingStrategy[descriptor.getMarshallingStrategies().size() + 1];
    int index = 0;
    for (ObjectModel model : descriptor.getMarshallingStrategies()) {
      Object strategy = getInstanceFromModel(model, kieContainer, contaxtParams);
      mStrategies[index] = (ObjectMarshallingStrategy) strategy;
      index++;
    }
    // lastly add the main default strategy
    mStrategies[index] =
        new SerializablePlaceholderResolverStrategy(ClassObjectMarshallingStrategyAcceptor.DEFAULT);
    builder.addEnvironmentEntry(EnvironmentName.OBJECT_MARSHALLING_STRATEGIES, mStrategies);

    builder.addEnvironmentEntry("KieDeploymentDescriptor", descriptor);
    builder.addEnvironmentEntry("KieContainer", kieContainer);
    if (executorService != null) {
      builder.addEnvironmentEntry("ExecutorService", executorService);
    }
    // populate all assets with roles for this deployment unit
    List<String> requiredRoles = descriptor.getRequiredRoles(DeploymentDescriptor.TYPE_VIEW);
    if (requiredRoles != null && !requiredRoles.isEmpty()) {
      for (DeployedAsset desc : deployedUnit.getDeployedAssets()) {
        if (desc instanceof ProcessAssetDesc) {
          ((ProcessAssetDesc) desc).setRoles(requiredRoles);
        }
      }
    }

    // Classes 3: classes added from descriptor
    List<String> remoteableClasses = descriptor.getClasses();
    if (remoteableClasses != null && !remoteableClasses.isEmpty()) {
      for (String className : remoteableClasses) {
        Class descriptorClass = null;
        try {
          descriptorClass = kieContainer.getClassLoader().loadClass(className);
          logger.debug(
              "Loaded {} into the classpath from deployment descriptor {}",
              className,
              kieContainer.getReleaseId().toExternalForm());
        } catch (ClassNotFoundException cnfe) {
          throw new IllegalArgumentException("Class " + className + " not found in the project");
        } catch (NoClassDefFoundError e) {
          throw new IllegalArgumentException("Class " + className + " not found in the project");
        }
        addClassToDeployedUnit(descriptorClass, (DeployedUnitImpl) deployedUnit);
      }
    }

    return builder;
  }