/* * 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. * 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.jbpm.test.functional.log; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import org.assertj.core.api.Assertions; import org.jbpm.process.audit.JPAAuditLogService; import org.jbpm.test.JbpmTestCase; import org.junit.Test; import org.kie.api.runtime.KieSession; import org.kie.api.runtime.manager.audit.ProcessInstanceLog; import org.kie.api.runtime.process.ProcessInstance; import org.kie.internal.runtime.manager.audit.query.ProcessInstanceLogDeleteBuilder; import org.kie.internal.runtime.manager.audit.query.ProcessInstanceLogQueryBuilder; import qa.tools.ikeeper.annotation.BZ; /** * TODO: * - try end dates. * - try initiator */ public class ProcessInstanceLogCleanTest extends JbpmTestCase { private static final String HELLO_WORLD_PROCESS = "org/jbpm/test/functional/common/HelloWorldProcess1.bpmn"; private static final String HELLO_WORLD_PROCESS_ID = "org.jbpm.test.functional.common.HelloWorldProcess1"; private static final String HELLO_WORLD_PROCESS2 = "org/jbpm/test/functional/common/HelloWorldProcess2.bpmn"; private static final String HELLO_WORLD_PROCESS2_ID = "org.jbpm.test.functional.common.HelloWorldProcess2"; private static final String PARENT_PROCESS_INFO = "org/jbpm/test/functional/common/ParentProcessInfo.bpmn2"; private static final String PARENT_PROCESS_INFO_ID = "org.jbpm.test.functional.common.ParentProcessInfo"; private static final String PARENT_PROCESS_CALLER = "org/jbpm/test/functional/common/ParentProcessInfo-Caller.bpmn2"; private static final String PARENT_PROCESS_CALLER_ID = "org.jbpm.test.functional.common.ParentProcessInfo-Caller"; private static final String HUMAN_TASK = "org/jbpm/test/functional/common/HumanTask.bpmn2"; private static final String HUMAN_TASK_ID = "org.jbpm.test.functional.common.HumanTask"; private static final String HELLO_WORLD_P1NAME = "HelloWorldProcess1"; private static final String HELLO_WORLD_P2NAME = "HelloWorldProcess2"; private JPAAuditLogService auditService; @Override public void setUp() throws Exception { super.setUp(); auditService = new JPAAuditLogService(getEmf()); auditService.clear(); } @Override public void tearDown() throws Exception { try { auditService.clear(); auditService.dispose(); } finally { super.tearDown(); } } @Test public void deleteLogsByProcessName() { KieSession kieSession = createKSession(HELLO_WORLD_PROCESS); startProcess(kieSession, HELLO_WORLD_PROCESS_ID, 2); // Check that all records are created. List<ProcessInstanceLog> resultList = auditService.processInstanceLogQuery() .processId(HELLO_WORLD_PROCESS_ID) .processVersion("1.0") .build() .getResultList(); Assertions.assertThat(resultList).hasSize(2); Assertions.assertThat(resultList) .extracting("processName") .containsExactly(HELLO_WORLD_P1NAME, HELLO_WORLD_P1NAME); // Perform delete int resultCount = auditService.processInstanceLogDelete() .processName(HELLO_WORLD_P1NAME) .build() .execute(); Assertions.assertThat(resultCount).isEqualTo(2); // Check that all records are gone resultList = auditService.processInstanceLogQuery() .processId(HELLO_WORLD_PROCESS_ID) .processVersion("1.0") .build() .getResultList(); Assertions.assertThat(resultList).hasSize(0); } @Test public void deleteLogsByProcessId() { KieSession kieSession = createKSession(HELLO_WORLD_PROCESS); startProcess(kieSession, HELLO_WORLD_PROCESS_ID, 3); // Check that all records are created. List<ProcessInstanceLog> resultList = auditService.processInstanceLogQuery() .processName(HELLO_WORLD_P1NAME) .processVersion("1.0") .build() .getResultList(); Assertions.assertThat(resultList).hasSize(3); Assertions.assertThat(resultList) .extracting("processId") .containsExactly(HELLO_WORLD_PROCESS_ID, HELLO_WORLD_PROCESS_ID, HELLO_WORLD_PROCESS_ID); // Perform delete int resultCount = auditService.processInstanceLogDelete() .processId(HELLO_WORLD_PROCESS_ID) .build() .execute(); Assertions.assertThat(resultCount).isEqualTo(3); // Check that all records are gone resultList = auditService.processInstanceLogQuery() .processName(HELLO_WORLD_P1NAME) .processVersion("1.0") .build() .getResultList(); Assertions.assertThat(resultList).hasSize(0); } @Test public void deleteLogsByVersion() { KieSession kieSession = createKSession(HELLO_WORLD_PROCESS); startProcess(kieSession, HELLO_WORLD_PROCESS_ID, 7); disposeRuntimeManager(); kieSession = createKSession(HELLO_WORLD_PROCESS2); startProcess(kieSession, HELLO_WORLD_PROCESS2_ID, 2); // Delete all logs of version 1.1 ProcessInstanceLogDeleteBuilder deleteBuilder = auditService .processInstanceLogDelete() .processVersion("1.0"); int deleteResult = deleteBuilder.build().execute(); Assertions.assertThat(deleteResult).isEqualTo(7); // Make sure that the 1.1 version logs are gone List<ProcessInstanceLog> resultList = auditService .processInstanceLogQuery() .processVersion("1.0") .build() .getResultList(); Assertions.assertThat(resultList).hasSize(0); // Now check that 1.0 version logs are present resultList = auditService .processInstanceLogQuery() .processVersion("1.1") .build() .getResultList(); Assertions.assertThat(resultList).hasSize(2); Assertions.assertThat(resultList).extracting("processVersion").containsExactly("1.1", "1.1"); } @Test public void deleteLogsWithStatusActive() { KieSession kieSession = null; List<ProcessInstance> instanceList1 = null; List<ProcessInstance> instanceList2 = null; try { kieSession = createKSession(HELLO_WORLD_PROCESS, HUMAN_TASK); instanceList1 = startProcess(kieSession, HELLO_WORLD_PROCESS_ID, 3); instanceList2 = startProcess(kieSession, HUMAN_TASK_ID, 5); ProcessInstanceLogDeleteBuilder deleteBuilder = auditService.processInstanceLogDelete().status(ProcessInstance.STATE_ACTIVE); int deleteResult = deleteBuilder.build().execute(); Assertions.assertThat(deleteResult).isEqualTo(5); ProcessInstanceLogQueryBuilder queryBuilder = auditService.processInstanceLogQuery().status(ProcessInstance.STATE_COMPLETED); List<ProcessInstanceLog> queryList = queryBuilder.build().getResultList(); Assertions.assertThat(queryList).hasSize(3); Assertions.assertThat(queryList).extracting("processId").containsExactly(HELLO_WORLD_PROCESS_ID, HELLO_WORLD_PROCESS_ID, HELLO_WORLD_PROCESS_ID); Assertions.assertThat(queryList).extracting("processVersion").containsExactly("1.0", "1.0", "1.0"); Assertions.assertThat(queryList).extracting("status").containsExactly(ProcessInstance.STATE_COMPLETED, ProcessInstance.STATE_COMPLETED, ProcessInstance.STATE_COMPLETED); } finally { if (instanceList2 != null) { abortProcess(kieSession, instanceList2); } if (kieSession != null) { kieSession.dispose(); } } } @Test @BZ("1188702") public void deleteLogsByDate() { Date testStartDate = new Date(); KieSession kieSession = createKSession(HELLO_WORLD_PROCESS); startProcess(kieSession, HELLO_WORLD_PROCESS_ID, 4); List<ProcessInstanceLog> resultList = auditService.processInstanceLogQuery() .startDateRangeStart(testStartDate) .build() .getResultList(); Assertions.assertThat(resultList) .hasSize(4) .extracting("processId") .containsExactly(HELLO_WORLD_PROCESS_ID, HELLO_WORLD_PROCESS_ID, HELLO_WORLD_PROCESS_ID, HELLO_WORLD_PROCESS_ID); // Delete the last 3 logs in the list for (int i = resultList.size() - 1; i > 0; i--) { int resultCount = auditService.processInstanceLogDelete() .startDate(resultList.get(i).getStart()) .build() .execute(); Assertions.assertThat(resultCount).isEqualTo(1); } // Attempt to delete with a date later than end of all the instances int resultCount = auditService.processInstanceLogDelete() .startDate(new Date()) .build() .execute(); Assertions.assertThat(resultCount).isEqualTo(0); // Check the last instance List<ProcessInstanceLog> resultList2 = auditService.processInstanceLogQuery() .startDateRangeStart(testStartDate) .build() .getResultList(); Assertions.assertThat(resultList2).hasSize(1); Assertions.assertThat(resultList2.get(0)).isEqualTo(resultList.get(0)); } @Test @BZ("1192498") public void deleteLogsByDateRange() throws InterruptedException { KieSession kieSession = createKSession(PARENT_PROCESS_CALLER, PARENT_PROCESS_INFO, HELLO_WORLD_PROCESS); Date date1 = new Date(); startProcess(kieSession, PARENT_PROCESS_CALLER_ID, 4); Date date2 = new Date(); Thread.sleep(1000); startProcess(kieSession, HELLO_WORLD_PROCESS_ID, 2); Date date3 = new Date(); int beforeSize = getProcessInstanceLogSize(getYesterday(), getTomorrow()); Assertions.assertThat(beforeSize).isEqualTo(10); int resultCount = auditService.processInstanceLogDelete() .startDateRangeStart(date1) .startDateRangeEnd(date2) .build() .execute(); // 1 for ReussableSubprocess and 1 for ParentProcessInfo called by it Assertions.assertThat(resultCount).isEqualTo(8); List<ProcessInstanceLog> resultList = auditService.processInstanceLogQuery() .startDateRangeEnd(date3) .build() .getResultList(); Assertions.assertThat(resultList) .hasSize(2) .extracting("processId").containsExactly(HELLO_WORLD_PROCESS_ID, HELLO_WORLD_PROCESS_ID); int afterSize = getProcessInstanceLogSize(date1, date3); Assertions.assertThat(afterSize).isEqualTo(2); } @Test @BZ("1192498") public void deleteLogsByDateRangeEndingYesterday() { deleteLogsByDateRange(getYesterday(), getYesterday(), false); } @Test @BZ("1192498") public void deleteLogsByDateRangeIncludingToday() { deleteLogsByDateRange(getYesterday(), getTomorrow(), true); } @Test @BZ("1192498") public void deleteLogsByDateRangeStartingTomorrow() { deleteLogsByDateRange(getTomorrow(), getTomorrow(), false); } private void deleteLogsByDateRange(Date startDate, Date endDate, boolean expectRemoval) { KieSession kieSession = createKSession(HELLO_WORLD_PROCESS); startProcess(kieSession, HELLO_WORLD_PROCESS_ID, 2); int beforeSize = getProcessInstanceLogSize(getYesterday(), getTomorrow()); Assertions.assertThat(beforeSize).isEqualTo(2); int resultCount = auditService.processInstanceLogDelete() .startDateRangeStart(startDate) .startDateRangeEnd(endDate) .build() .execute(); // 1 for ReussableSubprocess and 1 for ParentProcessInfo called by it Assertions.assertThat(resultCount).isEqualTo(expectRemoval ? 2 : 0); int afterSize = getProcessInstanceLogSize(getYesterday(), getTomorrow()); Assertions.assertThat(afterSize).isEqualTo(expectRemoval ? 0 : 2); } private int getProcessInstanceLogSize(Date startDateRangeStart, Date startDateRangeEnd) { return auditService.processInstanceLogQuery() .startDateRangeStart(startDateRangeStart) .startDateRangeEnd(startDateRangeEnd) .build() .getResultList() .size(); } private Date getTomorrow() { Calendar c = Calendar.getInstance(); c.setTime(new Date()); c.add(Calendar.DATE, 1); return c.getTime(); } private Date getYesterday() { Calendar c = Calendar.getInstance(); c.setTime(new Date()); c.add(Calendar.DATE, -1); return c.getTime(); } private void abortProcess(KieSession kieSession, List<ProcessInstance> processInstanceList) { for (ProcessInstance processInstance : processInstanceList) { abortProcess(kieSession, processInstance.getId()); } } private void abortProcess(KieSession kieSession, long pid) { ProcessInstance processInstance = kieSession.getProcessInstance(pid); if (processInstance != null && processInstance.getState() == ProcessInstance.STATE_ACTIVE) { kieSession.abortProcessInstance(pid); } } private List<ProcessInstance> startProcess(KieSession kieSession, String processId, int count) { List<ProcessInstance> piList = new ArrayList<ProcessInstance>(); for (int i = 0; i < count; i++) { ProcessInstance pi = kieSession.startProcess(processId); if (pi != null) { piList.add(pi); } } return piList; } }