17dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin/** 27dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin * Copyright (C) 2012 Google Inc. 37dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin * 47dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin * Licensed under the Apache License, Version 2.0 (the "License"); 57dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin * you may not use this file except in compliance with the License. 67dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin * You may obtain a copy of the License at 77dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin * 87dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin * http://www.apache.org/licenses/LICENSE-2.0 97dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin * 107dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin * Unless required by applicable law or agreed to in writing, software 117dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin * distributed under the License is distributed on an "AS IS" BASIS, 127dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin * See the License for the specific language governing permissions and 147dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin * limitations under the License. 157dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin */ 167dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin 177dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlinpackage com.google.inject.servlet; 187dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin 197dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlinimport com.google.common.collect.ImmutableMap; 207dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlinimport com.google.inject.AbstractModule; 217dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlinimport com.google.inject.Guice; 227dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlinimport com.google.inject.Injector; 237dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlinimport com.google.inject.Key; 247dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlinimport com.google.inject.OutOfScopeException; 257dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlinimport com.google.inject.Provides; 267dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin 277dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlinimport junit.framework.TestCase; 287dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin 297dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlinimport java.util.concurrent.Callable; 307dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlinimport java.util.concurrent.ExecutorService; 317dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlinimport java.util.concurrent.Executors; 327dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlinimport java.util.concurrent.Future; 334a4d8257ed41d8e2be03fd59a6c9dcf00c2379deSam Berlinimport java.util.concurrent.TimeUnit; 344a4d8257ed41d8e2be03fd59a6c9dcf00c2379deSam Berlinimport java.util.concurrent.TimeoutException; 357dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin 367dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin// TODO: Add test for HTTP transferring. 377dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin/** 387dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin * Tests transferring of entire request scope. 397dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin */ 407dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin 417dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlinpublic class TransferRequestIntegrationTest extends TestCase { 427dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin private final Callable<Boolean> FALSE_CALLABLE = new Callable<Boolean>() { 437dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin @Override public Boolean call() { 447dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin return false; 457dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin } 467dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin }; 477dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin 487dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin public void testTransferHttp_outOfScope() { 497dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin try { 507dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin ServletScopes.transferRequest(FALSE_CALLABLE); 517dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin fail(); 527dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin } catch (OutOfScopeException expected) {} 537dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin } 547dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin 557dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin public void testTransferNonHttp_outOfScope() { 567dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin try { 577dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin ServletScopes.transferRequest(FALSE_CALLABLE); 587dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin fail(); 597dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin } catch (OutOfScopeException expected) {} 607dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin } 617dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin 627dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin public void testTransferNonHttpRequest() throws Exception { 637dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin final Injector injector = Guice.createInjector(new AbstractModule() { 647dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin @Override protected void configure() { 657dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin bindScope(RequestScoped.class, ServletScopes.REQUEST); 667dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin } 677dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin 687dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin @Provides @RequestScoped Object provideObject() { 697dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin return new Object(); 707dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin } 717dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin }); 727dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin 737dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin Callable<Callable<Boolean>> callable = new Callable<Callable<Boolean>>() { 747dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin @Override public Callable<Boolean> call() { 757dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin final Object original = injector.getInstance(Object.class); 767dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin return ServletScopes.transferRequest(new Callable<Boolean>() { 777dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin @Override public Boolean call() { 787dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin return original == injector.getInstance(Object.class); 797dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin } 807dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin }); 817dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin } 827dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin }; 837dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin 847dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin ImmutableMap<Key<?>, Object> seedMap = ImmutableMap.of(); 857dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin Callable<Boolean> transfer = ServletScopes.scopeRequest(callable, seedMap).call(); 867dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin 877dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin ExecutorService executor = Executors.newSingleThreadExecutor(); 887dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin assertTrue(executor.submit(transfer).get()); 897dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin executor.shutdownNow(); 907dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin } 917dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin 924a4d8257ed41d8e2be03fd59a6c9dcf00c2379deSam Berlin public void testTransferNonHttpRequest_concurrentUseBlocks() throws Exception { 937dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin Callable<Boolean> callable = new Callable<Boolean>() { 947dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin @Override public Boolean call() throws Exception { 957dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin ExecutorService executor = Executors.newSingleThreadExecutor(); 967dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin try { 977dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin Future<Boolean> future = executor.submit(ServletScopes.transferRequest(FALSE_CALLABLE)); 987dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin try { 994a4d8257ed41d8e2be03fd59a6c9dcf00c2379deSam Berlin return future.get(100, TimeUnit.MILLISECONDS); 1004a4d8257ed41d8e2be03fd59a6c9dcf00c2379deSam Berlin } catch (TimeoutException e) { 1014a4d8257ed41d8e2be03fd59a6c9dcf00c2379deSam Berlin return true; 1027dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin } 1037dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin } finally { 1047dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin executor.shutdownNow(); 1057dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin } 1067dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin } 1077dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin }; 1087dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin 1097dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin ImmutableMap<Key<?>, Object> seedMap = ImmutableMap.of(); 1107dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin assertTrue(ServletScopes.scopeRequest(callable, seedMap).call()); 1117dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin } 1127dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin 1137dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin public void testTransferNonHttpRequest_concurrentUseSameThreadOk() throws Exception { 1147dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin Callable<Boolean> callable = new Callable<Boolean>() { 1157dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin @Override public Boolean call() throws Exception { 1167dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin return ServletScopes.transferRequest(FALSE_CALLABLE).call(); 1177dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin } 1187dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin }; 1197dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin 1207dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin ImmutableMap<Key<?>, Object> seedMap = ImmutableMap.of(); 1217dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin assertFalse(ServletScopes.scopeRequest(callable, seedMap).call()); 1227dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin } 1237dc62e5869d6d14744cc717b4a3d02e30fa22f66Sam Berlin} 124