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 --------------------------------------------------------
|
//~--- 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.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection provider for {@link HgContext}.
|
* Injection provider for {@link HgContext}.
|
||||||
* This provider returns an instance {@link HgContext} from request scope, if no {@link HgContext} could be found in
|
* 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);
|
LoggerFactory.getLogger(HgContextProvider.class);
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
/**
|
private Provider<HgContextRequestStore> requestStoreProvider;
|
||||||
* Method description
|
|
||||||
*
|
@Inject
|
||||||
*
|
public HgContextProvider(Provider<HgContextRequestStore> requestStoreProvider) {
|
||||||
* @return
|
this.requestStoreProvider = requestStoreProvider;
|
||||||
*/
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public HgContextProvider() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HgContext get() {
|
public HgContext get() {
|
||||||
if (contextRequestStore == null) {
|
HgContext context = fetchContextFromRequest();
|
||||||
logger.trace("context is null, we are probably out of request scope");
|
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();
|
return new HgContext();
|
||||||
}
|
}
|
||||||
logger.trace("return HgContext from request store");
|
|
||||||
return contextRequestStore.get();
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- fields ---------------------------------------------------------------
|
|
||||||
|
|
||||||
@Inject(optional = true)
|
|
||||||
private HgContextRequestStore contextRequestStore;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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