/* * 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.jbpm.test.functional.jpa; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.naming.InitialContext; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.transaction.UserTransaction; import org.drools.core.marshalling.impl.ClassObjectMarshallingStrategyAcceptor; import org.drools.core.marshalling.impl.SerializablePlaceholderResolverStrategy; import org.drools.persistence.jpa.marshaller.JPAPlaceholderResolverStrategy; import org.jbpm.marshalling.impl.ProcessInstanceResolverStrategy; import org.jbpm.services.task.utils.ContentMarshallerHelper; import org.jbpm.test.JbpmTestCase; import org.jbpm.test.entity.MedicalRecord; import org.jbpm.test.entity.Patient; import org.jbpm.test.entity.RecordRow; import org.junit.Assert; import org.junit.Test; import org.kie.api.marshalling.ObjectMarshallingStrategy; import org.kie.api.runtime.EnvironmentName; import org.kie.api.runtime.KieSession; import org.kie.api.runtime.manager.RuntimeEngine; import org.kie.api.runtime.manager.audit.VariableInstanceLog; import org.kie.api.runtime.process.ProcessInstance; import org.kie.api.task.TaskService; import org.kie.api.task.model.Content; import org.kie.api.task.model.Task; import org.kie.api.task.model.TaskSummary; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PatientVariablePersistenceStrategyTest extends JbpmTestCase { private static final Logger logger = LoggerFactory.getLogger(PatientVariablePersistenceStrategyTest.class); private EntityManagerFactory emfDomain; public PatientVariablePersistenceStrategyTest() { super(true, true); } @Test public void simplePatientMedicalRecordTest() throws Exception { Patient salaboy = new Patient("salaboy"); MedicalRecord medicalRecord = new MedicalRecord("Last Three Years Medical Hisotry", salaboy); emfDomain = Persistence.createEntityManagerFactory("org.jbpm.persistence.patient.example"); addEnvironmentEntry(EnvironmentName.OBJECT_MARSHALLING_STRATEGIES, new ObjectMarshallingStrategy[] { new ProcessInstanceResolverStrategy(), new JPAPlaceholderResolverStrategy(emfDomain), new SerializablePlaceholderResolverStrategy(ClassObjectMarshallingStrategyAcceptor.DEFAULT) }); EntityManager em = emfDomain.createEntityManager(); createRuntimeManager("org/jbpm/test/functional/jpa/patient-appointment.bpmn"); RuntimeEngine runtimeEngine = getRuntimeEngine(); KieSession ksession = runtimeEngine.getKieSession(); TaskService taskService = runtimeEngine.getTaskService(); logger.info("### Starting process ###"); Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put("medicalRecord", medicalRecord); ProcessInstance process = ksession.startProcess("org.jbpm.PatientAppointment", parameters); long processInstanceId = process.getId(); //The process is in the first Human Task waiting for its completion Assert.assertEquals(ProcessInstance.STATE_ACTIVE, process.getState()); List<? extends VariableInstanceLog> varLogs = runtimeEngine.getAuditService().findVariableInstances(processInstanceId, "medicalRecord"); assertNotNull(varLogs); assertEquals(1, varLogs.size()); //gets frontDesk's tasks List<TaskSummary> frontDeskTasks = taskService.getTasksAssignedAsPotentialOwner("frontDesk", "en-UK"); Assert.assertEquals(1, frontDeskTasks.size()); //doctor doesn't have any task List<TaskSummary> doctorTasks = taskService.getTasksAssignedAsPotentialOwner("doctor", "en-UK"); Assert.assertTrue(doctorTasks.isEmpty()); //manager doesn't have any task List<TaskSummary> managerTasks = taskService.getTasksAssignedAsPotentialOwner("manager", "en-UK"); Assert.assertTrue(managerTasks.isEmpty()); taskService.start(frontDeskTasks.get(0).getId(), "frontDesk"); //frontDesk completes its task MedicalRecord taskMedicalRecord = getTaskContent(runtimeEngine, frontDeskTasks.get(0)); Assert.assertNotNull(taskMedicalRecord.getId()); taskMedicalRecord.setDescription("Initial Description of the Medical Record"); Map<String, Object> output = new HashMap<String, Object>(); output.put("output1", taskMedicalRecord); taskService.complete(frontDeskTasks.get(0).getId(), "frontDesk", output); varLogs = runtimeEngine.getAuditService().findVariableInstances(processInstanceId, "medicalRecord"); assertNotNull(varLogs); assertEquals(2, varLogs.size()); assertTrue(varLogs.get(0).getValue().contains("Last Three Years Medical Hisotry")); assertTrue(varLogs.get(1).getValue().contains("Initial Description of the Medical Record")); //Now doctor has 1 task doctorTasks = taskService.getTasksAssignedAsPotentialOwner("doctor", "en-UK"); Assert.assertEquals(1, doctorTasks.size()); //No tasks for manager yet managerTasks = taskService.getTasksAssignedAsPotentialOwner("manager", "en-UK"); Assert.assertTrue(managerTasks.isEmpty()); // modify the entity from outside taskMedicalRecord.setDescription("Initial Description of the Medical Record - Updated"); UserTransaction ut = InitialContext.doLookup("java:comp/UserTransaction"); try { ut.begin(); em.merge(taskMedicalRecord); ut.commit(); } catch (Exception ex) { ut.rollback(); throw ex; } taskMedicalRecord = getTaskContent(runtimeEngine, doctorTasks.get(0)); Assert.assertNotNull(taskMedicalRecord.getId()); taskMedicalRecord.setDescription("Initial Description of the Medical Record - Updated"); taskService.start(doctorTasks.get(0).getId(), "doctor"); //Check that we have the Modified Document taskMedicalRecord = em.find(MedicalRecord.class, taskMedicalRecord.getId()); Assert.assertEquals("Initial Description of the Medical Record - Updated", taskMedicalRecord.getDescription()); taskMedicalRecord.setDescription("Medical Record Validated by Doctor"); List<RecordRow> rows = new ArrayList<RecordRow>(); RecordRow recordRow = new RecordRow("CODE-999", "Just a regular Cold"); recordRow.setMedicalRecord(medicalRecord); rows.add(recordRow); taskMedicalRecord.setRows(rows); taskMedicalRecord.setPriority(1); output = new HashMap<String, Object>(); output.put("output2", taskMedicalRecord); taskService.complete(doctorTasks.get(0).getId(), "doctor", output); // tasks for manager managerTasks = taskService.getTasksAssignedAsPotentialOwner("manager", "en-UK"); Assert.assertEquals(1, managerTasks.size()); taskService.start(managerTasks.get(0).getId(), "manager"); Patient patient = taskMedicalRecord.getPatient(); patient.setNextAppointment(new Date()); output = new HashMap<String, Object>(); output.put("output3", taskMedicalRecord); // ksession.getWorkItemManager().registerWorkItemHandler("Human Task", htHandler); taskService.complete(managerTasks.get(0).getId(), "manager", output); // since persisted process instance is completed it should be null process = ksession.getProcessInstance(process.getId()); Assert.assertNull(process); } @SuppressWarnings("rawtypes") private MedicalRecord getTaskContent(RuntimeEngine runtimeEngine, TaskSummary summary) throws IOException, ClassNotFoundException{ logger.info(" >>> Getting Task Content = {}", summary.getId()); Task task = runtimeEngine.getTaskService().getTaskById(summary.getId()); long documentContentId = task.getTaskData().getDocumentContentId(); Content content = runtimeEngine.getTaskService().getContentById(documentContentId); Object readObject = ContentMarshallerHelper.unmarshall(content.getContent(), runtimeEngine.getKieSession().getEnvironment()); logger.info(" >>> Object = {}", readObject); return (MedicalRecord)((Map)readObject).get("Content"); } }