/* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * 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.kie.server.integrationtests.jbpm.admin; import java.util.HashMap; import java.util.List; import java.util.Map; import org.junit.BeforeClass; import org.junit.Test; import org.kie.api.KieServices; import org.kie.server.api.model.ReleaseId; import org.kie.server.api.model.admin.ExecutionErrorInstance; import org.kie.server.api.model.admin.ProcessNode; import org.kie.server.api.model.admin.TimerInstance; import org.kie.server.api.model.instance.NodeInstance; import org.kie.server.api.model.instance.ProcessInstance; import org.kie.server.api.exception.KieServicesException; import org.kie.server.integrationtests.jbpm.JbpmKieServerBaseIntegrationTest; import org.kie.server.integrationtests.shared.KieServerDeployer; import org.kie.server.integrationtests.shared.KieServerSynchronization; import static org.junit.Assert.*; public class ProcessInstanceAdminServiceIntegrationTest extends JbpmKieServerBaseIntegrationTest { private static ReleaseId releaseId = new ReleaseId("org.kie.server.testing", "definition-project", "1.0.0.Final"); @BeforeClass public static void buildAndDeployArtifacts() { KieServerDeployer.buildAndDeployCommonMavenParent(); KieServerDeployer.buildAndDeployMavenProject(ClassLoader.class.getResource("/kjars-sources/definition-project").getFile()); kieContainer = KieServices.Factory.get().newKieContainer(releaseId); createContainer(CONTAINER_ID, releaseId); } @Override protected void addExtraCustomClasses(Map<String, Class<?>> extraClasses) throws Exception { extraClasses.put(PERSON_CLASS_NAME, Class.forName(PERSON_CLASS_NAME, true, kieContainer.getClassLoader())); } @Test public void testCancelAndTrigger() throws Exception { Map<String, Object> parameters = new HashMap<String, Object>(); Long processInstanceId = null; try { processInstanceId = processClient.startProcess(CONTAINER_ID, PROCESS_ID_EVALUATION, parameters); assertNotNull(processInstanceId); assertTrue(processInstanceId.longValue() > 0); List<NodeInstance> activeNodeInstances = processAdminClient.getActiveNodeInstances(CONTAINER_ID, processInstanceId); assertNotNull(activeNodeInstances); assertEquals(1, activeNodeInstances.size()); NodeInstance active = activeNodeInstances.get(0); assertEquals("Evaluate items?", active.getName()); processAdminClient.cancelNodeInstance(CONTAINER_ID, processInstanceId, active.getId()); activeNodeInstances = processAdminClient.getActiveNodeInstances(CONTAINER_ID, processInstanceId); assertNotNull(activeNodeInstances); assertEquals(0, activeNodeInstances.size()); List<ProcessNode> processNodes = processAdminClient.getProcessNodes(CONTAINER_ID, processInstanceId); ProcessNode first = processNodes.stream().filter(pn -> pn.getNodeName().equals("Evaluate items?")).findFirst().orElse(null); assertNotNull(first); processAdminClient.triggerNode(CONTAINER_ID, processInstanceId, first.getNodeId()); activeNodeInstances = processAdminClient.getActiveNodeInstances(CONTAINER_ID, processInstanceId); assertNotNull(activeNodeInstances); assertEquals(1, activeNodeInstances.size()); NodeInstance activeTriggered = activeNodeInstances.get(0); assertEquals("Evaluate items?", activeTriggered.getName()); assertFalse(activeTriggered.getId().longValue() == active.getId().longValue()); } finally { if (processInstanceId != null) { processClient.abortProcessInstance(CONTAINER_ID, processInstanceId); } } } @Test public void testRetrigger() throws Exception { Map<String, Object> parameters = new HashMap<String, Object>(); Long processInstanceId = null; try { processInstanceId = processClient.startProcess(CONTAINER_ID, PROCESS_ID_EVALUATION, parameters); assertNotNull(processInstanceId); assertTrue(processInstanceId.longValue() > 0); List<NodeInstance> activeNodeInstances = processAdminClient.getActiveNodeInstances(CONTAINER_ID, processInstanceId); assertNotNull(activeNodeInstances); assertEquals(1, activeNodeInstances.size()); NodeInstance active = activeNodeInstances.get(0); assertEquals("Evaluate items?", active.getName()); processAdminClient.retriggerNodeInstance(CONTAINER_ID, processInstanceId, active.getId()); activeNodeInstances = processAdminClient.getActiveNodeInstances(CONTAINER_ID, processInstanceId); assertNotNull(activeNodeInstances); assertEquals(1, activeNodeInstances.size()); NodeInstance activeTriggered = activeNodeInstances.get(0); assertEquals("Evaluate items?", activeTriggered.getName()); assertFalse(activeTriggered.getId().longValue() == active.getId().longValue()); } finally { if (processInstanceId != null) { processClient.abortProcessInstance(CONTAINER_ID, processInstanceId); } } } @Test(timeout = 60 * 1000) public void testUpdateTimer() throws Exception { Map<String, Object> parameters = new HashMap<>(); parameters.put("timer", "1h"); Long processInstanceId = processClient.startProcess(CONTAINER_ID, PROCESS_ID_TIMER, parameters); assertNotNull(processInstanceId); assertTrue(processInstanceId.longValue() > 0); try { List<TimerInstance> timers = processAdminClient.getTimerInstances(CONTAINER_ID, processInstanceId); assertNotNull(timers); assertEquals(1, timers.size()); TimerInstance timerInstance = timers.get(0); assertNotNull(timerInstance); assertEquals("timer", timerInstance.getTimerName()); processAdminClient.updateTimer(CONTAINER_ID, processInstanceId, timerInstance.getTimerId(), 3, 0, 0); KieServerSynchronization.waitForProcessInstanceToFinish(processClient, CONTAINER_ID, processInstanceId); ProcessInstance pi = processClient.getProcessInstance(CONTAINER_ID, processInstanceId); assertNotNull(pi); assertEquals(org.kie.api.runtime.process.ProcessInstance.STATE_COMPLETED, pi.getState().intValue()); } catch (Exception e){ processClient.abortProcessInstance(CONTAINER_ID, processInstanceId); fail(e.getMessage()); } } @Test(timeout = 60 * 1000) public void testUpdateTimerRelative() throws Exception { Map<String, Object> parameters = new HashMap<>(); parameters.put("timer", "1h"); Long processInstanceId = processClient.startProcess(CONTAINER_ID, PROCESS_ID_TIMER, parameters); assertNotNull(processInstanceId); assertTrue(processInstanceId.longValue() > 0); try { List<TimerInstance> timers = processAdminClient.getTimerInstances(CONTAINER_ID, processInstanceId); assertNotNull(timers); assertEquals(1, timers.size()); TimerInstance timerInstance = timers.get(0); assertNotNull(timerInstance); assertEquals("timer", timerInstance.getTimerName()); processAdminClient.updateTimerRelative(CONTAINER_ID, processInstanceId, timerInstance.getTimerId(), 3, 0, 0); KieServerSynchronization.waitForProcessInstanceToFinish(processClient, CONTAINER_ID, processInstanceId); ProcessInstance pi = processClient.getProcessInstance(CONTAINER_ID, processInstanceId); assertNotNull(pi); assertEquals(org.kie.api.runtime.process.ProcessInstance.STATE_COMPLETED, pi.getState().intValue()); } catch (Exception e){ processClient.abortProcessInstance(CONTAINER_ID, processInstanceId); fail(e.getMessage()); } } @Test public void testErrorHandlingFailedToStart() throws Exception { Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put("timer", "invalid value"); try { processClient.startProcess(CONTAINER_ID, PROCESS_ID_TIMER, parameters); fail("Process instance should fail as it has invalid timer expression"); } catch (KieServicesException e) { // expected as the variable to configure timer duration is invalid } List<ExecutionErrorInstance> errors = processAdminClient.getErrors(CONTAINER_ID, false, 0, 10); assertNotNull(errors); assertEquals(1, errors.size()); ExecutionErrorInstance errorInstance = errors.get(0); assertNotNull(errorInstance.getErrorId()); assertNull(errorInstance.getError()); assertNotNull(errorInstance.getProcessInstanceId()); assertNotNull(errorInstance.getActivityId()); assertNotNull(errorInstance.getErrorDate()); assertEquals(CONTAINER_ID, errorInstance.getContainerId()); assertEquals(PROCESS_ID_TIMER, errorInstance.getProcessId()); assertEquals("timer", errorInstance.getActivityName()); assertFalse(errorInstance.isAcknowledged()); assertNull(errorInstance.getAcknowledgedAt()); assertNull(errorInstance.getAcknowledgedBy()); processAdminClient.acknowledgeError(CONTAINER_ID, errorInstance.getErrorId()); errors = processAdminClient.getErrors(CONTAINER_ID, false, 0, 10); assertNotNull(errors); assertEquals(0, errors.size()); errorInstance = processAdminClient.getError(CONTAINER_ID, errorInstance.getErrorId()); assertNotNull(errorInstance); assertNotNull(errorInstance.getErrorId()); assertTrue(errorInstance.isAcknowledged()); assertNotNull(errorInstance.getAcknowledgedAt()); assertEquals(USER_YODA, errorInstance.getAcknowledgedBy()); } @Test public void testErrorHandlingFailedToSignal() throws Exception { Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put("nullAccepted", false); Long processInstanceId = null; try { processInstanceId = processClient.startProcess(CONTAINER_ID, PROCESS_ID_SIGNAL_PROCESS, parameters); List<ExecutionErrorInstance> errors = processAdminClient.getErrors(CONTAINER_ID, false, 0, 10); assertNotNull(errors); assertEquals(0, errors.size()); try { processClient.signalProcessInstance(CONTAINER_ID, processInstanceId, "Signal1", null); fail("Process instance signal fail as it provides null as event"); } catch (KieServicesException e) { // expected } errors = processAdminClient.getErrorsByProcessInstance(CONTAINER_ID, processInstanceId, false, 0, 10); assertNotNull(errors); assertEquals(1, errors.size()); ExecutionErrorInstance errorInstance = errors.get(0); assertNotNull(errorInstance.getErrorId()); assertNull(errorInstance.getError()); assertNotNull(errorInstance.getProcessInstanceId()); assertNotNull(errorInstance.getActivityId()); assertNotNull(errorInstance.getErrorDate()); assertEquals(CONTAINER_ID, errorInstance.getContainerId()); assertEquals(PROCESS_ID_SIGNAL_PROCESS, errorInstance.getProcessId()); assertEquals("Signal 1 data", errorInstance.getActivityName()); assertFalse(errorInstance.isAcknowledged()); assertNull(errorInstance.getAcknowledgedAt()); assertNull(errorInstance.getAcknowledgedBy()); errors = processAdminClient.getErrorsByProcessInstanceAndNode(CONTAINER_ID, processInstanceId, "Signal 1 data", false, 0, 10); assertNotNull(errors); assertEquals(1, errors.size()); ExecutionErrorInstance errorInstance2 = errors.get(0); assertEquals(errorInstance.getErrorId(), errorInstance2.getErrorId()); processAdminClient.acknowledgeError(CONTAINER_ID, errorInstance.getErrorId()); errors = processAdminClient.getErrors(CONTAINER_ID, false, 0, 10); assertNotNull(errors); assertEquals(0, errors.size()); errorInstance = processAdminClient.getError(CONTAINER_ID, errorInstance.getErrorId()); assertNotNull(errorInstance); assertNotNull(errorInstance.getErrorId()); assertTrue(errorInstance.isAcknowledged()); assertNotNull(errorInstance.getAcknowledgedAt()); assertEquals(USER_YODA, errorInstance.getAcknowledgedBy()); } catch (KieServicesException e) { logger.error("Unexpected error", e); fail(e.getMessage()); } finally { if (processInstanceId != null) { processClient.abortProcessInstance(CONTAINER_ID, processInstanceId); } } } @Test public void testErrorHandlingFailedToStartBulkAck() throws Exception { Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put("timer", "invalid value"); try { processClient.startProcess(CONTAINER_ID, PROCESS_ID_TIMER, parameters); fail("Process instance should fail as it has invalid timer expression"); } catch (KieServicesException e) { // expected as the variable to configure timer duration is invalid } try { processClient.startProcess(CONTAINER_ID, PROCESS_ID_TIMER, parameters); fail("Process instance should fail as it has invalid timer expression"); } catch (KieServicesException e) { // expected as the variable to configure timer duration is invalid } List<ExecutionErrorInstance> errors = processAdminClient.getErrors(CONTAINER_ID, false, 0, 10); assertNotNull(errors); assertEquals(2, errors.size()); ExecutionErrorInstance errorInstance = errors.get(0); assertFalse(errorInstance.isAcknowledged()); assertNull(errorInstance.getAcknowledgedAt()); assertNull(errorInstance.getAcknowledgedBy()); ExecutionErrorInstance errorInstance2 = errors.get(1); assertFalse(errorInstance2.isAcknowledged()); assertNull(errorInstance2.getAcknowledgedAt()); assertNull(errorInstance2.getAcknowledgedBy()); processAdminClient.acknowledgeError(CONTAINER_ID, errorInstance.getErrorId(), errorInstance2.getErrorId()); errors = processAdminClient.getErrors(CONTAINER_ID, false, 0, 10); assertNotNull(errors); assertEquals(0, errors.size()); errorInstance = processAdminClient.getError(CONTAINER_ID, errorInstance.getErrorId()); assertNotNull(errorInstance); assertNotNull(errorInstance.getErrorId()); assertTrue(errorInstance.isAcknowledged()); assertNotNull(errorInstance.getAcknowledgedAt()); assertEquals(USER_YODA, errorInstance.getAcknowledgedBy()); } }