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