1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.routeheader;
17
18
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNotNull;
21 import static org.junit.Assert.assertTrue;
22 import static org.junit.Assert.fail;
23
24 import java.sql.Timestamp;
25
26 import org.junit.Test;
27 import org.kuali.rice.core.api.config.property.Config;
28 import org.kuali.rice.core.api.config.property.ConfigContext;
29 import org.kuali.rice.kew.api.WorkflowDocument;
30 import org.kuali.rice.kew.api.WorkflowDocumentFactory;
31 import org.kuali.rice.kew.api.exception.LockingException;
32 import org.kuali.rice.kew.doctype.bo.DocumentType;
33 import org.kuali.rice.kew.routeheader.service.RouteHeaderService;
34 import org.kuali.rice.kew.service.KEWServiceLocator;
35 import org.kuali.rice.kew.test.KEWTestCase;
36 import org.kuali.rice.kew.api.KewApiConstants;
37 import org.kuali.rice.test.BaselineTestCase;
38 import org.springframework.transaction.TransactionStatus;
39 import org.springframework.transaction.support.TransactionCallback;
40
41
42 @BaselineTestCase.BaselineMode(BaselineTestCase.Mode.NONE)
43 public class RouteHeaderServiceTest extends KEWTestCase {
44
45 private Object lock = new Object();
46 private RouteHeaderService routeHeaderService;
47
48 protected void setUpAfterDataLoad() throws Exception {
49 super.setUpAfterDataLoad();
50 routeHeaderService = KEWServiceLocator.getRouteHeaderService();
51 }
52
53
54
55
56
57
58
59 @Test
60 public void testLargeDocumentContent() throws Exception {
61 StringBuffer buffer = new StringBuffer();
62 buffer.append("<content>");
63 for (int index = 0; index < 10000; index++) {
64 buffer.append("abcdefghijklmnopqrstuvwxyz");
65 }
66 buffer.append("</content>");
67 DocumentRouteHeaderValue document = new DocumentRouteHeaderValue();
68 document.setDocContent(buffer.toString());
69 document.setDocRouteStatus(KewApiConstants.ROUTE_HEADER_INITIATED_CD);
70 document.setDocRouteLevel(0);
71 document.setStatusModDate(new Timestamp(System.currentTimeMillis()));
72 document.setCreateDate(new Timestamp(System.currentTimeMillis()));
73 document.setInitiatorWorkflowId("1");
74 DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName("TestDocumentType");
75 assertNotNull(documentType);
76 document.setDocumentTypeId(documentType.getDocumentTypeId());
77 routeHeaderService.saveRouteHeader(document);
78 assertNotNull("Document was saved, it should have an ID now.", document.getDocumentId());
79
80
81 document = routeHeaderService.getRouteHeader(document.getDocumentId());
82 String docContent = document.getDocContent();
83 assertEquals("Doc content should be the same size as original string buffer.", buffer.length(), docContent.length());
84 assertTrue("Should be greater than about 5000 bytes.", docContent.getBytes().length > 5000);
85 }
86
87 @Test public void testGetApplicationIdByDocumentId() throws Exception {
88 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "TestDocumentType2");
89 String documentId = document.getDocumentId();
90 String applicationId = routeHeaderService.getApplicationIdByDocumentId(documentId);
91 assertEquals("applicationId should be KEWNEW", "KEWNEW", applicationId);
92
93
94 document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "TestDocumentType");
95 documentId = document.getDocumentId();
96 applicationId = routeHeaderService.getApplicationIdByDocumentId(documentId);
97 assertEquals("applicationId should be KEW", "KEW", applicationId);
98 }
99
100 @Test public void testLockRouteHeader() throws Exception {
101
102 if (ConfigContext.getCurrentContextConfig().getProperty("datasource.ojb.platform").equals("Mckoi")) {
103 return;
104 }
105
106 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("rkirkend"), "TestDocumentType");
107 document.saveDocumentData();
108 final String documentId = document.getDocumentId();
109 Locker locker = null;
110 synchronized (lock) {
111 locker = new Locker(documentId);
112 locker.start();
113 lock.wait();
114 }
115
116 try {
117 routeHeaderService.lockRouteHeader(documentId, false);
118 fail("The route header should be locked.");
119 } catch (LockingException e) {
120
121 }
122 synchronized (lock) {
123 lock.notify();
124 }
125 locker.join();
126
127 routeHeaderService.lockRouteHeader(documentId, false);
128 assertTrue("Locker thread should have completed.", locker.isCompleted());
129
130
131 ConfigContext.getCurrentContextConfig().putProperty(Config.DOCUMENT_LOCK_TIMEOUT, "2");
132 synchronized (lock) {
133 locker = new Locker(documentId);
134 locker.start();
135 lock.wait();
136 }
137
138 long millisStart = System.currentTimeMillis();
139 try {
140 routeHeaderService.lockRouteHeader(documentId, true);
141 fail("The route header should be locked.");
142 } catch (LockingException e) {
143
144 }
145
146 long millisEnd = System.currentTimeMillis();
147 long timeLocked = (millisEnd - millisStart);
148
149 synchronized(lock) {
150 lock.notify();
151 }
152 locker.join();
153
154
155
156
157
158 routeHeaderService.lockRouteHeader(document.getDocumentId(), false);
159 assertTrue("Locker thread should have completed.", locker.isCompleted());
160 }
161
162 private class Locker extends Thread {
163 private String documentId;
164 private boolean isCompleted = false;
165 public Locker(String documentId) {
166 this.documentId = documentId;
167 }
168 public void run() {
169 getTransactionTemplate().execute(new TransactionCallback() {
170 public Object doInTransaction(TransactionStatus status) {
171 synchronized (lock) {
172 routeHeaderService.lockRouteHeader(documentId, true);
173 try {
174 lock.notify();
175 lock.wait();
176 } catch (InterruptedException e) {
177 fail("Shouldn't have been interrupted");
178 }
179 }
180 return null;
181 }
182 });
183 isCompleted = true;
184 }
185 public boolean isCompleted() {
186 return isCompleted;
187 }
188 }
189
190 }