/*
* 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.
*
* Contributions from 2013-2017 where performed either by US government
* employees, or under US Veterans Health Administration contracts.
*
* US Veterans Health Administration contributions by government employees
* are work of the U.S. Government and are not subject to copyright
* protection in the United States. Portions contributed by government
* employees are USGovWork (17USC §105). Not subject to copyright.
*
* Contribution by contractors to the US Veterans Health Administration
* during this period are contractually contributed under the
* Apache License, Version 2.0.
*
* See: https://www.usa.gov/government-works
*
* Contributions prior to 2013:
*
* Copyright (C) International Health Terminology Standards Development Organisation.
* Licensed under the Apache License, Version 2.0.
*
*/
package sh.isaac.integration.tests;
//~--- JDK imports ------------------------------------------------------------
import java.util.Date;
import java.util.HashSet;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
//~--- non-JDK imports --------------------------------------------------------
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jvnet.testing.hk2testng.HK2;
import org.testng.Assert;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import sh.isaac.api.Get;
import sh.isaac.api.LookupService;
import sh.isaac.api.State;
import sh.isaac.api.UserRole;
import sh.isaac.api.bootstrap.TermAux;
import sh.isaac.api.chronicle.LatestVersion;
import sh.isaac.api.commit.CommitRecord;
import sh.isaac.api.commit.Stamp;
import sh.isaac.api.component.concept.ConceptChronology;
import sh.isaac.api.component.concept.ConceptVersion;
import sh.isaac.api.component.sememe.SememeChronology;
import sh.isaac.api.component.sememe.version.DescriptionSememe;
import sh.isaac.api.component.sememe.version.SememeVersion;
import sh.isaac.api.coordinate.EditCoordinate;
import sh.isaac.api.coordinate.StampCoordinate;
import sh.isaac.api.observable.coordinate.ObservableStampCoordinate;
import sh.isaac.MetaData;
import sh.isaac.model.concept.ConceptChronologyImpl;
import sh.isaac.model.coordinate.EditCoordinateImpl;
import sh.isaac.model.coordinate.StampCoordinateImpl;
import sh.isaac.model.sememe.SememeChronologyImpl;
import sh.isaac.model.sememe.version.DescriptionSememeImpl;
import sh.isaac.provider.workflow.BPMNInfo;
import sh.isaac.provider.workflow.WorkflowProvider;
import sh.isaac.provider.workflow.model.contents.AbstractStorableWorkflowContents;
import sh.isaac.provider.workflow.model.contents.AvailableAction;
import sh.isaac.provider.workflow.model.contents.ProcessDetail;
import sh.isaac.provider.workflow.model.contents.ProcessDetail.EndWorkflowType;
import sh.isaac.provider.workflow.model.contents.ProcessDetail.ProcessStatus;
import sh.isaac.provider.workflow.model.contents.ProcessHistory;
import sh.isaac.provider.workflow.user.SimpleUserRoleService;
//~--- classes ----------------------------------------------------------------
/**
* Created by kec on 1/2/16.
*/
@HK2("integration")
public class WorkflowFrameworkTest {
/** The Constant LOG. */
private static final Logger LOG = LogManager.getLogger();
/** The Constant LAUNCH_STATE. */
private static final String LAUNCH_STATE = "Ready for Edit";
/** The Constant LAUNCH_ACTION. */
private static final String LAUNCH_ACTION = "Edit";
/** The Constant LAUNCH_OUTCOME. */
private static final String LAUNCH_OUTCOME = "Ready for Review";
/** The Constant LAUNCH_COMMENT. */
private static final String LAUNCH_COMMENT = "Launch Comment";
/** The Constant SEND_TO_APPROVAL_STATE. */
private static final String SEND_TO_APPROVAL_STATE = "Ready for Review";
/** The Constant SEND_TO_APPROVAL_ACTION. */
private static final String SEND_TO_APPROVAL_ACTION = "Review";
/** The Constant SEND_TO_APPROVAL_OUTCOME. */
private static final String SEND_TO_APPROVAL_OUTCOME = "Ready for Approve";
/** The Constant SEND_TO_APPROVAL_COMMENT. */
private static final String SEND_TO_APPROVAL_COMMENT = "Sending for Approval";
/** The Constant REJECT_REVIEW_STATE. */
private static final String REJECT_REVIEW_STATE = "Ready for Review";
/** The Constant REJECT_REVIEW_ACTION. */
private static final String REJECT_REVIEW_ACTION = "Reject QA";
/** The Constant REJECT_REVIEW_OUTCOME. */
private static final String REJECT_REVIEW_OUTCOME = "Ready for Edit";
/** The Constant REJECT_REVIEW_COMMENT. */
private static final String REJECT_REVIEW_COMMENT = "Rejecting QA sending back to Edit";
/** The Constant CONCLUDED_WORKFLOW_COMMENT. */
protected static final String CONCLUDED_WORKFLOW_COMMENT = "Concluded Workflow";
/** The Constant CANCELED_WORKFLOW_COMMENT. */
protected static final String CANCELED_WORKFLOW_COMMENT = "Canceled Workflow";
/** The bpmn file path. */
private static final String BPMN_FILE_PATH =
"/sh/isaac/integration/tests/StaticWorkflowIntegrationTestingDefinition.bpmn2";
/** The user id. */
private static UUID userId;
/** The first test concept nid. */
private static int firstTestConceptNid;
/** The second test concept nid. */
private static int secondTestConceptNid;
/** The cancel action. */
protected static AvailableAction cancelAction;
//~--- fields --------------------------------------------------------------
/** The wp. */
WorkflowProvider wp;
/** The default edit coordinate. */
private EditCoordinate defaultEditCoordinate;
/** The default stamp coordinate. */
private StampCoordinate defaultStampCoordinate;
/** The module seq. */
private int moduleSeq;
/** The path seq. */
private int pathSeq;
//~--- methods -------------------------------------------------------------
/**
* Test cancel activation of components.
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testCancelActivationOfComponents() {
clearStores();
LOG.info("Testing Ability to cancel change on a concept and a sememe made active when originally was inactive");
}
/**
* Test cancel editing of sememe.
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testCancelEditingOfSememe() {
clearStores();
LOG.info("Testing Ability to cancel changes made to a sememe's text");
try {
final UUID processId = this.wp.getWorkflowProcessInitializerConcluder()
.createWorkflowProcess(this.wp.getBPMNInfo()
.getDefinitionId(),
userId,
"Framework Workflow Name",
" Framework Workflow Description");
final ConceptChronology<? extends ConceptVersion<?>> con = Get.conceptService()
.getConcept(firstTestConceptNid);
final SememeChronologyImpl descSem = (SememeChronologyImpl) con.getConceptDescriptionList()
.iterator()
.next();
Optional<LatestVersion<DescriptionSememe<?>>> latestDescVersion =
((SememeChronology) descSem).getLatestVersion(DescriptionSememe.class,
Get.configurationService()
.getDefaultStampCoordinate());
final String originalText = latestDescVersion.get()
.value()
.getText();
// Modify Sememe Text
final DescriptionSememeImpl createdVersion = cloneVersion(descSem, State.ACTIVE);
createdVersion.setText("New Text");
Get.commitService()
.addUncommitted(descSem)
.get();
final Optional<CommitRecord> commitRecord = Get.commitService()
.commit("Inactivating sememe for Testing")
.get();
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "Edit", "Edit Comment", this.defaultEditCoordinate);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId,
userId,
"Cancel Workflow",
"Canceling Workflow for Testing",
this.defaultEditCoordinate);
final SememeChronology<? extends SememeVersion<?>> semChron = Get.sememeService()
.getSememe(descSem.getNid());
latestDescVersion = ((SememeChronology) semChron).getLatestVersion(DescriptionSememe.class,
Get.configurationService()
.getDefaultStampCoordinate());
Assert.assertEquals(originalText, latestDescVersion.get()
.value()
.getText());
} catch (final Exception e) {
Assert.fail(e.getMessage());
}
}
/**
* Test cancel inactivation of components.
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testCancelInactivationOfComponents() {
clearStores();
LOG.info("Testing Ability to cancel change on a concept and a sememe made inactive when originally was active");
try {
final UUID processId = this.wp.getWorkflowProcessInitializerConcluder()
.createWorkflowProcess(this.wp.getBPMNInfo()
.getDefinitionId(),
userId,
"Framework Workflow Name",
" Framework Workflow Description");
final ConceptChronologyImpl con = (ConceptChronologyImpl) Get.conceptService()
.getConcept(firstTestConceptNid);
final int semNid = con.getConceptDescriptionList()
.iterator()
.next()
.getNid();
final SememeChronologyImpl semChron = (SememeChronologyImpl) Get.sememeService()
.getSememe(semNid);
verifyState(con, semChron, State.ACTIVE);
// Inactivate Concept
con.createMutableVersion(State.INACTIVE, this.defaultEditCoordinate);
Get.commitService()
.addUncommitted(con)
.get();
Optional<CommitRecord> commitRecord = Get.commitService()
.commit("Inactivating concept for Testing")
.get();
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
// Inactivate Sememe
final DescriptionSememeImpl createdVersion = cloneVersion(semChron, State.INACTIVE);
Get.commitService()
.addUncommitted(semChron)
.get();
commitRecord = Get.commitService()
.commit("Inactivating sememe for Testing")
.get();
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
verifyState(con, semChron, State.INACTIVE);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "Edit", "Edit Comment", this.defaultEditCoordinate);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId,
userId,
"Cancel Workflow",
"Canceling Workflow for Testing",
this.defaultEditCoordinate);
verifyState(con, semChron, State.ACTIVE);
} catch (final Exception e) {
Assert.fail();
}
}
/**
* Test cancel new components.
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testCancelNewComponents() {
clearStores();
LOG.info("Testing Ability to cancel new concept reverting it entirely");
}
/**
* Test cancel new sememe.
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testCancelNewSememe() {
clearStores();
LOG.info("Testing Ability to cancel new sememe reverting it entirely");
}
/**
* Test cancel no launch.
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testCancelNoLaunch() {
clearStores();
LOG.info("Testing ability to cancel a workflow that has only been defined");
UUID processId = null;
try {
processId = this.wp.getWorkflowProcessInitializerConcluder()
.createWorkflowProcess(this.wp.getBPMNInfo()
.getDefinitionId(),
userId,
"Framework Workflow Name",
" Framework Workflow Description");
this.wp.getWorkflowProcessInitializerConcluder()
.endWorkflowProcess(processId,
getCancelAction(),
userId,
"Canceling Workflow for Testing",
EndWorkflowType.CANCELED,
this.defaultEditCoordinate);
Assert.assertEquals(ProcessStatus.CANCELED,
this.wp.getWorkflowAccessor()
.getProcessDetails(processId)
.getStatus());
} catch (final Exception e) {
Assert.fail();
}
}
/**
* Test conclude no launch.
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testConcludeNoLaunch() {
clearStores();
LOG.info("Testing ability to conclude a workflow that has only been defined");
UUID processId = null;
try {
processId = this.wp.getWorkflowProcessInitializerConcluder()
.createWorkflowProcess(this.wp.getBPMNInfo()
.getDefinitionId(),
userId,
"Framework Workflow Name",
" Framework Workflow Description");
this.wp.getWorkflowProcessInitializerConcluder()
.endWorkflowProcess(processId,
getConcludeAction(),
userId,
"Concluding Workflow for Testing",
EndWorkflowType.CONCLUDED,
this.defaultEditCoordinate);
} catch (final Exception e) {
Assert.assertTrue(true);
}
Assert.assertEquals(ProcessStatus.DEFINED,
this.wp.getWorkflowAccessor()
.getProcessDetails(processId)
.getStatus());
}
/**
* Test fail cancel call.
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testFailCancelCall() {
clearStores();
LOG.info("Testing inability to cancel an already concluded Workflow ");
UUID processId = null;
try {
processId = this.wp.getWorkflowProcessInitializerConcluder()
.createWorkflowProcess(this.wp.getBPMNInfo()
.getDefinitionId(),
userId,
"Framework Workflow Name",
" Framework Workflow Description");
final Optional<CommitRecord> commitRecord = createNewVersion(firstTestConceptNid, null);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "Edit", "Edit Comment", this.defaultEditCoordinate);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "QA Passes", "Review Comment", this.defaultEditCoordinate);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "Approve", "Approve Comment", this.defaultEditCoordinate);
Assert.assertFalse(this.wp.getWorkflowUpdater()
.advanceWorkflow(processId,
userId,
"Cancel Workflow",
"Canceling Workflow for Testing",
this.defaultEditCoordinate));
Assert.assertEquals(ProcessStatus.CONCLUDED,
this.wp.getWorkflowAccessor()
.getProcessDetails(processId)
.getStatus());
final ProcessHistory hx = this.wp.getWorkflowAccessor()
.getProcessHistory(processId)
.last();
Assert.assertTrue(isEndState(hx.getOutcomeState(), EndWorkflowType.CONCLUDED));
} catch (final Exception e) {
Assert.fail();
}
}
/**
* Test fail conclude.
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testFailConclude() {
clearStores();
LOG.info("Testing inability to conclude a workflow that hasn't reached a final workflow state");
UUID processId = null;
try {
processId = this.wp.getWorkflowProcessInitializerConcluder()
.createWorkflowProcess(this.wp.getBPMNInfo()
.getDefinitionId(),
userId,
"Framework Workflow Name",
" Framework Workflow Description");
final Optional<CommitRecord> commitRecord = createNewVersion(firstTestConceptNid, null);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
ProcessHistory hx = this.wp.getWorkflowAccessor()
.getProcessHistory(processId)
.last();
Assert.assertTrue(this.wp.getBPMNInfo()
.getEditStatesMap()
.get(this.wp.getBPMNInfo()
.getDefinitionId())
.contains(hx.getOutcomeState()));
Assert.assertTrue(isStartState(this.wp.getBPMNInfo()
.getDefinitionId(), hx.getInitialState()));
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "Edit", "Edit Comment", this.defaultEditCoordinate);
final boolean result = this.wp.getWorkflowUpdater()
.advanceWorkflow(processId,
userId,
"Approve",
"Concluding Workflow for Testing",
this.defaultEditCoordinate);
Assert.assertFalse(result);
Assert.assertEquals(ProcessStatus.LAUNCHED,
this.wp.getWorkflowAccessor()
.getProcessDetails(processId)
.getStatus());
hx = this.wp.getWorkflowAccessor()
.getProcessHistory(processId)
.last();
Assert.assertFalse(this.wp.getBPMNInfo()
.getEditStatesMap()
.get(this.wp.getBPMNInfo()
.getDefinitionId())
.contains(hx.getOutcomeState()));
Assert.assertFalse(isStartState(this.wp.getBPMNInfo()
.getDefinitionId(), hx.getInitialState()));
} catch (final Exception e) {
Assert.fail();
}
}
// TODO: Decide if prevent multiple processes with same name
/**
* Test fail define after launched.
*/
/*
* @Test(groups = { "wf" }, dependsOnMethods = { "testLoadWorkflow" })
* public void testFailDefineAfterDefineSameName() { LOG.
* info("Testing inability to define a workflow on a concept that has already been defined"
* ); UUID processId = null;
*
* try { processId =
* wp.getWorkflowProcessInitializerConcluder().createWorkflowProcess(wp.
* getBPMNInfo().getDefinitionId(), userId, "Framework Workflow Name",
* " Framework Workflow Description"); processId =
* wp.getWorkflowProcessInitializerConcluder().createWorkflowProcess(wp.
* getBPMNInfo().getDefinitionId(), userId, "Framework Workflow Name",
* " Framework Workflow Description"); Assert.fail(); } catch (Exception e)
* { Assert.assertTrue(true); Assert.assertEquals(ProcessStatus.DEFINED,
* wp.getWorkflowAccessor().getProcessDetails(processId).getStatus()); }
*
* clearStores(); }
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testFailDefineAfterLaunched() {
clearStores();
LOG.info("Testing inability to add a concept onto a workflow other than one that has already been launched");
UUID processId = null;
try {
processId = this.wp.getWorkflowProcessInitializerConcluder()
.createWorkflowProcess(this.wp.getBPMNInfo()
.getDefinitionId(),
userId,
"Framework Workflow Name",
" Framework Workflow Description");
Optional<CommitRecord> commitRecord = createNewVersion(firstTestConceptNid, null);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
commitRecord = createNewVersion(firstTestConceptNid, null);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "Edit", "Edit Comment", this.defaultEditCoordinate);
try {
commitRecord = createNewVersion(firstTestConceptNid, null);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
Assert.fail();
} catch (final Exception e) {
Assert.assertTrue(true);
}
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "QA Fails", "QA Fail", this.defaultEditCoordinate);
commitRecord = createNewVersion(firstTestConceptNid, null);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
Assert.assertEquals(ProcessStatus.LAUNCHED,
this.wp.getWorkflowAccessor()
.getProcessDetails(processId)
.getStatus());
} catch (final Exception e) {
Assert.fail();
}
}
/**
* Test fail launch.
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testFailLaunch() {
clearStores();
LOG.info("Testing inability to launch a workflow that has yet to be defined");
final UUID processId = UUID.randomUUID();
try {
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "Edit", "Edit Comment", this.defaultEditCoordinate);
Assert.assertTrue(true);
AbstractStorableWorkflowContents process = null;
process = this.wp.getWorkflowAccessor()
.getProcessDetails(processId);
if (process == null) {
Assert.assertTrue(true);
} else {
Assert.fail();
}
} catch (final Exception ee) {
Assert.fail();
}
}
/**
* Test integration add commit record to workflow.
*
* @throws Exception the exception
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testIntegrationAddCommitRecordToWorkflow()
throws Exception {
clearStores();
// Cannot make this work without at least a Mock Database.
// Added to Integration-Test module's workflowFramworkTest. For now just
// pass.
Assert.assertTrue(true);
final UUID processId = createFirstWorkflowProcess(this.wp.getBPMNInfo()
.getDefinitionId());
ProcessDetail details = this.wp.getProcessDetailStore()
.get(processId);
Assert.assertFalse(details.getComponentToInitialEditMap()
.keySet()
.contains(firstTestConceptNid));
Optional<CommitRecord> commitRecord = createNewVersion(firstTestConceptNid, null);
final Stamp commitRecordStamp = createStampFromCommitRecord(commitRecord);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
details = this.wp.getProcessDetailStore()
.get(processId);
Assert.assertEquals(1, details.getComponentToInitialEditMap()
.keySet()
.size());
Assert.assertTrue(details.getComponentToInitialEditMap()
.keySet()
.contains(firstTestConceptNid));
Assert.assertEquals(1, details.getComponentToInitialEditMap()
.keySet()
.size());
Assert.assertTrue(commitRecordStamp.equals(details.getComponentToInitialEditMap()
.get(firstTestConceptNid)));
commitRecord = createNewVersion(firstTestConceptNid, null);
final Stamp updatedCommitRecordStamp = createStampFromCommitRecord(commitRecord);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
details = this.wp.getProcessDetailStore()
.get(processId);
Assert.assertEquals(1, details.getComponentToInitialEditMap()
.keySet()
.size());
Assert.assertTrue(details.getComponentToInitialEditMap()
.keySet()
.contains(firstTestConceptNid));
Assert.assertTrue(commitRecordStamp.equals(details.getComponentToInitialEditMap()
.get(firstTestConceptNid)));
Assert.assertFalse(updatedCommitRecordStamp.equals(details.getComponentToInitialEditMap()
.get(firstTestConceptNid)));
// Dan commented out on 10/31/16, because these tests are broken with a nasty timing bug that I don't have time to deal with. Jesse to fix
// commitRecord = createNewVersion(secondTestConceptNid, null);
// Stamp secondCommitRecordStamp = createStampFromCommitRecord(commitRecord);
// wp.getWorkflowUpdater().addCommitRecordToWorkflow(processId, commitRecord);
// details = wp.getProcessDetailStore().get(processId);
// Assert.assertEquals(2, details.getComponentToInitialEditMap().keySet().size());
// Assert.assertTrue(details.getComponentToInitialEditMap().keySet().contains(firstTestConceptNid));
// Assert.assertTrue(details.getComponentToInitialEditMap().keySet().contains(secondTestConceptNid));
// Assert.assertTrue(commitRecordStamp.equals(details.getComponentToInitialEditMap().get(firstTestConceptNid)));
// Assert.assertFalse(updatedCommitRecordStamp.equals(details.getComponentToInitialEditMap().get(firstTestConceptNid)));
// Assert.assertFalse(secondCommitRecordStamp.equals(details.getComponentToInitialEditMap().get(firstTestConceptNid)));
// Assert.assertFalse(commitRecordStamp.equals(details.getComponentToInitialEditMap().get(secondTestConceptNid)));
// Assert.assertFalse(updatedCommitRecordStamp.equals(details.getComponentToInitialEditMap().get(secondTestConceptNid)));
// Assert.assertTrue(secondCommitRecordStamp.equals(details.getComponentToInitialEditMap().get(secondTestConceptNid)));
}
/**
* Test integration failures with add remove components to process.
*
* @throws Exception the exception
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testIntegrationFailuresWithAddRemoveComponentsToProcess()
throws Exception {
clearStores();
final UUID processId = UUID.randomUUID();
try {
this.wp.getWorkflowUpdater()
.removeComponentFromWorkflow(processId, firstTestConceptNid, this.defaultEditCoordinate);
Assert.fail();
} catch (final Exception e) {
Assert.assertTrue(true);
}
final UUID firstProcessId = createFirstWorkflowProcess(this.wp.getBPMNInfo()
.getDefinitionId());
final Optional<CommitRecord> commitRecord = createNewVersion(firstTestConceptNid, null);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(firstProcessId, commitRecord);
this.wp.getWorkflowUpdater()
.advanceWorkflow(firstProcessId, userId, "Edit", "Edit Comment", this.defaultEditCoordinate);
try {
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(firstProcessId, commitRecord);
Assert.fail();
} catch (final Exception e) {
Assert.assertTrue(true);
}
try {
// Go back to no components in any workflow
this.wp.getWorkflowUpdater()
.removeComponentFromWorkflow(firstProcessId, firstTestConceptNid, this.defaultEditCoordinate);
Assert.fail();
} catch (final Exception e) {
Assert.assertTrue(true);
}
executeSendForReviewAdvancement(firstProcessId);
try {
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(firstProcessId, commitRecord);
Assert.fail();
} catch (final Exception e) {
Assert.assertTrue(true);
}
try {
// Go back to no components in any workflow
this.wp.getWorkflowUpdater()
.removeComponentFromWorkflow(firstProcessId, firstTestConceptNid, this.defaultEditCoordinate);
Assert.fail();
} catch (final Exception e) {
Assert.assertTrue(true);
}
// Rejecting QA to get back to edit state
executeRejectReviewAdvancement(firstProcessId);
// Go back to no components in any workflow
this.wp.getWorkflowUpdater()
.removeComponentFromWorkflow(firstProcessId, firstTestConceptNid, this.defaultEditCoordinate);
// Testing LAUNCHED-EDIT Case
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(firstProcessId, commitRecord);
final ProcessDetail details = this.wp.getProcessDetailStore()
.get(firstProcessId);
Assert.assertEquals(1, details.getComponentToInitialEditMap()
.keySet()
.size());
Assert.assertTrue(details.getComponentToInitialEditMap()
.keySet()
.contains(firstTestConceptNid));
Assert.assertEquals(1, details.getComponentToInitialEditMap()
.keySet()
.size());
// Testing INACTIVE Case
cancelWorkflow(firstProcessId);
try {
this.wp.getWorkflowUpdater()
.removeComponentFromWorkflow(firstProcessId, firstTestConceptNid, this.defaultEditCoordinate);
Assert.fail();
} catch (final Exception e) {
Assert.assertTrue(true);
}
}
/**
* Test integration remove components from process.
*
* @throws Exception the exception
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testIntegrationRemoveComponentsFromProcess()
throws Exception {
clearStores();
final UUID processId = createFirstWorkflowProcess(this.wp.getBPMNInfo()
.getDefinitionId());
ProcessDetail details = this.wp.getProcessDetailStore()
.get(processId);
Assert.assertEquals(0, details.getComponentToInitialEditMap()
.keySet()
.size());
Optional<CommitRecord> commitRecord = createNewVersion(firstTestConceptNid, null);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
commitRecord = createNewVersion(firstTestConceptNid, null);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
commitRecord = createNewVersion(secondTestConceptNid, null);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
commitRecord = createNewVersion(secondTestConceptNid, null);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
details = this.wp.getProcessDetailStore()
.get(processId);
Assert.assertEquals(2, details.getComponentToInitialEditMap()
.keySet()
.size());
this.wp.getWorkflowUpdater()
.removeComponentFromWorkflow(processId, firstTestConceptNid, this.defaultEditCoordinate);
details = this.wp.getProcessDetailStore()
.get(processId);
Assert.assertEquals(1, details.getComponentToInitialEditMap()
.keySet()
.size());
Assert.assertFalse(details.getComponentToInitialEditMap()
.keySet()
.contains(firstTestConceptNid));
Assert.assertTrue(details.getComponentToInitialEditMap()
.keySet()
.contains(secondTestConceptNid));
this.wp.getWorkflowUpdater()
.removeComponentFromWorkflow(processId, secondTestConceptNid, this.defaultEditCoordinate);
details = this.wp.getProcessDetailStore()
.get(processId);
Assert.assertEquals(0, details.getComponentToInitialEditMap()
.keySet()
.size());
}
/**
* Test load workflow.
*/
@Test(
groups = { "wf" },
dependsOnGroups = { "load" }
)
public void testLoadWorkflow() {
LOG.info("Loading Metadata db");
firstTestConceptNid = MetaData.ISAAC_METADATA.getNid();
secondTestConceptNid = MetaData.ACCEPTABLE.getNid();
WorkflowProvider.BPMN_PATH = BPMN_FILE_PATH;
this.wp = LookupService.get()
.getService(WorkflowProvider.class);
cancelAction = this.wp.getBPMNInfo()
.getEndWorkflowTypeMap()
.get(EndWorkflowType.CONCLUDED)
.iterator()
.next();
this.defaultEditCoordinate = new EditCoordinateImpl(TermAux.USER.getNid(),
MetaData.ISAAC_MODULE.getNid(),
MetaData.DEVELOPMENT_PATH.getNid());
final ObservableStampCoordinate defaultSC = Get.configurationService()
.getDefaultStampCoordinate();
this.defaultStampCoordinate = new StampCoordinateImpl(defaultSC.getStampPrecedence(),
defaultSC.getStampPosition(),
defaultSC.getModuleSequences(),
State.ANY_STATE_SET);
firstTestConceptNid = MetaData.EL_PLUS_PLUS_INFERRED_FORM_ASSEMBLAGE.getNid();
secondTestConceptNid = MetaData.ACCEPTABLE.getNid();
}
/**
* Test process time fields.
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testProcessTimeFields() {
clearStores();
LOG.info("Testing Ability to cancel changes made to a sememe's text");
try {
// Create WF
final UUID processId = this.wp.getWorkflowProcessInitializerConcluder()
.createWorkflowProcess(this.wp.getBPMNInfo()
.getDefinitionId(),
userId,
"Framework Workflow Name",
" Framework Workflow Description");
long timeCreated = this.wp.getWorkflowAccessor()
.getProcessDetails(processId)
.getTimeCreated();
long timeCanceledOrConcluded = this.wp.getWorkflowAccessor()
.getProcessDetails(processId)
.getTimeCanceledOrConcluded();
long timeLaunched = this.wp.getWorkflowAccessor()
.getProcessDetails(processId)
.getTimeLaunched();
Assert.assertTrue(timeCreated > -1);
Assert.assertEquals(-1, timeLaunched);
Assert.assertEquals(-1, timeCanceledOrConcluded);
// Launch WF
final Optional<CommitRecord> commitRecord = createNewVersion(firstTestConceptNid, null);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "Edit", "Edit Comment", this.defaultEditCoordinate);
timeCreated = this.wp.getWorkflowAccessor()
.getProcessDetails(processId)
.getTimeCreated();
timeCanceledOrConcluded = this.wp.getWorkflowAccessor()
.getProcessDetails(processId)
.getTimeCanceledOrConcluded();
timeLaunched = this.wp.getWorkflowAccessor()
.getProcessDetails(processId)
.getTimeLaunched();
Assert.assertTrue(timeCreated > -1);
Assert.assertTrue(timeLaunched > -1);
Assert.assertEquals(-1, timeCanceledOrConcluded);
// Cancel WF
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId,
userId,
"Cancel Workflow",
"Canceling Workflow for Testing",
this.defaultEditCoordinate);
timeCreated = this.wp.getWorkflowAccessor()
.getProcessDetails(processId)
.getTimeCreated();
timeCanceledOrConcluded = this.wp.getWorkflowAccessor()
.getProcessDetails(processId)
.getTimeCanceledOrConcluded();
timeLaunched = this.wp.getWorkflowAccessor()
.getProcessDetails(processId)
.getTimeLaunched();
Assert.assertTrue(timeCreated > -1);
Assert.assertTrue(timeLaunched > -1);
Assert.assertTrue(timeCanceledOrConcluded > -1);
} catch (final Exception e) {
Assert.fail(e.getMessage());
}
}
/**
* Test redefine call.
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testRedefineCall() {
clearStores();
LOG.info("Testing ability to define and launch workflow on a concept that has an already-concluded workflow");
try {
UUID processId = this.wp.getWorkflowProcessInitializerConcluder()
.createWorkflowProcess(this.wp.getBPMNInfo()
.getDefinitionId(),
userId,
"Framework Workflow Name",
" Framework Workflow Description");
final Optional<CommitRecord> commitRecord = createNewVersion(firstTestConceptNid, null);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "Edit", "Edit Comment", this.defaultEditCoordinate);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "QA Passes", "Review Comment", this.defaultEditCoordinate);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "Approve", "Approve Comment", this.defaultEditCoordinate);
Assert.assertEquals(ProcessStatus.CONCLUDED,
this.wp.getWorkflowAccessor()
.getProcessDetails(processId)
.getStatus());
final ProcessHistory hx = this.wp.getWorkflowAccessor()
.getProcessHistory(processId)
.last();
Assert.assertTrue(isEndState(hx.getOutcomeState(), EndWorkflowType.CONCLUDED));
processId = this.wp.getWorkflowProcessInitializerConcluder()
.createWorkflowProcess(this.wp.getBPMNInfo()
.getDefinitionId(),
userId,
"Framework Workflow Name2",
" Framework Workflow Description");
Assert.assertEquals(ProcessStatus.DEFINED,
this.wp.getWorkflowAccessor()
.getProcessDetails(processId)
.getStatus());
} catch (final Exception e) {
Assert.fail();
}
}
/**
* Test start all fail conclude.
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testStartAllFailConclude() {
clearStores();
LOG.info(
"Testing ability to advance workflow to conclusion via with a rejection/failure happening at each point in path");
UUID processId = null;
try {
processId = this.wp.getWorkflowProcessInitializerConcluder()
.createWorkflowProcess(this.wp.getBPMNInfo()
.getDefinitionId(),
userId,
"Framework Workflow Name",
" Framework Workflow Description");
final Optional<CommitRecord> commitRecord = createNewVersion(firstTestConceptNid, null);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "Edit", "Edit Comment", this.defaultEditCoordinate);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "QA Fails", "Fail Review Comment", this.defaultEditCoordinate);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "Edit", "Second Edit Comment", this.defaultEditCoordinate);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "QA Passes", "Review Comment", this.defaultEditCoordinate);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "Reject Edit", "Reject Edit Comment", this.defaultEditCoordinate);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "Edit", "Third Edit Comment", this.defaultEditCoordinate);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "QA Passes", "Second Review Comment", this.defaultEditCoordinate);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId,
userId,
"Reject Review",
"Reject Review Comment",
this.defaultEditCoordinate);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "QA Passes", "Third Review Comment", this.defaultEditCoordinate);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "Approve", "Approve Comment", this.defaultEditCoordinate);
final boolean result = this.wp.getWorkflowUpdater()
.advanceWorkflow(processId,
userId,
"Approve",
"Concluding Workflow for Testing",
this.defaultEditCoordinate);
Assert.assertFalse(result);
Assert.assertEquals(ProcessStatus.CONCLUDED,
this.wp.getWorkflowAccessor()
.getProcessDetails(processId)
.getStatus());
final ProcessHistory hx = this.wp.getWorkflowAccessor()
.getProcessHistory(processId)
.last();
Assert.assertTrue(isEndState(hx.getOutcomeState(), EndWorkflowType.CONCLUDED));
} catch (final Exception ee) {
Assert.fail();
}
}
/**
* Test start all pass conclude.
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testStartAllPassConclude() {
clearStores();
LOG.info("Testing ability to advance workflow to conclusion via its easy-path");
UUID processId = null;
try {
processId = this.wp.getWorkflowProcessInitializerConcluder()
.createWorkflowProcess(this.wp.getBPMNInfo()
.getDefinitionId(),
userId,
"Framework Workflow Name",
" Framework Workflow Description");
Assert.assertEquals(userId, this.wp.getProcessDetailStore()
.get(processId)
.getOwnerId());
ProcessDetail process = this.wp.getProcessDetailStore()
.get(processId);
Assert.assertEquals(userId, process.getOwnerId());
final Optional<CommitRecord> commitRecord = createNewVersion(firstTestConceptNid, null);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "Edit", "Edit Comment", this.defaultEditCoordinate);
process = this.wp.getProcessDetailStore()
.get(processId);
Assert.assertEquals(BPMNInfo.UNOWNED_PROCESS, process.getOwnerId());
process.setOwnerId(userId);
this.wp.getProcessDetailStore()
.put(processId, process);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "QA Passes", "Review Comment", this.defaultEditCoordinate);
process = this.wp.getProcessDetailStore()
.get(processId);
Assert.assertEquals(BPMNInfo.UNOWNED_PROCESS, process.getOwnerId());
process.setOwnerId(userId);
this.wp.getProcessDetailStore()
.put(processId, process);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "Approve", "Approve Comment", this.defaultEditCoordinate);
process = this.wp.getProcessDetailStore()
.get(processId);
Assert.assertEquals(ProcessStatus.CONCLUDED, process.getStatus());
Assert.assertEquals(BPMNInfo.UNOWNED_PROCESS, process.getOwnerId());
final ProcessHistory hx = this.wp.getWorkflowAccessor()
.getProcessHistory(processId)
.last();
Assert.assertTrue(isEndState(hx.getOutcomeState(), EndWorkflowType.CONCLUDED));
processId = this.wp.getWorkflowProcessInitializerConcluder()
.createWorkflowProcess(this.wp.getBPMNInfo()
.getDefinitionId(),
userId,
"Framework Workflow Name",
" Framework Workflow Description");
process = this.wp.getProcessDetailStore()
.get(processId);
Assert.assertEquals(userId, process.getOwnerId());
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId,
userId,
"Cancel Workflow",
"Canceling Workflow for Testing",
this.defaultEditCoordinate);
process = this.wp.getProcessDetailStore()
.get(processId);
Assert.assertEquals(BPMNInfo.UNOWNED_PROCESS, process.getOwnerId());
} catch (final Exception e) {
Assert.fail();
}
}
/**
* Test start cancel.
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testStartCancel() {
clearStores();
LOG.info("Testing ability to cancel a workflow that has been defined and launched");
UUID processId = null;
try {
processId = this.wp.getWorkflowProcessInitializerConcluder()
.createWorkflowProcess(this.wp.getBPMNInfo()
.getDefinitionId(),
userId,
"Framework Workflow Name",
" Framework Workflow Description");
final Optional<CommitRecord> commitRecord = createNewVersion(firstTestConceptNid, null);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "Edit", "Edit Comment", this.defaultEditCoordinate);
Thread.sleep(1); // TODO fix Dan Work around bug in design
this.wp.getWorkflowProcessInitializerConcluder()
.endWorkflowProcess(processId,
getCancelAction(),
userId,
"Canceling Workflow for Testing",
EndWorkflowType.CANCELED,
this.defaultEditCoordinate);
Assert.assertEquals(ProcessStatus.CANCELED,
this.wp.getWorkflowAccessor()
.getProcessDetails(processId)
.getStatus());
final ProcessHistory hx = this.wp.getWorkflowAccessor()
.getProcessHistory(processId)
.last();
Assert.assertTrue(isEndState(hx.getOutcomeState(), EndWorkflowType.CANCELED));
} catch (final Exception e) {
Assert.fail();
}
}
/**
* Test status accessor component in active workflow.
*/
@Test(
groups = { "wf" },
dependsOnMethods = { "testLoadWorkflow" }
)
public void testStatusAccessorComponentInActiveWorkflow() {
clearStores();
LOG.info("Testing Workflow History Accessor isComponentInActiveWorkflow()");
final ConceptChronology<? extends ConceptVersion<?>> con = Get.conceptService()
.getConcept(firstTestConceptNid);
final SememeChronology<? extends DescriptionSememe<?>> descSem = con.getConceptDescriptionList()
.iterator()
.next();
final int conNid = con.getNid();
final int semNid = descSem.getNid();
try {
Assert.assertFalse(this.wp.getWorkflowAccessor()
.isComponentInActiveWorkflow(this.wp.getBPMNInfo()
.getDefinitionId(), conNid));
Assert.assertFalse(this.wp.getWorkflowAccessor()
.isComponentInActiveWorkflow(this.wp.getBPMNInfo()
.getDefinitionId(), semNid));
final UUID processId = this.wp.getWorkflowProcessInitializerConcluder()
.createWorkflowProcess(this.wp.getBPMNInfo()
.getDefinitionId(),
userId,
"Framework Workflow Name",
" Framework Workflow Description");
Assert.assertFalse(this.wp.getWorkflowAccessor()
.isComponentInActiveWorkflow(this.wp.getBPMNInfo()
.getDefinitionId(), conNid));
Assert.assertFalse(this.wp.getWorkflowAccessor()
.isComponentInActiveWorkflow(this.wp.getBPMNInfo()
.getDefinitionId(), semNid));
Optional<CommitRecord> commitRecord = createNewVersion(conNid, null);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
commitRecord = createNewVersion(null, semNid);
this.wp.getWorkflowUpdater()
.addCommitRecordToWorkflow(processId, commitRecord);
Assert.assertTrue(this.wp.getWorkflowAccessor()
.isComponentInActiveWorkflow(this.wp.getBPMNInfo()
.getDefinitionId(), conNid));
Assert.assertTrue(this.wp.getWorkflowAccessor()
.isComponentInActiveWorkflow(this.wp.getBPMNInfo()
.getDefinitionId(), semNid));
this.wp.getWorkflowUpdater()
.advanceWorkflow(processId, userId, "Edit", "Edit Comment", this.defaultEditCoordinate);
Assert.assertTrue(this.wp.getWorkflowAccessor()
.isComponentInActiveWorkflow(this.wp.getBPMNInfo()
.getDefinitionId(), conNid));
Assert.assertTrue(this.wp.getWorkflowAccessor()
.isComponentInActiveWorkflow(this.wp.getBPMNInfo()
.getDefinitionId(), semNid));
this.wp.getWorkflowProcessInitializerConcluder()
.endWorkflowProcess(processId,
getCancelAction(),
userId,
"Canceling Workflow for Testing",
EndWorkflowType.CANCELED,
null);
Assert.assertFalse(this.wp.getWorkflowAccessor()
.isComponentInActiveWorkflow(this.wp.getBPMNInfo()
.getDefinitionId(), conNid));
Assert.assertFalse(this.wp.getWorkflowAccessor()
.isComponentInActiveWorkflow(this.wp.getBPMNInfo()
.getDefinitionId(), semNid));
} catch (final Exception e) {
Assert.fail(e.getMessage());
}
}
/**
* Cancel workflow.
*
* @param processId the process id
*/
protected void cancelWorkflow(UUID processId) {
try {
Thread.sleep(1);
finishWorkflowProcess(processId, cancelAction, userId, "Canceled Workflow", EndWorkflowType.CANCELED);
} catch (final Exception e) {
Assert.fail();
}
}
/**
* Creates the first workflow process.
*
* @param requestedDefinitionId the requested definition id
* @return the uuid
*/
protected UUID createFirstWorkflowProcess(UUID requestedDefinitionId) {
return createWorkflowProcess(requestedDefinitionId, "Main Process Name", "Main Process Description");
}
/**
* Creates the second workflow process.
*
* @param requestedDefinitionId the requested definition id
* @return the uuid
*/
protected UUID createSecondWorkflowProcess(UUID requestedDefinitionId) {
return createWorkflowProcess(requestedDefinitionId, "Secondary Process Name", "Secondary Process Description");
}
/**
* Execute launch workflow.
*
* @param processId the process id
*/
protected void executeLaunchWorkflow(UUID processId) {
try {
Thread.sleep(1);
final ProcessDetail entry = this.wp.getProcessDetailStore()
.get(processId);
entry.setStatus(ProcessStatus.LAUNCHED);
entry.setTimeLaunched(new Date().getTime());
this.wp.getProcessDetailStore()
.put(processId, entry);
} catch (final InterruptedException e) {
throw new RuntimeException(e);
}
}
/**
* Execute reject review advancement.
*
* @param requestedProcessId the requested process id
*/
protected void executeRejectReviewAdvancement(UUID requestedProcessId) {
try {
Thread.sleep(1);
final ProcessHistory hx = this.wp.getWorkflowAccessor()
.getProcessHistory(requestedProcessId)
.last();
final ProcessHistory entry = new ProcessHistory(requestedProcessId,
userId,
new Date().getTime(),
REJECT_REVIEW_STATE,
REJECT_REVIEW_ACTION,
REJECT_REVIEW_OUTCOME,
REJECT_REVIEW_COMMENT,
hx.getHistorySequence() + 1);
this.wp.getProcessHistoryStore()
.add(entry);
} catch (final InterruptedException e) {
throw new RuntimeException(e);
}
}
/**
* Execute send for approval advancement.
*
* @param requestedProcessId the requested process id
*/
protected void executeSendForApprovalAdvancement(UUID requestedProcessId) {
try {
Thread.sleep(1);
final ProcessHistory hx = this.wp.getWorkflowAccessor()
.getProcessHistory(requestedProcessId)
.last();
final ProcessHistory entry = new ProcessHistory(requestedProcessId,
userId,
new Date().getTime(),
SEND_TO_APPROVAL_STATE,
SEND_TO_APPROVAL_ACTION,
SEND_TO_APPROVAL_OUTCOME,
SEND_TO_APPROVAL_COMMENT,
hx.getHistorySequence() + 1);
this.wp.getProcessHistoryStore()
.add(entry);
} catch (final InterruptedException e) {
throw new RuntimeException(e);
}
}
/**
* Execute send for review advancement.
*
* @param processId the process id
*/
protected void executeSendForReviewAdvancement(UUID processId) {
final ProcessDetail entry = this.wp.getProcessDetailStore()
.get(processId);
try {
Thread.sleep(1);
final ProcessHistory hx = this.wp.getWorkflowAccessor()
.getProcessHistory(processId)
.last();
final ProcessHistory advanceEntry = new ProcessHistory(processId,
entry.getCreatorId(),
new Date().getTime(),
LAUNCH_STATE,
LAUNCH_ACTION,
LAUNCH_OUTCOME,
LAUNCH_COMMENT,
hx.getHistorySequence() + 1);
this.wp.getProcessHistoryStore()
.add(advanceEntry);
} catch (final InterruptedException e) {
throw new RuntimeException(e);
}
}
/**
* Clear stores.
*/
private void clearStores() {
this.wp.getProcessDetailStore()
.clear();
this.wp.getProcessHistoryStore()
.clear();
}
/**
* Clone version.
*
* @param semChron the sem chron
* @param state the state
* @return the description sememe impl
* @throws InterruptedException the interrupted exception
* @throws ExecutionException the execution exception
*/
private DescriptionSememeImpl cloneVersion(SememeChronologyImpl semChron,
State state)
throws InterruptedException,
ExecutionException {
final DescriptionSememe<?> latestVersion =
((LatestVersion<DescriptionSememe<?>>) semChron.getLatestVersion(DescriptionSememe.class,
Get.configurationService()
.getDefaultStampCoordinate())
.get()).value();
final DescriptionSememeImpl createdVersion =
(DescriptionSememeImpl) semChron.createMutableVersion(DescriptionSememeImpl.class,
state,
this.defaultEditCoordinate);
createdVersion.setCaseSignificanceConceptSequence(latestVersion.getCaseSignificanceConceptSequence());
createdVersion.setDescriptionTypeConceptSequence((latestVersion.getDescriptionTypeConceptSequence()));
createdVersion.setLanguageConceptSequence(latestVersion.getLanguageConceptSequence());
createdVersion.setText(latestVersion.getText());
return createdVersion;
}
/**
* Creates the new version.
*
* @param conNid the con nid
* @param semNid the sem nid
* @return the optional
* @throws InterruptedException the interrupted exception
* @throws ExecutionException the execution exception
*/
private Optional<CommitRecord> createNewVersion(Integer conNid,
Integer semNid)
throws InterruptedException,
ExecutionException {
if (conNid != null) {
final ConceptChronologyImpl con = (ConceptChronologyImpl) Get.conceptService()
.getConcept(conNid);
con.createMutableVersion(State.ACTIVE, this.defaultEditCoordinate);
Get.commitService()
.addUncommitted(con)
.get();
return Get.commitService()
.commit("Inactivating concept for Testing")
.get();
} else {
final SememeChronologyImpl semChron = (SememeChronologyImpl) Get.sememeService()
.getSememe(semNid);
final DescriptionSememeImpl createdVersion = cloneVersion(semChron, State.ACTIVE);
Get.commitService()
.addUncommitted(semChron)
.get();
return Get.commitService()
.commit("Inactivating sememe for Testing")
.get();
}
}
/**
* Creates the stamp.
*
* @param userSeq the user seq
* @param state the state
* @return the stamp
*/
private Stamp createStamp(int userSeq, State state) {
if ((this.moduleSeq < 0) || (this.pathSeq < 0)) {
if (Get.configurationService()
.getDefaultStampCoordinate()
.getModuleSequences()
.size() != 1) {
return null;
}
this.moduleSeq = Get.configurationService()
.getDefaultStampCoordinate()
.getModuleSequences()
.getIntIterator()
.nextInt();
this.pathSeq = Get.configurationService()
.getDefaultStampCoordinate()
.getStampPosition()
.getStampPathSequence();
}
return new Stamp(state, new Date().getTime(), this.moduleSeq, userSeq, this.pathSeq);
}
/**
* Creates the stamp from commit record.
*
* @param commitRecord the commit record
* @return the stamp
*/
private Stamp createStampFromCommitRecord(Optional<CommitRecord> commitRecord) {
final int stampSeq = commitRecord.get()
.getStampsInCommit()
.getIntIterator()
.next();
final State status = Get.stampService()
.getStatusForStamp(stampSeq);
final long time = Get.stampService()
.getTimeForStamp(stampSeq);
final int author = Get.stampService()
.getAuthorSequenceForStamp(stampSeq);
final int module = Get.stampService()
.getModuleSequenceForStamp(stampSeq);
final int path = Get.stampService()
.getPathSequenceForStamp(stampSeq);
return new Stamp(status, time, author, module, path);
}
/**
* Creates the workflow process.
*
* @param requestedDefinitionId the requested definition id
* @param name the name
* @param description the description
* @return the uuid
*/
private UUID createWorkflowProcess(UUID requestedDefinitionId, String name, String description) {
final AvailableAction startNodeAction = this.wp.getBPMNInfo()
.getDefinitionStartActionMap()
.get(this.wp.getBPMNInfo()
.getDefinitionId())
.iterator()
.next();
// Mimick the wp.getWorkflowProcessInitializerConcluder()'s create new
// process
final ProcessDetail details = new ProcessDetail(requestedDefinitionId,
userId,
new Date().getTime(),
ProcessStatus.DEFINED,
name,
description);
final UUID processId = this.wp.getProcessDetailStore()
.add(details);
// Add Process History with START_STATE-AUTOMATED-EDIT_STATE
final AvailableAction startAdvancement = new AvailableAction(requestedDefinitionId,
startNodeAction.getInitialState(),
startNodeAction.getAction(),
startNodeAction.getOutcomeState(),
UserRole.AUTOMATED);
final ProcessHistory advanceEntry = new ProcessHistory(processId,
userId,
new Date().getTime(),
startAdvancement.getInitialState(),
startAdvancement.getAction(),
startAdvancement.getOutcomeState(),
"",
1);
this.wp.getProcessHistoryStore()
.add(advanceEntry);
return processId;
}
/**
* Finish workflow process.
*
* @param processId the process id
* @param actionToProcess the action to process
* @param userId the user id
* @param comment the comment
* @param endType the end type
* @throws Exception the exception
*/
private void finishWorkflowProcess(UUID processId,
AvailableAction actionToProcess,
UUID userId,
String comment,
EndWorkflowType endType)
throws Exception {
// Mimick the wp.getWorkflowProcessInitializerConcluder()'s finish
// workflow process
final ProcessDetail entry = this.wp.getProcessDetailStore()
.get(processId);
if (endType.equals(EndWorkflowType.CANCELED)) {
entry.setStatus(ProcessStatus.CANCELED);
} else if (endType.equals(EndWorkflowType.CONCLUDED)) {
entry.setStatus(ProcessStatus.CONCLUDED);
}
entry.setTimeCanceledOrConcluded(new Date().getTime());
this.wp.getProcessDetailStore()
.put(processId, entry);
// Only add Cancel state in Workflow if process has already been
// launched
final ProcessHistory hx = this.wp.getWorkflowAccessor()
.getProcessHistory(processId)
.last();
final ProcessHistory advanceEntry = new ProcessHistory(processId,
userId,
new Date().getTime(),
actionToProcess.getInitialState(),
actionToProcess.getAction(),
actionToProcess.getOutcomeState(),
comment,
hx.getHistorySequence() + 1);
this.wp.getProcessHistoryStore()
.add(advanceEntry);
if (endType.equals(EndWorkflowType.CANCELED)) {
// TODO: Handle cancelation store and handle reverting automatically
}
}
/**
* Verify state.
*
* @param con the con
* @param descSem the desc sem
* @param state the state
*/
private void verifyState(ConceptChronology<? extends ConceptVersion<?>> con,
SememeChronology<? extends DescriptionSememe<?>> descSem,
State state) {
final ConceptChronology<? extends ConceptVersion<?>> cc = Get.conceptService()
.getConcept(con.getNid());
final Optional<LatestVersion<ConceptVersion>> latestConVersion =
((ConceptChronology) cc).getLatestVersion(ConceptVersion.class,
this.defaultStampCoordinate);
Assert.assertEquals(latestConVersion.get()
.value()
.getState(), state);
final SememeChronology<? extends SememeVersion<?>> semChron = Get.sememeService()
.getSememe(descSem.getNid());
final Optional<LatestVersion<DescriptionSememe<?>>> latestDescVersion =
((SememeChronology) semChron).getLatestVersion(DescriptionSememe.class,
this.defaultStampCoordinate);
Assert.assertEquals(latestDescVersion.get()
.value()
.getState(), state);
}
//~--- get methods ---------------------------------------------------------
/**
* Gets the cancel action.
*
* @return the cancel action
*/
private AvailableAction getCancelAction() {
return this.wp.getBPMNInfo()
.getEndWorkflowTypeMap()
.get(EndWorkflowType.CANCELED)
.iterator()
.next();
}
/**
* Gets the conclude action.
*
* @return the conclude action
*/
private AvailableAction getConcludeAction() {
return this.wp.getBPMNInfo()
.getEndWorkflowTypeMap()
.get(EndWorkflowType.CONCLUDED)
.iterator()
.next();
}
/**
* Checks if end state.
*
* @param state the state
* @param type the type
* @return true, if end state
*/
private boolean isEndState(String state, EndWorkflowType type) {
for (final AvailableAction action: this.wp.getBPMNInfo()
.getEndWorkflowTypeMap()
.get(type)) {
if (action.getOutcomeState()
.equals(state)) {
return true;
}
}
return false;
}
/**
* Checks if start state.
*
* @param defId the def id
* @param state the state
* @return true, if start state
*/
private boolean isStartState(UUID defId, String state) {
for (final AvailableAction action: this.wp.getBPMNInfo()
.getDefinitionStartActionMap()
.get(defId)) {
if (action.getInitialState()
.equals(state)) {
return true;
}
}
return false;
}
//~--- set methods ---------------------------------------------------------
/**
* Set up users.
*
* @throws Exception the exception
*/
@BeforeGroups(groups = { "wf" })
public void setUpUsers()
throws Exception {
userId = UUID.randomUUID();
final SimpleUserRoleService rolesService = LookupService.get()
.getService(SimpleUserRoleService.class);
rolesService.addRole(UserRole.EDITOR);
rolesService.addRole(UserRole.REVIEWER);
rolesService.addRole(UserRole.APPROVER);
rolesService.addRole(UserRole.AUTOMATED);
final HashSet<UserRole> roles = new HashSet<>();
roles.add(UserRole.EDITOR);
roles.add(UserRole.APPROVER);
roles.add(UserRole.REVIEWER);
rolesService.addUser(userId, roles);
}
}