1
2
3
4
5
6
7
8
9
10
11 package org.mule.component;
12
13 import org.mule.api.component.LifecycleAdapter;
14 import org.mule.api.lifecycle.InitialisationException;
15 import org.mule.api.object.ObjectFactory;
16 import org.mule.config.PoolingProfile;
17 import org.mule.object.PrototypeObjectFactory;
18 import org.mule.tck.services.UniqueComponent;
19 import org.mule.tck.testmodels.fruit.Orange;
20 import org.mule.tck.testmodels.fruit.WaterMelon;
21 import org.mule.util.ExceptionUtils;
22 import org.mule.util.pool.AbstractPoolingTestCase;
23
24 import java.util.NoSuchElementException;
25
26 public class PooledJavaComponentTestCase extends AbstractPoolingTestCase
27 {
28 public void testComponentCreation() throws Exception
29 {
30 PrototypeObjectFactory objectFactory = getDefaultObjectFactory();
31
32 PoolingProfile pp = createDefaultPoolingProfile();
33 pp.setExhaustedAction(PoolingProfile.WHEN_EXHAUSTED_FAIL);
34
35 PooledJavaComponent component = new PooledJavaComponent(objectFactory, pp);
36 component.setMuleContext(muleContext);
37 assertNotNull(component.getObjectFactory());
38 assertEquals(objectFactory, component.getObjectFactory());
39 assertEquals(Orange.class, component.getObjectType());
40
41 assertNotNull(component.getPoolingProfile());
42 assertEquals(pp, component.getPoolingProfile());
43 }
44
45 public void testPoolManagement() throws Exception
46 {
47 PooledJavaComponent component = new PooledJavaComponent(getDefaultObjectFactory(), createDefaultPoolingProfile());
48 assertNull(component.lifecycleAdapterPool);
49
50 component.setFlowConstruct(getTestService());
51 component.setMuleContext(muleContext);
52 component.initialise();
53 assertNull(component.lifecycleAdapterPool);
54
55 component.start();
56 assertNotNull(component.lifecycleAdapterPool);
57
58 component.stop();
59 assertNull(component.lifecycleAdapterPool);
60 }
61
62 public void testStartStop() throws Exception
63 {
64 PooledJavaComponent component = createPooledComponent();
65 assertNotSame(component.borrowComponentLifecycleAdaptor(), component.borrowComponentLifecycleAdaptor());
66
67 component.stop();
68 component.start();
69
70 Object la1 = ((DefaultComponentLifecycleAdapter) component.borrowComponentLifecycleAdaptor()).componentObject;
71 Object la2 = ((DefaultComponentLifecycleAdapter) component.borrowComponentLifecycleAdaptor()).componentObject;
72 assertNotSame(la1, la2);
73 }
74
75 public void testCreateLifecycleAdapters() throws Exception
76 {
77 PooledJavaComponent component = createPooledComponent();
78 assertEquals(0, component.lifecycleAdapterPool.getNumActive());
79
80 LifecycleAdapter borrowed = component.borrowComponentLifecycleAdaptor();
81 assertNotNull(borrowed);
82 assertEquals(1, component.lifecycleAdapterPool.getNumActive());
83
84 component.returnComponentLifecycleAdaptor(borrowed);
85 assertEquals(0, component.lifecycleAdapterPool.getNumActive());
86
87 borrowed = component.borrowComponentLifecycleAdaptor();
88 assertNotNull(borrowed);
89 assertEquals(1, component.lifecycleAdapterPool.getNumActive());
90
91 Object borrowed2 = component.borrowComponentLifecycleAdaptor();
92 assertNotNull(borrowed2);
93 assertEquals(2, component.lifecycleAdapterPool.getNumActive());
94 }
95
96 public void testFailOnExhaust() throws Exception
97 {
98 PoolingProfile pp = createDefaultPoolingProfile();
99 pp.setExhaustedAction(PoolingProfile.WHEN_EXHAUSTED_FAIL);
100
101 PooledJavaComponent component = createPooledComponent(pp);
102 borrowLifecycleAdaptersUntilPoolIsFull(component);
103
104 try
105 {
106 component.borrowComponentLifecycleAdaptor();
107 fail("Should throw an Exception");
108 }
109 catch (NoSuchElementException nse)
110 {
111
112 }
113 }
114
115 public void testBlockExpiryOnExhaust() throws Exception
116 {
117 PoolingProfile pp = createDefaultPoolingProfile();
118 pp.setExhaustedAction(PoolingProfile.WHEN_EXHAUSTED_WAIT);
119
120 PooledJavaComponent component = createPooledComponent(pp);
121 assertEquals(0, component.lifecycleAdapterPool.getNumActive());
122
123 borrowLifecycleAdaptersUntilPoolIsFull(component);
124
125 long startTime = System.currentTimeMillis();
126 try
127 {
128 component.borrowComponentLifecycleAdaptor();
129 fail("Should throw an Exception");
130 }
131 catch (NoSuchElementException e)
132 {
133 long totalTime = System.currentTimeMillis() - startTime;
134 assertTrue(totalTime >= MAX_WAIT);
135 }
136 }
137
138 public void testBlockOnExhaust() throws Exception
139 {
140 PoolingProfile pp = createDefaultPoolingProfile();
141 pp.setExhaustedAction(PoolingProfile.WHEN_EXHAUSTED_WAIT);
142
143 PooledJavaComponent component = createPooledComponent(pp);
144 assertEquals(0, component.lifecycleAdapterPool.getNumActive());
145
146
147 int oneRemainingInPool = (MAX_ACTIVE - 1);
148 for (int i = 0; i < oneRemainingInPool; i++)
149 {
150 LifecycleAdapter borrowed = component.borrowComponentLifecycleAdaptor();
151 assertNotNull(borrowed);
152 assertEquals(component.lifecycleAdapterPool.getNumActive(), i + 1);
153 }
154 assertEquals(oneRemainingInPool, component.lifecycleAdapterPool.getNumActive());
155
156 long startTime = System.currentTimeMillis();
157 int borrowerWait = 500;
158 Borrower borrower = new Borrower(component, borrowerWait);
159 new Thread(borrower, "BorrowThread").start();
160
161
162 try
163 {
164 Thread.sleep(200);
165 }
166 catch (InterruptedException e)
167 {
168
169 }
170
171
172 Object borrowed = component.borrowComponentLifecycleAdaptor();
173 assertNotNull(borrowed);
174 long totalTime = System.currentTimeMillis() - startTime;
175 assertTrue(totalTime >= borrowerWait);
176 }
177
178 public void testGrowOnExhaust() throws Exception
179 {
180 PoolingProfile pp = createDefaultPoolingProfile();
181 pp.setExhaustedAction(PoolingProfile.WHEN_EXHAUSTED_GROW);
182
183 PooledJavaComponent component = createPooledComponent(pp);
184
185 borrowLifecycleAdaptersUntilPoolIsFull(component);
186
187
188 Object borrowed = component.borrowComponentLifecycleAdaptor();
189 assertNotNull(borrowed);
190 assertEquals(MAX_ACTIVE + 1, component.lifecycleAdapterPool.getNumActive());
191 }
192
193 public void testClearPool() throws Exception
194 {
195 PoolingProfile pp = createDefaultPoolingProfile();
196 pp.setExhaustedAction(PoolingProfile.WHEN_EXHAUSTED_FAIL);
197
198 PooledJavaComponent component = createPooledComponent(pp);
199
200 LifecycleAdapter borrowed = component.borrowComponentLifecycleAdaptor();
201 assertEquals(1, component.lifecycleAdapterPool.getNumActive());
202 component.returnComponentLifecycleAdaptor(borrowed);
203 assertEquals(0, component.lifecycleAdapterPool.getNumActive());
204
205 component.stop();
206 component.start();
207 assertEquals(0, component.lifecycleAdapterPool.getNumActive());
208 }
209
210 public void testObjectUniqueness() throws Exception
211 {
212 PrototypeObjectFactory objectFactory = new PrototypeObjectFactory(UniqueComponent.class);
213 PooledJavaComponent component = createPooledComponent(objectFactory);
214 assertEquals(0, component.lifecycleAdapterPool.getNumActive());
215
216 String id1 = getIdFromObjectCreatedByPool(component);
217 String id2 = getIdFromObjectCreatedByPool(component);
218 String id3 = getIdFromObjectCreatedByPool(component);
219
220 assertFalse("Service IDs " + id1 + " and " + id2 + " should be different", id1.equals(id2));
221 assertFalse("Service IDs " + id2 + " and " + id3 + " should be different", id2.equals(id3));
222 assertFalse("Service IDs " + id1 + " and " + id3 + " should be different", id1.equals(id3));
223 }
224
225 public void testDisposingFactoryDisposesObject() throws Exception
226 {
227 PrototypeObjectFactory objectFactory = new PrototypeObjectFactory(WaterMelon.class);
228 PooledJavaComponent component = createPooledComponent(objectFactory);
229
230 DefaultComponentLifecycleAdapter lifecycleAdapter = (DefaultComponentLifecycleAdapter) component.borrowComponentLifecycleAdaptor();
231 component.returnComponentLifecycleAdaptor(lifecycleAdapter);
232 component.stop();
233 component.dispose();
234
235 assertNull(lifecycleAdapter.componentObject);
236 }
237
238 private PrototypeObjectFactory getDefaultObjectFactory() throws InitialisationException
239 {
240 PrototypeObjectFactory objectFactory = new PrototypeObjectFactory(Orange.class);
241 objectFactory.initialise();
242 return objectFactory;
243 }
244
245 private PooledJavaComponent createPooledComponent() throws Exception
246 {
247 return createPooledComponent(createDefaultPoolingProfile(), getDefaultObjectFactory());
248 }
249
250 private PooledJavaComponent createPooledComponent(ObjectFactory objectFactory) throws Exception
251 {
252 return createPooledComponent(createDefaultPoolingProfile(), objectFactory);
253 }
254
255 private PooledJavaComponent createPooledComponent(PoolingProfile poolingProfile) throws Exception
256 {
257 return createPooledComponent(poolingProfile, getDefaultObjectFactory());
258 }
259
260 private PooledJavaComponent createPooledComponent(PoolingProfile poolingProfile, ObjectFactory objectFactory) throws Exception
261 {
262 PooledJavaComponent component = new PooledJavaComponent(objectFactory, poolingProfile);
263 component.setMuleContext(muleContext);
264 component.setFlowConstruct(getTestService());
265 component.initialise();
266 component.start();
267 return component;
268 }
269
270 private void borrowLifecycleAdaptersUntilPoolIsFull(PooledJavaComponent component) throws Exception
271 {
272 for (int i = 0; i < MAX_ACTIVE; i++)
273 {
274 Object borrowed = component.borrowComponentLifecycleAdaptor();
275 assertNotNull(borrowed);
276 assertEquals(component.lifecycleAdapterPool.getNumActive(), i + 1);
277 }
278 assertEquals(MAX_ACTIVE, component.lifecycleAdapterPool.getNumActive());
279 }
280
281 private String getIdFromObjectCreatedByPool(PooledJavaComponent component) throws Exception
282 {
283 DefaultComponentLifecycleAdapter lifecycleAdapter =
284 (DefaultComponentLifecycleAdapter) component.borrowComponentLifecycleAdaptor();
285 Object obj = lifecycleAdapter.componentObject;
286
287
288
289 assertNotNull(obj);
290
291 assertTrue("Object should be of type UniqueComponent", obj instanceof UniqueComponent);
292
293 String id = ((UniqueComponent) obj).getId();
294 assertNotNull(id);
295 return id;
296 }
297
298 private static class Borrower implements Runnable
299 {
300 private PooledJavaComponent component;
301 private long time;
302
303 public Borrower(PooledJavaComponent component, long time)
304 {
305 super();
306 if (component == null)
307 {
308 throw new IllegalArgumentException("Pool cannot be null");
309 }
310 this.component = component;
311 if (time < 500)
312 {
313 time = 500;
314 }
315 this.time = time;
316 }
317
318 public void run()
319 {
320 try
321 {
322 LifecycleAdapter object = component.borrowComponentLifecycleAdaptor();
323 try
324 {
325 Thread.sleep(time);
326 }
327 catch (InterruptedException e)
328 {
329
330 }
331 component.returnComponentLifecycleAdaptor(object);
332 }
333 catch (Exception e)
334 {
335 fail("Borrower thread failed:\n" + ExceptionUtils.getStackTrace(e));
336 }
337 }
338 }
339 }