KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tctest > spring > integrationtests > tests > CustomScopedBeanTest


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tctest.spring.integrationtests.tests;
5
6 import org.apache.commons.httpclient.HostConfiguration;
7 import org.apache.commons.httpclient.HttpClient;
8 import org.apache.commons.httpclient.HttpException;
9 import org.apache.commons.httpclient.HttpMethod;
10 import org.apache.commons.httpclient.HttpState;
11 import org.springframework.beans.factory.BeanFactory;
12 import org.springframework.beans.factory.BeanFactoryAware;
13 import org.springframework.beans.factory.ObjectFactory;
14 import org.springframework.beans.factory.config.Scope;
15 import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
16 import org.springframework.web.context.request.HttpRequestAccessor;
17 import org.springframework.web.context.request.RequestAttributes;
18 import org.springframework.web.context.request.RequestContextHolder;
19 import org.springframework.web.context.request.ServletRequestAttributes;
20 import org.springframework.web.context.request.SessionScope;
21 import org.springframework.web.servlet.DispatcherServlet;
22
23 import com.tc.test.TestConfigObject;
24 import com.tcspring.ComplexBeanId;
25 import com.tcspring.DistributableBeanFactory;
26 import com.tctest.spring.bean.ISimpleBean;
27 import com.tctest.spring.integrationtests.framework.AbstractTwoServerDeploymentTest;
28 import com.tctest.spring.integrationtests.framework.DeploymentBuilder;
29 import com.tctest.spring.integrationtests.framework.ProxyBuilder;
30
31 import java.io.IOException JavaDoc;
32 import java.util.Collections JavaDoc;
33 import java.util.HashMap JavaDoc;
34 import java.util.Iterator JavaDoc;
35 import java.util.Map JavaDoc;
36
37 import javax.servlet.http.HttpSessionBindingListener JavaDoc;
38
39 import junit.framework.Test;
40
41
42 /**
43  * Test clustering custom scoped bean. This custom scope is a subtype of SessionScope with finer granularity driven by
44  * CONVERSATION parameter of the http request
45  */

46 public class CustomScopedBeanTest extends AbstractTwoServerDeploymentTest {
47
48   private static final String JavaDoc FASADE_NAME = "TestFasadeService";
49   
50   private static ITestFacade beanN1C1; // node1 session1 conv1
51
private static ITestFacade beanN1C2; // node1 session1 conv2
52

53   private static ITestFacade beanN2C1; // node2 session1 conv1
54
private static ITestFacade beanN2C2; // node2 session1 conv2
55

56   
57   public CustomScopedBeanTest() {
58     this.disableVariant(TestConfigObject.SPRING_VARIANT, "128");
59   }
60   
61   public void testSharedFields() throws Exception JavaDoc {
62     beanN1C1.setField("newVal1");
63     beanN2C2.setField("newVal2");
64
65     assertEquals("Failed to share", "newVal1", beanN2C1.getField());
66     assertEquals("Failed to share", "newVal2", beanN1C2.getField());
67   }
68   
69   public void testScopeId() throws Exception JavaDoc {
70     String JavaDoc id11 = beanN1C1.getConversationId();
71     String JavaDoc id12 = beanN1C2.getConversationId();
72
73     String JavaDoc id21 = beanN2C1.getConversationId();
74     String JavaDoc id22 = beanN2C2.getConversationId();
75     
76     assertEquals("Unexpected scope", id11, id21);
77     assertEquals("Unexpected scope", id12, id22);
78   }
79
80   public void testDestructionCallbacks() throws Exception JavaDoc {
81     String JavaDoc conversationId11 = beanN1C1.getConversationId();
82     String JavaDoc conversationId21 = beanN1C2.getConversationId();
83     String JavaDoc conversationId12 = beanN2C1.getConversationId();
84     String JavaDoc conversationId22 = beanN2C2.getConversationId();
85
86     beanN1C1.setField("newVal11");
87     beanN1C2.setField("newVal12");
88     beanN2C1.setField("newVal21");
89     beanN2C2.setField("newVal22");
90     
91     assertTrue("Failed to create scoped bean", beanN1C1.isInClusteredSingletonCache(conversationId11));
92     assertTrue("Failed to create scoped bean", beanN1C2.isInClusteredSingletonCache(conversationId12));
93     assertTrue("Failed to create scoped bean", beanN2C1.isInClusteredSingletonCache(conversationId21));
94     assertTrue("Failed to create scoped bean", beanN2C2.isInClusteredSingletonCache(conversationId22));
95     
96     beanN1C1.invokeDestructionCallback();
97     beanN2C2.invokeDestructionCallback();
98         
99     assertFalse("Failed to destruct scoped bean", beanN1C1.isInClusteredSingletonCache(conversationId11));
100     assertFalse("Failed to destruct scoped bean", beanN1C2.isInClusteredSingletonCache(conversationId12));
101     assertFalse("Failed to destruct scoped bean", beanN2C1.isInClusteredSingletonCache(conversationId21));
102     assertFalse("Failed to destruct scoped bean", beanN2C2.isInClusteredSingletonCache(conversationId22));
103   }
104
105   public void testTransparentFields() throws Exception JavaDoc {
106     assertEquals("Failed to initialize transient field", "transient-val", beanN1C1.getTransientField());
107     assertEquals("Failed to initialize transient field", "transient-val", beanN1C2.getTransientField());
108     assertEquals("Failed to initialize transient field", "transient-val", beanN2C1.getTransientField());
109     assertEquals("Failed to initialize transient field", "transient-val", beanN2C2.getTransientField());
110     
111     beanN1C1.setTransientField("newVal11");
112     beanN1C2.setTransientField("newVal12");
113     beanN2C1.setTransientField("newVal21");
114     beanN2C2.setTransientField("newVal22");
115     
116     assertEquals("Unexpected sharing", "newVal11", beanN1C1.getTransientField());
117     assertEquals("Unexpected sharing", "newVal12", beanN1C2.getTransientField());
118     assertEquals("Unexpected sharing", "newVal21", beanN2C1.getTransientField());
119     assertEquals("Unexpected sharing", "newVal22", beanN2C2.getTransientField());
120   }
121
122   
123   private static class InnerTestSetup extends TwoSvrSetup {
124     private static final String JavaDoc APP_NAME = "test-customscope";
125
126     private InnerTestSetup() {
127       super(CustomScopedBeanTest.class, "/tc-config-files/customscoped-tc-config.xml", APP_NAME);
128     }
129
130     protected void setUp() throws Exception JavaDoc {
131       try {
132         super.setUp();
133         
134         Map JavaDoc initCtx = new HashMap JavaDoc();
135         initCtx.put(ProxyBuilder.EXPORTER_TYPE_KEY, HttpInvokerServiceExporter.class);
136         
137         HttpClient clientS1C1 = new HttpClientWithParams(Collections.singletonMap(ConversationScope.CONV_KEY, "(1)"));
138         initCtx.put(ProxyBuilder.HTTP_CLIENT_KEY, clientS1C1);
139         
140         beanN1C1 = (ITestFacade) server1.getProxy(ITestFacade.class, APP_NAME + "/http/" + FASADE_NAME, initCtx);
141         beanN2C1 = (ITestFacade) server2.getProxy(ITestFacade.class, APP_NAME + "/http/" + FASADE_NAME, initCtx);
142         
143         HttpClient clientS1C2 = new HttpClientWithParams(Collections.singletonMap(ConversationScope.CONV_KEY, "(2)"));
144         clientS1C2.setState(clientS1C1.getState()); // share state across the clients, they should be in the same session now
145
initCtx.put(ProxyBuilder.HTTP_CLIENT_KEY, clientS1C2);
146         
147         beanN1C2 = (ITestFacade) server1.getProxy(ITestFacade.class, APP_NAME + "/http/" + FASADE_NAME, initCtx);
148         beanN2C2 = (ITestFacade) server2.getProxy(ITestFacade.class, APP_NAME + "/http/" + FASADE_NAME, initCtx);
149       } catch (Exception JavaDoc e) {
150         e.printStackTrace();
151         throw e;
152       }
153     }
154
155     protected void configureWar(DeploymentBuilder builder) {
156       builder.addBeanDefinitionFile("classpath:/com/tctest/spring/beanfactory-customscope.xml");
157       
158       builder.addRemoteService(HttpInvokerServiceExporter.class, FASADE_NAME, "testFacade", ITestFacade.class);
159
160       builder.setDispatcherServlet("httpinvoker", "/http/*", DispatcherServlet.class, null, true);
161       builder.addDirectoryOrJARContainingClass(net.sf.cglib.core.Constants.class);
162     }
163   }
164
165
166   public static Test suite() {
167     return new InnerTestSetup();
168   }
169   
170   
171   /**
172    * Custom scope and client
173    */

174   public static class ConversationScope extends SessionScope implements Scope {
175     public static final String JavaDoc CONV_KEY = "CONVERSATION";
176     
177     public String JavaDoc getConversationId() {
178       String JavaDoc conversation = getWebConversationName();
179       return conversation == null ? null : super.getConversationId() + conversation;
180     }
181     
182     public Object JavaDoc get(String JavaDoc name, ObjectFactory objectFactory) {
183       return super.get(getWebConversationName() + name, objectFactory);
184     }
185     
186     public Object JavaDoc remove(String JavaDoc name) {
187       return super.remove(getWebConversationName() + name);
188     }
189
190     public void registerDestructionCallback(String JavaDoc name, Runnable JavaDoc callback) {
191       super.registerDestructionCallback(getWebConversationName() + name, callback);
192     }
193     
194     public Object JavaDoc getDestructionCallback(String JavaDoc name) {
195       return RequestContextHolder.currentRequestAttributes().getAttribute(
196           ServletRequestAttributes.DESTRUCTION_CALLBACK_NAME_PREFIX + getWebConversationName() + name,
197           RequestAttributes.SCOPE_SESSION);
198     }
199     
200     private String JavaDoc getWebConversationName() {
201       return HttpRequestAccessor.getRequest(
202            (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getParameter(CONV_KEY);
203     }
204   }
205   
206   
207   public static class HttpClientWithParams extends HttpClient {
208     private Map JavaDoc stickyParameters = null;
209
210     HttpClientWithParams(Map JavaDoc attributes) {
211       this.stickyParameters = attributes;
212     }
213
214     public int executeMethod(HostConfiguration hostconfig, final HttpMethod httpMethod, final HttpState state)
215         throws IOException JavaDoc, HttpException {
216       httpMethod.setQueryString(appendParams(httpMethod.getQueryString()));
217       return super.executeMethod(hostconfig, httpMethod, state);
218     }
219
220     private String JavaDoc appendParams(String JavaDoc queryStr) {
221       StringBuffer JavaDoc sb = new StringBuffer JavaDoc(queryStr == null ? "" : queryStr);
222       if (stickyParameters != null) {
223         for (Iterator JavaDoc iter = this.stickyParameters.entrySet().iterator(); iter.hasNext();) {
224           if (sb.length() > 0) {
225             sb.append('&');
226           }
227           Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iter.next();
228           sb.append(entry.getKey()).append('=').append(entry.getValue());
229         }
230       }
231       return sb.toString();
232     }
233   }
234   
235   
236   public static interface ITestFacade {
237     public String JavaDoc getConversationId();
238     public String JavaDoc getTransientField();
239     public void setTransientField(String JavaDoc string);
240     public String JavaDoc getField();
241     public void setField(String JavaDoc value);
242     public void invokeDestructionCallback();
243     public boolean isInClusteredSingletonCache(String JavaDoc conversationId);
244   }
245   
246   
247   public static class ConversationScopeTestFacade implements ITestFacade, BeanFactoryAware {
248     private BeanFactory factory;
249     private ConversationScope scope;
250     private ISimpleBean bean;
251     private String JavaDoc beanName;
252     
253     public void setBeanFactory(BeanFactory factory) {
254       this.factory = factory;
255     }
256     
257     public void setScope(ConversationScope scope) {
258       this.scope = scope;
259     }
260
261     public void setBean(ISimpleBean bean) {
262       this.bean = bean;
263     }
264     
265     public void setField(String JavaDoc value) {
266       bean.setField(value);
267     }
268     
269     public String JavaDoc getField() {
270       return bean.getField();
271     }
272     
273     public String JavaDoc getTransientField() {
274       return bean.getTransientField();
275     }
276     
277     public void setTransientField(String JavaDoc value) {
278       bean.setTransientField(value);
279     }
280     
281     public String JavaDoc getConversationId() {
282       return scope.getConversationId();
283     }
284     
285     public void invokeDestructionCallback() {
286       System.err.println("#### ConversationScopeTestFacade.invokeDestructionCallback() " + getBeanName());
287       HttpSessionBindingListener JavaDoc listener = (HttpSessionBindingListener JavaDoc) scope.getDestructionCallback(getBeanName());
288       listener.valueUnbound(null); // cause unbound
289
}
290     
291     public boolean isInClusteredSingletonCache(String JavaDoc conversationId) {
292       ComplexBeanId beanId = new ComplexBeanId(conversationId, getBeanName());
293       boolean res = ((DistributableBeanFactory) factory).getBeanContainer(beanId) != null;
294       System.err.println("#### ConversationScopeTestFacade.isInClusteredSingletonCache() " + beanId + " " + res);
295       return res;
296     }
297
298     private String JavaDoc getBeanName() {
299       if(beanName==null) {
300         beanName = bean.getBeanName();
301       }
302       return beanName;
303     }
304
305   }
306   
307 }
308
Popular Tags