mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-10 23:45:44 +01:00
fixed injection of HgContext, if no request scope is available
This commit is contained in:
@@ -35,12 +35,16 @@ package sonia.scm.repository;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.inject.OutOfScopeException;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.ProvisionException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Injection provider for {@link HgContext}.
|
||||
* This provider returns an instance {@link HgContext} from request scope, if no {@link HgContext} could be found in
|
||||
@@ -52,31 +56,50 @@ public class HgContextProvider implements Provider<HgContext>
|
||||
{
|
||||
|
||||
/**
|
||||
* the logger for HgContextProvider
|
||||
* the LOG for HgContextProvider
|
||||
*/
|
||||
private static final Logger logger =
|
||||
private static final Logger LOG =
|
||||
LoggerFactory.getLogger(HgContextProvider.class);
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public HgContext get() {
|
||||
if (contextRequestStore == null) {
|
||||
logger.trace("context is null, we are probably out of request scope");
|
||||
return new HgContext();
|
||||
}
|
||||
logger.trace("return HgContext from request store");
|
||||
return contextRequestStore.get();
|
||||
private Provider<HgContextRequestStore> requestStoreProvider;
|
||||
|
||||
@Inject
|
||||
public HgContextProvider(Provider<HgContextRequestStore> requestStoreProvider) {
|
||||
this.requestStoreProvider = requestStoreProvider;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
@VisibleForTesting
|
||||
public HgContextProvider() {
|
||||
}
|
||||
|
||||
@Inject(optional = true)
|
||||
private HgContextRequestStore contextRequestStore;
|
||||
@Override
|
||||
public HgContext get() {
|
||||
HgContext context = fetchContextFromRequest();
|
||||
if (context != null) {
|
||||
LOG.trace("return HgContext from request store");
|
||||
return context;
|
||||
}
|
||||
LOG.trace("could not find context in request scope, returning new instance");
|
||||
return new HgContext();
|
||||
}
|
||||
|
||||
private HgContext fetchContextFromRequest() {
|
||||
try {
|
||||
if (requestStoreProvider != null) {
|
||||
return requestStoreProvider.get().get();
|
||||
} else {
|
||||
LOG.trace("no request store provider defined, could not return context from request");
|
||||
return null;
|
||||
}
|
||||
} catch (ProvisionException ex) {
|
||||
if (ex.getCause() instanceof OutOfScopeException) {
|
||||
LOG.trace("we are currently out of request scope, failed to retrieve context");
|
||||
return null;
|
||||
} else {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
package sonia.scm.repository;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.OutOfScopeException;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.ProvisionException;
|
||||
import com.google.inject.Scope;
|
||||
import com.google.inject.servlet.RequestScoped;
|
||||
import com.google.inject.util.Providers;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class HgContextProviderTest {
|
||||
|
||||
@Mock
|
||||
private Scope scope;
|
||||
|
||||
@Test
|
||||
void shouldThrowNonOutOfScopeProvisionExceptions() {
|
||||
Provider<HgContextRequestStore> provider = () -> {
|
||||
throw new RuntimeException("something different");
|
||||
};
|
||||
|
||||
when(scope.scope(any(Key.class), any(Provider.class))).thenReturn(provider);
|
||||
|
||||
Injector injector = Guice.createInjector(new HgContextModule(scope));
|
||||
|
||||
assertThrows(ProvisionException.class, () -> injector.getInstance(HgContext.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldCreateANewInstanceIfOutOfRequestScope() {
|
||||
Provider<HgContextRequestStore> provider = () -> {
|
||||
throw new OutOfScopeException("no request");
|
||||
};
|
||||
when(scope.scope(any(Key.class), any(Provider.class))).thenReturn(provider);
|
||||
|
||||
Injector injector = Guice.createInjector(new HgContextModule(scope));
|
||||
|
||||
HgContext contextOne = injector.getInstance(HgContext.class);
|
||||
HgContext contextTwo = injector.getInstance(HgContext.class);
|
||||
|
||||
assertThat(contextOne).isNotSameAs(contextTwo);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldInjectFromRequestScope() {
|
||||
HgContextRequestStore requestStore = new HgContextRequestStore();
|
||||
Provider<HgContextRequestStore> provider = Providers.of(requestStore);
|
||||
|
||||
when(scope.scope(any(Key.class), any(Provider.class))).thenReturn(provider);
|
||||
|
||||
Injector injector = Guice.createInjector(new HgContextModule(scope));
|
||||
|
||||
HgContext contextOne = injector.getInstance(HgContext.class);
|
||||
HgContext contextTwo = injector.getInstance(HgContext.class);
|
||||
|
||||
assertThat(contextOne).isSameAs(contextTwo);
|
||||
}
|
||||
|
||||
private static class HgContextModule extends AbstractModule {
|
||||
|
||||
private Scope scope;
|
||||
|
||||
private HgContextModule(Scope scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindScope(RequestScoped.class, scope);
|
||||
bind(HgContextRequestStore.class);
|
||||
bind(HgContext.class).toProvider(HgContextProvider.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user