1 16 17 package org.springframework.remoting.httpinvoker; 18 19 import java.io.ByteArrayInputStream ; 20 import java.io.ByteArrayOutputStream ; 21 import java.io.IOException ; 22 import java.io.InputStream ; 23 import java.io.ObjectInputStream ; 24 import java.io.ObjectOutputStream ; 25 import java.io.OutputStream ; 26 import java.io.Serializable ; 27 import java.lang.reflect.InvocationTargetException ; 28 import java.util.zip.GZIPInputStream ; 29 import java.util.zip.GZIPOutputStream ; 30 31 import javax.servlet.http.HttpServletRequest ; 32 import javax.servlet.http.HttpServletResponse ; 33 34 import junit.framework.TestCase; 35 import org.aopalliance.intercept.MethodInvocation; 36 37 import org.springframework.beans.ITestBean; 38 import org.springframework.beans.TestBean; 39 import org.springframework.mock.web.MockHttpServletRequest; 40 import org.springframework.mock.web.MockHttpServletResponse; 41 import org.springframework.remoting.RemoteAccessException; 42 import org.springframework.remoting.support.DefaultRemoteInvocationExecutor; 43 import org.springframework.remoting.support.RemoteInvocation; 44 import org.springframework.remoting.support.RemoteInvocationFactory; 45 import org.springframework.remoting.support.RemoteInvocationResult; 46 47 51 public class HttpInvokerTests extends TestCase { 52 53 public void testHttpInvokerProxyFactoryBeanAndServiceExporter() throws Throwable { 54 TestBean target = new TestBean("myname", 99); 55 56 final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter(); 57 exporter.setServiceInterface(ITestBean.class); 58 exporter.setService(target); 59 exporter.afterPropertiesSet(); 60 61 HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean(); 62 pfb.setServiceInterface(ITestBean.class); 63 pfb.setServiceUrl("http://myurl"); 64 65 pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() { 66 protected RemoteInvocationResult doExecuteRequest( 67 HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) 68 throws IOException , ClassNotFoundException { 69 assertEquals("http://myurl", config.getServiceUrl()); 70 MockHttpServletRequest request = new MockHttpServletRequest(); 71 MockHttpServletResponse response = new MockHttpServletResponse(); 72 request.setContent(baos.toByteArray()); 73 exporter.handleRequest(request, response); 74 return readRemoteInvocationResult( 75 new ByteArrayInputStream (response.getContentAsByteArray()), config.getCodebaseUrl()); 76 } 77 }); 78 79 pfb.afterPropertiesSet(); 80 ITestBean proxy = (ITestBean) pfb.getObject(); 81 assertEquals("myname", proxy.getName()); 82 assertEquals(99, proxy.getAge()); 83 proxy.setAge(50); 84 assertEquals(50, proxy.getAge()); 85 86 try { 87 proxy.exceptional(new IllegalStateException ()); 88 fail("Should have thrown IllegalStateException"); 89 } 90 catch (IllegalStateException ex) { 91 } 93 try { 94 proxy.exceptional(new IllegalAccessException ()); 95 fail("Should have thrown IllegalAccessException"); 96 } 97 catch (IllegalAccessException ex) { 98 } 100 } 101 102 public void testHttpInvokerProxyFactoryBeanAndServiceExporterWithIOException() throws Exception { 103 TestBean target = new TestBean("myname", 99); 104 105 final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter(); 106 exporter.setServiceInterface(ITestBean.class); 107 exporter.setService(target); 108 exporter.afterPropertiesSet(); 109 110 HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean(); 111 pfb.setServiceInterface(ITestBean.class); 112 pfb.setServiceUrl("http://myurl"); 113 114 pfb.setHttpInvokerRequestExecutor(new HttpInvokerRequestExecutor() { 115 public RemoteInvocationResult executeRequest( 116 HttpInvokerClientConfiguration config, RemoteInvocation invocation) throws IOException { 117 throw new IOException ("argh"); 118 } 119 }); 120 121 pfb.afterPropertiesSet(); 122 ITestBean proxy = (ITestBean) pfb.getObject(); 123 try { 124 proxy.setAge(50); 125 fail("Should have thrown RemoteAccessException"); 126 } 127 catch (RemoteAccessException ex) { 128 assertTrue(ex.getCause() instanceof IOException ); 130 } 131 } 132 133 public void testHttpInvokerProxyFactoryBeanAndServiceExporterWithGzipCompression() throws Throwable { 134 TestBean target = new TestBean("myname", 99); 135 136 final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter() { 137 protected InputStream decorateInputStream(HttpServletRequest request, InputStream is) throws IOException { 138 if ("gzip".equals(request.getHeader("Compression"))) { 139 return new GZIPInputStream (is); 140 } 141 else { 142 return is; 143 } 144 } 145 protected OutputStream decorateOutputStream( 146 HttpServletRequest request, HttpServletResponse response, OutputStream os) throws IOException { 147 if ("gzip".equals(request.getHeader("Compression"))) { 148 return new GZIPOutputStream (os); 149 } 150 else { 151 return os; 152 } 153 } 154 }; 155 exporter.setServiceInterface(ITestBean.class); 156 exporter.setService(target); 157 exporter.afterPropertiesSet(); 158 159 HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean(); 160 pfb.setServiceInterface(ITestBean.class); 161 pfb.setServiceUrl("http://myurl"); 162 163 pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() { 164 protected RemoteInvocationResult doExecuteRequest( 165 HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) 166 throws IOException , ClassNotFoundException { 167 assertEquals("http://myurl", config.getServiceUrl()); 168 MockHttpServletRequest request = new MockHttpServletRequest(); 169 request.addHeader("Compression", "gzip"); 170 MockHttpServletResponse response = new MockHttpServletResponse(); 171 request.setContent(baos.toByteArray()); 172 exporter.handleRequest(request, response); 173 return readRemoteInvocationResult( 174 new ByteArrayInputStream (response.getContentAsByteArray()), config.getCodebaseUrl()); 175 } 176 protected OutputStream decorateOutputStream(OutputStream os) throws IOException { 177 return new GZIPOutputStream (os); 178 } 179 protected InputStream decorateInputStream(InputStream is) throws IOException { 180 return new GZIPInputStream (is); 181 } 182 }); 183 184 pfb.afterPropertiesSet(); 185 ITestBean proxy = (ITestBean) pfb.getObject(); 186 assertEquals("myname", proxy.getName()); 187 assertEquals(99, proxy.getAge()); 188 proxy.setAge(50); 189 assertEquals(50, proxy.getAge()); 190 191 try { 192 proxy.exceptional(new IllegalStateException ()); 193 fail("Should have thrown IllegalStateException"); 194 } 195 catch (IllegalStateException ex) { 196 } 198 try { 199 proxy.exceptional(new IllegalAccessException ()); 200 fail("Should have thrown IllegalAccessException"); 201 } 202 catch (IllegalAccessException ex) { 203 } 205 } 206 207 public void testHttpInvokerProxyFactoryBeanAndServiceExporterWithWrappedInvocations() throws Throwable { 208 TestBean target = new TestBean("myname", 99); 209 210 final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter() { 211 protected RemoteInvocation doReadRemoteInvocation(ObjectInputStream ois) 212 throws IOException , ClassNotFoundException { 213 Object obj = ois.readObject(); 214 if (!(obj instanceof TestRemoteInvocationWrapper)) { 215 throw new IOException ("Deserialized object needs to be assignable to type [" + 216 TestRemoteInvocationWrapper.class.getName() + "]: " + obj); 217 } 218 return ((TestRemoteInvocationWrapper) obj).remoteInvocation; 219 } 220 protected void doWriteRemoteInvocationResult(RemoteInvocationResult result, ObjectOutputStream oos) 221 throws IOException { 222 oos.writeObject(new TestRemoteInvocationResultWrapper(result)); 223 } 224 }; 225 exporter.setServiceInterface(ITestBean.class); 226 exporter.setService(target); 227 exporter.afterPropertiesSet(); 228 229 HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean(); 230 pfb.setServiceInterface(ITestBean.class); 231 pfb.setServiceUrl("http://myurl"); 232 233 pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() { 234 protected RemoteInvocationResult doExecuteRequest( 235 HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) 236 throws IOException , ClassNotFoundException { 237 assertEquals("http://myurl", config.getServiceUrl()); 238 MockHttpServletRequest request = new MockHttpServletRequest(); 239 MockHttpServletResponse response = new MockHttpServletResponse(); 240 request.setContent(baos.toByteArray()); 241 exporter.handleRequest(request, response); 242 return readRemoteInvocationResult( 243 new ByteArrayInputStream (response.getContentAsByteArray()), config.getCodebaseUrl()); 244 } 245 protected void doWriteRemoteInvocation(RemoteInvocation invocation, ObjectOutputStream oos) throws IOException { 246 oos.writeObject(new TestRemoteInvocationWrapper(invocation)); 247 } 248 protected RemoteInvocationResult doReadRemoteInvocationResult(ObjectInputStream ois) 249 throws IOException , ClassNotFoundException { 250 Object obj = ois.readObject(); 251 if (!(obj instanceof TestRemoteInvocationResultWrapper)) { 252 throw new IOException ("Deserialized object needs to be assignable to type [" 253 + TestRemoteInvocationResultWrapper.class.getName() + "]: " + obj); 254 } 255 return ((TestRemoteInvocationResultWrapper) obj).remoteInvocationResult; 256 } 257 }); 258 259 pfb.afterPropertiesSet(); 260 ITestBean proxy = (ITestBean) pfb.getObject(); 261 assertEquals("myname", proxy.getName()); 262 assertEquals(99, proxy.getAge()); 263 proxy.setAge(50); 264 assertEquals(50, proxy.getAge()); 265 266 try { 267 proxy.exceptional(new IllegalStateException ()); 268 fail("Should have thrown IllegalStateException"); 269 } 270 catch (IllegalStateException ex) { 271 } 273 try { 274 proxy.exceptional(new IllegalAccessException ()); 275 fail("Should have thrown IllegalAccessException"); 276 } 277 catch (IllegalAccessException ex) { 278 } 280 } 281 282 public void testHttpInvokerProxyFactoryBeanAndServiceExporterWithInvocationAttributes() throws Exception { 283 TestBean target = new TestBean("myname", 99); 284 285 final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter(); 286 exporter.setServiceInterface(ITestBean.class); 287 exporter.setService(target); 288 exporter.setRemoteInvocationExecutor(new DefaultRemoteInvocationExecutor() { 289 public Object invoke(RemoteInvocation invocation, Object targetObject) 290 throws NoSuchMethodException , IllegalAccessException , InvocationTargetException { 291 assertNotNull(invocation.getAttributes()); 292 assertEquals(1, invocation.getAttributes().size()); 293 assertEquals("myValue", invocation.getAttributes().get("myKey")); 294 assertEquals("myValue", invocation.getAttribute("myKey")); 295 return super.invoke(invocation, targetObject); 296 } 297 }); 298 exporter.afterPropertiesSet(); 299 300 HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean(); 301 pfb.setServiceInterface(ITestBean.class); 302 pfb.setServiceUrl("http://myurl"); 303 pfb.setRemoteInvocationFactory(new RemoteInvocationFactory() { 304 public RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) { 305 RemoteInvocation invocation = new RemoteInvocation(methodInvocation); 306 invocation.addAttribute("myKey", "myValue"); 307 try { 308 invocation.addAttribute("myKey", "myValue"); 309 fail("Should have thrown IllegalStateException"); 310 } 311 catch (IllegalStateException ex) { 312 } 314 assertNotNull(invocation.getAttributes()); 315 assertEquals(1, invocation.getAttributes().size()); 316 assertEquals("myValue", invocation.getAttributes().get("myKey")); 317 assertEquals("myValue", invocation.getAttribute("myKey")); 318 return invocation; 319 } 320 }); 321 322 pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() { 323 protected RemoteInvocationResult doExecuteRequest( 324 HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) 325 throws IOException , ClassNotFoundException { 326 assertEquals("http://myurl", config.getServiceUrl()); 327 MockHttpServletRequest request = new MockHttpServletRequest(); 328 MockHttpServletResponse response = new MockHttpServletResponse(); 329 request.setContent(baos.toByteArray()); 330 exporter.handleRequest(request, response); 331 return readRemoteInvocationResult( 332 new ByteArrayInputStream (response.getContentAsByteArray()), config.getCodebaseUrl()); 333 } 334 }); 335 336 pfb.afterPropertiesSet(); 337 ITestBean proxy = (ITestBean) pfb.getObject(); 338 assertEquals("myname", proxy.getName()); 339 assertEquals(99, proxy.getAge()); 340 } 341 342 public void testHttpInvokerProxyFactoryBeanAndServiceExporterWithCustomInvocationObject() throws Exception { 343 TestBean target = new TestBean("myname", 99); 344 345 final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter(); 346 exporter.setServiceInterface(ITestBean.class); 347 exporter.setService(target); 348 exporter.setRemoteInvocationExecutor(new DefaultRemoteInvocationExecutor() { 349 public Object invoke(RemoteInvocation invocation, Object targetObject) 350 throws NoSuchMethodException , IllegalAccessException , InvocationTargetException { 351 assertTrue(invocation instanceof TestRemoteInvocation); 352 assertNull(invocation.getAttributes()); 353 assertNull(invocation.getAttribute("myKey")); 354 return super.invoke(invocation, targetObject); 355 } 356 }); 357 exporter.afterPropertiesSet(); 358 359 HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean(); 360 pfb.setServiceInterface(ITestBean.class); 361 pfb.setServiceUrl("http://myurl"); 362 pfb.setRemoteInvocationFactory(new RemoteInvocationFactory() { 363 public RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) { 364 RemoteInvocation invocation = new TestRemoteInvocation(methodInvocation); 365 assertNull(invocation.getAttributes()); 366 assertNull(invocation.getAttribute("myKey")); 367 return invocation; 368 } 369 }); 370 371 pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() { 372 protected RemoteInvocationResult doExecuteRequest( 373 HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) 374 throws IOException , ClassNotFoundException { 375 assertEquals("http://myurl", config.getServiceUrl()); 376 MockHttpServletRequest request = new MockHttpServletRequest(); 377 MockHttpServletResponse response = new MockHttpServletResponse(); 378 request.setContent(baos.toByteArray()); 379 exporter.handleRequest(request, response); 380 return readRemoteInvocationResult( 381 new ByteArrayInputStream (response.getContentAsByteArray()), config.getCodebaseUrl()); 382 } 383 }); 384 385 pfb.afterPropertiesSet(); 386 ITestBean proxy = (ITestBean) pfb.getObject(); 387 assertEquals("myname", proxy.getName()); 388 assertEquals(99, proxy.getAge()); 389 } 390 391 public void testHttpInvokerWithSpecialLocalMethods() throws Exception { 392 String serviceUrl = "http://myurl"; 393 HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean(); 394 pfb.setServiceInterface(ITestBean.class); 395 pfb.setServiceUrl(serviceUrl); 396 397 pfb.setHttpInvokerRequestExecutor(new HttpInvokerRequestExecutor() { 398 public RemoteInvocationResult executeRequest( 399 HttpInvokerClientConfiguration config, RemoteInvocation invocation) throws IOException { 400 throw new IOException ("argh"); 401 } 402 }); 403 404 pfb.afterPropertiesSet(); 405 ITestBean proxy = (ITestBean) pfb.getObject(); 406 407 assertTrue(proxy.toString().indexOf("HTTP invoker") != -1); 409 assertTrue(proxy.toString().indexOf(serviceUrl) != -1); 410 assertEquals(proxy.hashCode(), proxy.hashCode()); 411 assertTrue(proxy.equals(proxy)); 412 413 try { 415 proxy.setAge(50); 416 fail("Should have thrown RemoteAccessException"); 417 } 418 catch (RemoteAccessException ex) { 419 assertTrue(ex.getCause() instanceof IOException ); 421 } 422 } 423 424 425 private static class TestRemoteInvocation extends RemoteInvocation { 426 427 public TestRemoteInvocation(MethodInvocation methodInvocation) { 428 super(methodInvocation); 429 } 430 } 431 432 433 private static class TestRemoteInvocationWrapper implements Serializable { 434 435 private final RemoteInvocation remoteInvocation; 436 437 public TestRemoteInvocationWrapper(RemoteInvocation remoteInvocation) { 438 this.remoteInvocation = remoteInvocation; 439 } 440 } 441 442 443 private static class TestRemoteInvocationResultWrapper implements Serializable { 444 445 private final RemoteInvocationResult remoteInvocationResult; 446 447 public TestRemoteInvocationResultWrapper(RemoteInvocationResult remoteInvocationResult) { 448 this.remoteInvocationResult = remoteInvocationResult; 449 } 450 } 451 452 } 453 | Popular Tags |