Update the ThreadLocal based scopes to use RequestContext.
Bound the ThreadLocalRequestContext module, which makes the CurrentUser available in the Global module. Removed any binding in the scopes that provided the CurrentUser. Updated all of the scopes to propagate the RequestContext. The PerThreadRequestScope.Propagator allows scoping callables to enter a request context. Change-Id: Idf682ed1d7485cf8c9cdd22cd89bfe1ad5296880
This commit is contained in:
@@ -1,41 +0,0 @@
|
|||||||
// Copyright (C) 2009 The Android Open Source Project
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package com.google.gerrit.httpd;
|
|
||||||
|
|
||||||
import com.google.gerrit.common.errors.NotSignedInException;
|
|
||||||
import com.google.gerrit.server.CurrentUser;
|
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.google.inject.Provider;
|
|
||||||
import com.google.inject.ProvisionException;
|
|
||||||
|
|
||||||
class HttpIdentifiedUserProvider implements Provider<IdentifiedUser> {
|
|
||||||
private final Provider<CurrentUser> currUserProvider;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
HttpIdentifiedUserProvider(Provider<CurrentUser> currUserProvider) {
|
|
||||||
this.currUserProvider = currUserProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IdentifiedUser get() {
|
|
||||||
CurrentUser user = currUserProvider.get();
|
|
||||||
if (user instanceof IdentifiedUser) {
|
|
||||||
return (IdentifiedUser) user;
|
|
||||||
}
|
|
||||||
throw new ProvisionException(NotSignedInException.MESSAGE,
|
|
||||||
new NotSignedInException());
|
|
||||||
}
|
|
||||||
}
|
|
@@ -15,19 +15,20 @@
|
|||||||
package com.google.gerrit.httpd;
|
package com.google.gerrit.httpd;
|
||||||
|
|
||||||
import com.google.gerrit.server.CurrentUser;
|
import com.google.gerrit.server.CurrentUser;
|
||||||
|
import com.google.gerrit.server.util.RequestContext;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
|
|
||||||
class HttpCurrentUserProvider implements Provider<CurrentUser> {
|
class HttpRequestContext implements RequestContext {
|
||||||
private final WebSession session;
|
private final WebSession session;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
HttpCurrentUserProvider(final WebSession session) {
|
HttpRequestContext(final WebSession session) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CurrentUser get() {
|
public CurrentUser getCurrentUser() {
|
||||||
return session.getCurrentUser();
|
return session.getCurrentUser();
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -15,9 +15,13 @@
|
|||||||
package com.google.gerrit.httpd;
|
package com.google.gerrit.httpd;
|
||||||
|
|
||||||
import com.google.gerrit.server.RequestCleanup;
|
import com.google.gerrit.server.RequestCleanup;
|
||||||
|
import com.google.gerrit.server.util.RequestContext;
|
||||||
|
import com.google.gerrit.server.util.ThreadLocalRequestContext;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Module;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
|
import com.google.inject.servlet.ServletModule;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@@ -30,12 +34,27 @@ import javax.servlet.ServletResponse;
|
|||||||
|
|
||||||
/** Executes any pending {@link RequestCleanup} at the end of a request. */
|
/** Executes any pending {@link RequestCleanup} at the end of a request. */
|
||||||
@Singleton
|
@Singleton
|
||||||
class RequestCleanupFilter implements Filter {
|
public class RequestContextFilter implements Filter {
|
||||||
|
public static Module module() {
|
||||||
|
return new ServletModule() {
|
||||||
|
@Override
|
||||||
|
protected void configureServlets() {
|
||||||
|
filter("/*").through(RequestContextFilter.class);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private final Provider<RequestCleanup> cleanup;
|
private final Provider<RequestCleanup> cleanup;
|
||||||
|
private final Provider<HttpRequestContext> requestContext;
|
||||||
|
private final ThreadLocalRequestContext local;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
RequestCleanupFilter(final Provider<RequestCleanup> r) {
|
RequestContextFilter(final Provider<RequestCleanup> r,
|
||||||
|
final Provider<HttpRequestContext> c,
|
||||||
|
final ThreadLocalRequestContext l) {
|
||||||
cleanup = r;
|
cleanup = r;
|
||||||
|
requestContext = c;
|
||||||
|
local = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -50,10 +69,15 @@ class RequestCleanupFilter implements Filter {
|
|||||||
public void doFilter(final ServletRequest request,
|
public void doFilter(final ServletRequest request,
|
||||||
final ServletResponse response, final FilterChain chain)
|
final ServletResponse response, final FilterChain chain)
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
|
RequestContext old = local.setContext(requestContext.get());
|
||||||
|
try {
|
||||||
try {
|
try {
|
||||||
chain.doFilter(request, response);
|
chain.doFilter(request, response);
|
||||||
} finally {
|
} finally {
|
||||||
cleanup.get().run();
|
cleanup.get().run();
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
local.setContext(old);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -25,8 +25,6 @@ import com.google.gerrit.httpd.auth.ldap.LdapAuthModule;
|
|||||||
import com.google.gerrit.httpd.gitweb.GitWebModule;
|
import com.google.gerrit.httpd.gitweb.GitWebModule;
|
||||||
import com.google.gerrit.httpd.rpc.UiRpcModule;
|
import com.google.gerrit.httpd.rpc.UiRpcModule;
|
||||||
import com.google.gerrit.lifecycle.LifecycleModule;
|
import com.google.gerrit.lifecycle.LifecycleModule;
|
||||||
import com.google.gerrit.server.CurrentUser;
|
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
|
||||||
import com.google.gerrit.server.RemotePeer;
|
import com.google.gerrit.server.RemotePeer;
|
||||||
import com.google.gerrit.server.account.AccountManager;
|
import com.google.gerrit.server.account.AccountManager;
|
||||||
import com.google.gerrit.server.account.ChangeUserName;
|
import com.google.gerrit.server.account.ChangeUserName;
|
||||||
@@ -78,13 +76,8 @@ public class WebModule extends FactoryModule {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
install(new ServletModule() {
|
|
||||||
@Override
|
|
||||||
protected void configureServlets() {
|
|
||||||
filter("/*").through(RequestCleanupFilter.class);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
bind(RequestScopePropagator.class).to(GuiceRequestScopePropagator.class);
|
bind(RequestScopePropagator.class).to(GuiceRequestScopePropagator.class);
|
||||||
|
bind(HttpRequestContext.class);
|
||||||
|
|
||||||
if (wantSSL) {
|
if (wantSSL) {
|
||||||
install(new RequireSslFilter.Module());
|
install(new RequireSslFilter.Module());
|
||||||
@@ -147,9 +140,6 @@ public class WebModule extends FactoryModule {
|
|||||||
bind(SocketAddress.class).annotatedWith(RemotePeer.class).toProvider(
|
bind(SocketAddress.class).annotatedWith(RemotePeer.class).toProvider(
|
||||||
HttpRemotePeerProvider.class).in(RequestScoped.class);
|
HttpRemotePeerProvider.class).in(RequestScoped.class);
|
||||||
|
|
||||||
bind(CurrentUser.class).toProvider(HttpCurrentUserProvider.class);
|
|
||||||
bind(IdentifiedUser.class).toProvider(HttpIdentifiedUserProvider.class);
|
|
||||||
|
|
||||||
install(new LifecycleModule() {
|
install(new LifecycleModule() {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
|
@@ -21,6 +21,7 @@ import com.google.gerrit.ehcache.EhcachePoolImpl;
|
|||||||
import com.google.gerrit.httpd.CacheBasedWebSession;
|
import com.google.gerrit.httpd.CacheBasedWebSession;
|
||||||
import com.google.gerrit.httpd.GitOverHttpModule;
|
import com.google.gerrit.httpd.GitOverHttpModule;
|
||||||
import com.google.gerrit.httpd.HttpCanonicalWebUrlProvider;
|
import com.google.gerrit.httpd.HttpCanonicalWebUrlProvider;
|
||||||
|
import com.google.gerrit.httpd.RequestContextFilter;
|
||||||
import com.google.gerrit.httpd.WebModule;
|
import com.google.gerrit.httpd.WebModule;
|
||||||
import com.google.gerrit.httpd.WebSshGlueModule;
|
import com.google.gerrit.httpd.WebSshGlueModule;
|
||||||
import com.google.gerrit.httpd.auth.openid.OpenIdModule;
|
import com.google.gerrit.httpd.auth.openid.OpenIdModule;
|
||||||
@@ -271,6 +272,7 @@ public class Daemon extends SiteProgram {
|
|||||||
|
|
||||||
private Injector createWebInjector() {
|
private Injector createWebInjector() {
|
||||||
final List<Module> modules = new ArrayList<Module>();
|
final List<Module> modules = new ArrayList<Module>();
|
||||||
|
modules.add(RequestContextFilter.module());
|
||||||
modules.add(CacheBasedWebSession.module());
|
modules.add(CacheBasedWebSession.module());
|
||||||
modules.add(HttpContactStoreConnection.module());
|
modules.add(HttpContactStoreConnection.module());
|
||||||
modules.add(sysInjector.getInstance(GitOverHttpModule.class));
|
modules.add(sysInjector.getInstance(GitOverHttpModule.class));
|
||||||
|
@@ -23,6 +23,7 @@ import com.google.gerrit.extensions.registration.DynamicSet;
|
|||||||
import com.google.gerrit.reviewdb.client.AuthType;
|
import com.google.gerrit.reviewdb.client.AuthType;
|
||||||
import com.google.gerrit.rules.PrologModule;
|
import com.google.gerrit.rules.PrologModule;
|
||||||
import com.google.gerrit.rules.RulesCache;
|
import com.google.gerrit.rules.RulesCache;
|
||||||
|
import com.google.gerrit.server.AnonymousUser;
|
||||||
import com.google.gerrit.server.FileTypeRegistry;
|
import com.google.gerrit.server.FileTypeRegistry;
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
import com.google.gerrit.server.InternalUser;
|
import com.google.gerrit.server.InternalUser;
|
||||||
@@ -64,8 +65,10 @@ import com.google.gerrit.server.project.ProjectState;
|
|||||||
import com.google.gerrit.server.project.SectionSortCache;
|
import com.google.gerrit.server.project.SectionSortCache;
|
||||||
import com.google.gerrit.server.tools.ToolsCatalog;
|
import com.google.gerrit.server.tools.ToolsCatalog;
|
||||||
import com.google.gerrit.server.util.IdGenerator;
|
import com.google.gerrit.server.util.IdGenerator;
|
||||||
|
import com.google.gerrit.server.util.ThreadLocalRequestContext;
|
||||||
import com.google.gerrit.server.workflow.FunctionState;
|
import com.google.gerrit.server.workflow.FunctionState;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.servlet.RequestScoped;
|
||||||
|
|
||||||
import org.apache.velocity.runtime.RuntimeInstance;
|
import org.apache.velocity.runtime.RuntimeInstance;
|
||||||
import org.eclipse.jgit.lib.Config;
|
import org.eclipse.jgit.lib.Config;
|
||||||
@@ -117,6 +120,7 @@ public class GerritGlobalModule extends FactoryModule {
|
|||||||
install(new AccessControlModule());
|
install(new AccessControlModule());
|
||||||
install(new GitModule());
|
install(new GitModule());
|
||||||
install(new PrologModule());
|
install(new PrologModule());
|
||||||
|
install(ThreadLocalRequestContext.module());
|
||||||
|
|
||||||
factory(AccountInfoCacheFactory.Factory.class);
|
factory(AccountInfoCacheFactory.Factory.class);
|
||||||
factory(CapabilityControl.Factory.class);
|
factory(CapabilityControl.Factory.class);
|
||||||
@@ -154,5 +158,7 @@ public class GerritGlobalModule extends FactoryModule {
|
|||||||
bind(GitReferenceUpdated.class);
|
bind(GitReferenceUpdated.class);
|
||||||
DynamicSet.setOf(binder(), GitReferenceUpdatedListener.class);
|
DynamicSet.setOf(binder(), GitReferenceUpdatedListener.class);
|
||||||
DynamicSet.setOf(binder(), NewProjectCreatedListener.class);
|
DynamicSet.setOf(binder(), NewProjectCreatedListener.class);
|
||||||
|
|
||||||
|
bind(AnonymousUser.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -77,7 +77,6 @@ public class GerritRequestModule extends FactoryModule {
|
|||||||
bind(ListProjects.class);
|
bind(ListProjects.class);
|
||||||
bind(ApprovalsUtil.class);
|
bind(ApprovalsUtil.class);
|
||||||
|
|
||||||
bind(AnonymousUser.class).in(RequestScoped.class);
|
|
||||||
bind(PerRequestProjectControlCache.class).in(RequestScoped.class);
|
bind(PerRequestProjectControlCache.class).in(RequestScoped.class);
|
||||||
bind(ChangeControl.Factory.class).in(SINGLETON);
|
bind(ChangeControl.Factory.class).in(SINGLETON);
|
||||||
bind(GroupControl.Factory.class).in(SINGLETON);
|
bind(GroupControl.Factory.class).in(SINGLETON);
|
||||||
|
@@ -20,16 +20,17 @@ import static java.util.concurrent.TimeUnit.SECONDS;
|
|||||||
import com.google.gerrit.reviewdb.client.Branch;
|
import com.google.gerrit.reviewdb.client.Branch;
|
||||||
import com.google.gerrit.reviewdb.client.Project;
|
import com.google.gerrit.reviewdb.client.Project;
|
||||||
import com.google.gerrit.server.CurrentUser;
|
import com.google.gerrit.server.CurrentUser;
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
|
||||||
import com.google.gerrit.server.RemotePeer;
|
import com.google.gerrit.server.RemotePeer;
|
||||||
import com.google.gerrit.server.config.GerritRequestModule;
|
import com.google.gerrit.server.config.GerritRequestModule;
|
||||||
import com.google.gerrit.server.ssh.SshInfo;
|
import com.google.gerrit.server.ssh.SshInfo;
|
||||||
|
import com.google.gerrit.server.util.RequestContext;
|
||||||
import com.google.gerrit.server.util.RequestScopePropagator;
|
import com.google.gerrit.server.util.RequestScopePropagator;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.OutOfScopeException;
|
import com.google.inject.OutOfScopeException;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
|
import com.google.inject.Provides;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import com.google.inject.servlet.RequestScoped;
|
import com.google.inject.servlet.RequestScoped;
|
||||||
|
|
||||||
@@ -43,6 +44,7 @@ import java.util.Collections;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@@ -57,6 +59,7 @@ public class ChangeMergeQueue implements MergeQueue {
|
|||||||
|
|
||||||
private final WorkQueue workQueue;
|
private final WorkQueue workQueue;
|
||||||
private final Provider<MergeOp.Factory> bgFactory;
|
private final Provider<MergeOp.Factory> bgFactory;
|
||||||
|
private final PerThreadRequestScope.Scoper threadScoper;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ChangeMergeQueue(final WorkQueue wq, Injector parent) {
|
ChangeMergeQueue(final WorkQueue wq, Injector parent) {
|
||||||
@@ -68,15 +71,9 @@ public class ChangeMergeQueue implements MergeQueue {
|
|||||||
bindScope(RequestScoped.class, PerThreadRequestScope.REQUEST);
|
bindScope(RequestScoped.class, PerThreadRequestScope.REQUEST);
|
||||||
bind(RequestScopePropagator.class)
|
bind(RequestScopePropagator.class)
|
||||||
.to(PerThreadRequestScope.Propagator.class);
|
.to(PerThreadRequestScope.Propagator.class);
|
||||||
|
bind(PerThreadRequestScope.Propagator.class);
|
||||||
install(new GerritRequestModule());
|
install(new GerritRequestModule());
|
||||||
|
|
||||||
bind(CurrentUser.class).to(IdentifiedUser.class);
|
|
||||||
bind(IdentifiedUser.class).toProvider(new Provider<IdentifiedUser>() {
|
|
||||||
@Override
|
|
||||||
public IdentifiedUser get() {
|
|
||||||
throw new OutOfScopeException("No user on merge thread");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
bind(SocketAddress.class).annotatedWith(RemotePeer.class).toProvider(
|
bind(SocketAddress.class).annotatedWith(RemotePeer.class).toProvider(
|
||||||
new Provider<SocketAddress>() {
|
new Provider<SocketAddress>() {
|
||||||
@Override
|
@Override
|
||||||
@@ -91,8 +88,26 @@ public class ChangeMergeQueue implements MergeQueue {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
public PerThreadRequestScope.Scoper provideScoper(
|
||||||
|
final PerThreadRequestScope.Propagator propagator) {
|
||||||
|
final RequestContext requestContext = new RequestContext() {
|
||||||
|
@Override
|
||||||
|
public CurrentUser getCurrentUser() {
|
||||||
|
throw new OutOfScopeException("No user on merge thread");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return new PerThreadRequestScope.Scoper() {
|
||||||
|
@Override
|
||||||
|
public <T> Callable<T> scope(Callable<T> callable) {
|
||||||
|
return propagator.scope(requestContext, callable);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
});
|
});
|
||||||
bgFactory = child.getProvider(MergeOp.Factory.class);
|
bgFactory = child.getProvider(MergeOp.Factory.class);
|
||||||
|
threadScoper = child.getInstance(PerThreadRequestScope.Scoper.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -186,19 +201,15 @@ public class ChangeMergeQueue implements MergeQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void mergeImpl(Branch.NameKey branch) {
|
private void mergeImpl(final Branch.NameKey branch) {
|
||||||
try {
|
|
||||||
PerThreadRequestScope ctx = new PerThreadRequestScope();
|
|
||||||
PerThreadRequestScope old = PerThreadRequestScope.set(ctx);
|
|
||||||
try {
|
|
||||||
try {
|
try {
|
||||||
|
threadScoper.scope(new Callable<Void>(){
|
||||||
|
@Override
|
||||||
|
public Void call() throws Exception {
|
||||||
bgFactory.get().create(branch).merge();
|
bgFactory.get().create(branch).merge();
|
||||||
} finally {
|
return null;
|
||||||
ctx.cleanup.run();
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
PerThreadRequestScope.set(old);
|
|
||||||
}
|
}
|
||||||
|
}).call();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
log.error("Merge attempt for " + branch + " failed", e);
|
log.error("Merge attempt for " + branch + " failed", e);
|
||||||
} finally {
|
} finally {
|
||||||
|
@@ -14,50 +14,86 @@
|
|||||||
|
|
||||||
package com.google.gerrit.server.git;
|
package com.google.gerrit.server.git;
|
||||||
|
|
||||||
import com.google.gerrit.server.RequestCleanup;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.gerrit.server.util.RequestContext;
|
||||||
|
import com.google.gerrit.server.util.ThreadLocalRequestContext;
|
||||||
import com.google.gerrit.server.util.ThreadLocalRequestScopePropagator;
|
import com.google.gerrit.server.util.ThreadLocalRequestScopePropagator;
|
||||||
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Key;
|
import com.google.inject.Key;
|
||||||
import com.google.inject.OutOfScopeException;
|
import com.google.inject.OutOfScopeException;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
import com.google.inject.Scope;
|
import com.google.inject.Scope;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
public class PerThreadRequestScope {
|
public class PerThreadRequestScope {
|
||||||
static class Propagator
|
public interface Scoper {
|
||||||
extends ThreadLocalRequestScopePropagator<PerThreadRequestScope> {
|
<T> Callable<T> scope(Callable<T> callable);
|
||||||
Propagator() {
|
}
|
||||||
super(REQUEST, current);
|
|
||||||
|
private static class Context {
|
||||||
|
private final Map<Key<?>, Object> map;
|
||||||
|
|
||||||
|
private Context() {
|
||||||
|
map = Maps.newHashMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T get(Key<T> key, Provider<T> creator) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
T t = (T) map.get(key);
|
||||||
|
if (t == null) {
|
||||||
|
t = creator.get();
|
||||||
|
map.put(key, t);
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Propagator extends ThreadLocalRequestScopePropagator<Context> {
|
||||||
|
@Inject
|
||||||
|
Propagator(ThreadLocalRequestContext local) {
|
||||||
|
super(REQUEST, current, local);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PerThreadRequestScope continuingContext(
|
protected Context continuingContext(Context ctx) {
|
||||||
PerThreadRequestScope ctx) {
|
return new Context();
|
||||||
return new PerThreadRequestScope();
|
}
|
||||||
|
|
||||||
|
public <T> Callable<T> scope(RequestContext requestContext, Callable<T> callable) {
|
||||||
|
final Context ctx = new Context();
|
||||||
|
final Callable<T> wrapped = context(requestContext, cleanup(callable));
|
||||||
|
return new Callable<T>() {
|
||||||
|
@Override
|
||||||
|
public T call() throws Exception {
|
||||||
|
Context old = current.get();
|
||||||
|
current.set(ctx);
|
||||||
|
try {
|
||||||
|
return wrapped.call();
|
||||||
|
} finally {
|
||||||
|
current.set(old);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final ThreadLocal<PerThreadRequestScope> current =
|
private static final ThreadLocal<Context> current = new ThreadLocal<Context>();
|
||||||
new ThreadLocal<PerThreadRequestScope>();
|
|
||||||
|
|
||||||
private static PerThreadRequestScope requireContext() {
|
private static Context requireContext() {
|
||||||
final PerThreadRequestScope ctx = current.get();
|
final Context ctx = current.get();
|
||||||
if (ctx == null) {
|
if (ctx == null) {
|
||||||
throw new OutOfScopeException("Not in command/request");
|
throw new OutOfScopeException("Not in command/request");
|
||||||
}
|
}
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PerThreadRequestScope set(PerThreadRequestScope ctx) {
|
|
||||||
PerThreadRequestScope old = current.get();
|
|
||||||
current.set(ctx);
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Scope REQUEST = new Scope() {
|
public static final Scope REQUEST = new Scope() {
|
||||||
|
@Override
|
||||||
public <T> Provider<T> scope(final Key<T> key, final Provider<T> creator) {
|
public <T> Provider<T> scope(final Key<T> key, final Provider<T> creator) {
|
||||||
return new Provider<T>() {
|
return new Provider<T>() {
|
||||||
|
@Override
|
||||||
public T get() {
|
public T get() {
|
||||||
return requireContext().get(key, creator);
|
return requireContext().get(key, creator);
|
||||||
}
|
}
|
||||||
@@ -74,26 +110,4 @@ public class PerThreadRequestScope {
|
|||||||
return "PerThreadRequestScope.REQUEST";
|
return "PerThreadRequestScope.REQUEST";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final Key<RequestCleanup> RC_KEY =
|
|
||||||
Key.get(RequestCleanup.class);
|
|
||||||
|
|
||||||
final RequestCleanup cleanup;
|
|
||||||
private final Map<Key<?>, Object> map;
|
|
||||||
|
|
||||||
public PerThreadRequestScope() {
|
|
||||||
cleanup = new RequestCleanup();
|
|
||||||
map = new HashMap<Key<?>, Object>();
|
|
||||||
map.put(RC_KEY, cleanup);
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized <T> T get(Key<T> key, Provider<T> creator) {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
T t = (T) map.get(key);
|
|
||||||
if (t == null) {
|
|
||||||
t = creator.get();
|
|
||||||
map.put(key, t);
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -38,17 +38,15 @@ public class GuiceRequestScopePropagator extends RequestScopePropagator {
|
|||||||
|
|
||||||
private final String url;
|
private final String url;
|
||||||
private final SocketAddress peer;
|
private final SocketAddress peer;
|
||||||
private final CurrentUser user;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
GuiceRequestScopePropagator(
|
GuiceRequestScopePropagator(
|
||||||
@CanonicalWebUrl @Nullable Provider<String> urlProvider,
|
@CanonicalWebUrl @Nullable Provider<String> urlProvider,
|
||||||
@RemotePeer Provider<SocketAddress> remotePeerProvider,
|
@RemotePeer Provider<SocketAddress> remotePeerProvider,
|
||||||
Provider<CurrentUser> currentUserProvider) {
|
ThreadLocalRequestContext local) {
|
||||||
super(ServletScopes.REQUEST);
|
super(ServletScopes.REQUEST, local);
|
||||||
this.url = urlProvider != null ? urlProvider.get() : null;
|
this.url = urlProvider != null ? urlProvider.get() : null;
|
||||||
this.peer = remotePeerProvider.get();
|
this.peer = remotePeerProvider.get();
|
||||||
this.user = currentUserProvider.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,9 +67,6 @@ public class GuiceRequestScopePropagator extends RequestScopePropagator {
|
|||||||
Providers.of(peer));
|
Providers.of(peer));
|
||||||
seedMap.put(Key.get(SocketAddress.class, RemotePeer.class), peer);
|
seedMap.put(Key.get(SocketAddress.class, RemotePeer.class), peer);
|
||||||
|
|
||||||
seedMap.put(Key.get(typeOfProvider(CurrentUser.class)), Providers.of(user));
|
|
||||||
seedMap.put(Key.get(CurrentUser.class), user);
|
|
||||||
|
|
||||||
return ServletScopes.continueRequest(callable, seedMap);
|
return ServletScopes.continueRequest(callable, seedMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -42,9 +42,12 @@ import java.util.concurrent.Executors;
|
|||||||
public abstract class RequestScopePropagator {
|
public abstract class RequestScopePropagator {
|
||||||
|
|
||||||
private final Scope scope;
|
private final Scope scope;
|
||||||
|
private final ThreadLocalRequestContext local;
|
||||||
|
|
||||||
protected RequestScopePropagator(Scope scope) {
|
protected RequestScopePropagator(Scope scope,
|
||||||
|
ThreadLocalRequestContext local) {
|
||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
|
this.local = local;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,26 +73,8 @@ public abstract class RequestScopePropagator {
|
|||||||
* @return a new Callable which will execute in the current request scope.
|
* @return a new Callable which will execute in the current request scope.
|
||||||
*/
|
*/
|
||||||
public final <T> Callable<T> wrap(final Callable<T> callable) {
|
public final <T> Callable<T> wrap(final Callable<T> callable) {
|
||||||
final Callable<T> wrapped = wrapImpl(new Callable<T>() {
|
final Callable<T> wrapped =
|
||||||
@Override
|
wrapImpl(context(local.getContext(), cleanup(callable)));
|
||||||
public T call() throws Exception {
|
|
||||||
RequestCleanup cleanup = scope.scope(
|
|
||||||
Key.get(RequestCleanup.class),
|
|
||||||
new Provider<RequestCleanup>() {
|
|
||||||
@Override
|
|
||||||
public RequestCleanup get() {
|
|
||||||
return new RequestCleanup();
|
|
||||||
}
|
|
||||||
}).get();
|
|
||||||
|
|
||||||
try {
|
|
||||||
return callable.call();
|
|
||||||
} finally {
|
|
||||||
cleanup.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return new Callable<T>() {
|
return new Callable<T>() {
|
||||||
@Override
|
@Override
|
||||||
public T call() throws Exception {
|
public T call() throws Exception {
|
||||||
@@ -178,4 +163,41 @@ public abstract class RequestScopePropagator {
|
|||||||
* @see #wrap(Callable)
|
* @see #wrap(Callable)
|
||||||
*/
|
*/
|
||||||
protected abstract <T> Callable<T> wrapImpl(final Callable<T> callable);
|
protected abstract <T> Callable<T> wrapImpl(final Callable<T> callable);
|
||||||
|
|
||||||
|
protected <T> Callable<T> context(final RequestContext context,
|
||||||
|
final Callable<T> callable) {
|
||||||
|
return new Callable<T>() {
|
||||||
|
@Override
|
||||||
|
public T call() throws Exception {
|
||||||
|
RequestContext old = local.setContext(context);
|
||||||
|
try {
|
||||||
|
return callable.call();
|
||||||
|
} finally {
|
||||||
|
local.setContext(old);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <T> Callable<T> cleanup(final Callable<T> callable) {
|
||||||
|
return new Callable<T>() {
|
||||||
|
@Override
|
||||||
|
public T call() throws Exception {
|
||||||
|
RequestCleanup cleanup = scope.scope(
|
||||||
|
Key.get(RequestCleanup.class),
|
||||||
|
new Provider<RequestCleanup>() {
|
||||||
|
@Override
|
||||||
|
public RequestCleanup get() {
|
||||||
|
return new RequestCleanup();
|
||||||
|
}
|
||||||
|
}).get();
|
||||||
|
|
||||||
|
try {
|
||||||
|
return callable.call();
|
||||||
|
} finally {
|
||||||
|
cleanup.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -31,8 +31,8 @@ public abstract class ThreadLocalRequestScopePropagator<C>
|
|||||||
private final ThreadLocal<C> threadLocal;
|
private final ThreadLocal<C> threadLocal;
|
||||||
|
|
||||||
protected ThreadLocalRequestScopePropagator(Scope scope,
|
protected ThreadLocalRequestScopePropagator(Scope scope,
|
||||||
ThreadLocal<C> threadLocal) {
|
ThreadLocal<C> threadLocal, ThreadLocalRequestContext local) {
|
||||||
super(scope);
|
super(scope, local);
|
||||||
this.threadLocal = threadLocal;
|
this.threadLocal = threadLocal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -122,7 +122,7 @@ class CommandFactoryProvider implements Provider<CommandFactory> {
|
|||||||
|
|
||||||
public void setSession(final ServerSession session) {
|
public void setSession(final ServerSession session) {
|
||||||
final SshSession s = session.getAttribute(SshSession.KEY);
|
final SshSession s = session.getAttribute(SshSession.KEY);
|
||||||
this.ctx = new Context(s, commandLine);
|
this.ctx = sshScope.newContext(s, commandLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start(final Environment env) throws IOException {
|
public void start(final Environment env) throws IOException {
|
||||||
|
@@ -173,7 +173,7 @@ class DatabasePubKeyAuth implements PublickeyAuthenticator {
|
|||||||
// session, record a login event in the log and add
|
// session, record a login event in the log and add
|
||||||
// a close listener to record a logout event.
|
// a close listener to record a logout event.
|
||||||
//
|
//
|
||||||
Context ctx = new Context(sd, null);
|
Context ctx = sshScope.newContext(sd, null);
|
||||||
Context old = sshScope.set(ctx);
|
Context old = sshScope.set(ctx);
|
||||||
try {
|
try {
|
||||||
sshLog.onLogin();
|
sshLog.onLogin();
|
||||||
@@ -185,7 +185,7 @@ class DatabasePubKeyAuth implements PublickeyAuthenticator {
|
|||||||
new IoFutureListener<IoFuture>() {
|
new IoFutureListener<IoFuture>() {
|
||||||
@Override
|
@Override
|
||||||
public void operationComplete(IoFuture future) {
|
public void operationComplete(IoFuture future) {
|
||||||
final Context ctx = new Context(sd, null);
|
final Context ctx = sshScope.newContext(sd, null);
|
||||||
final Context old = sshScope.set(ctx);
|
final Context old = sshScope.set(ctx);
|
||||||
try {
|
try {
|
||||||
sshLog.onLogout();
|
sshLog.onLogout();
|
||||||
|
@@ -89,7 +89,7 @@ class NoShell implements Factory<Command> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setSession(final ServerSession session) {
|
public void setSession(final ServerSession session) {
|
||||||
this.context = new Context(session.getAttribute(SshSession.KEY), "");
|
this.context = sshScope.newContext(session.getAttribute(SshSession.KEY), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start(final Environment env) throws IOException {
|
public void start(final Environment env) throws IOException {
|
||||||
|
@@ -1,42 +0,0 @@
|
|||||||
// Copyright (C) 2010 The Android Open Source Project
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package com.google.gerrit.sshd;
|
|
||||||
|
|
||||||
import com.google.gerrit.server.CurrentUser;
|
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.google.inject.Provider;
|
|
||||||
import com.google.inject.Singleton;
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
class SshCurrentUserProvider implements Provider<CurrentUser> {
|
|
||||||
private final Provider<SshSession> session;
|
|
||||||
private final Provider<IdentifiedUser> identifiedProvider;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
SshCurrentUserProvider(Provider<SshSession> s, Provider<IdentifiedUser> p) {
|
|
||||||
session = s;
|
|
||||||
identifiedProvider = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CurrentUser get() {
|
|
||||||
final CurrentUser user = session.get().getCurrentUser();
|
|
||||||
if (user instanceof IdentifiedUser) {
|
|
||||||
return identifiedProvider.get();
|
|
||||||
}
|
|
||||||
return session.get().getCurrentUser();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,47 +0,0 @@
|
|||||||
// Copyright (C) 2010 The Android Open Source Project
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package com.google.gerrit.sshd;
|
|
||||||
|
|
||||||
import com.google.gerrit.common.errors.NotSignedInException;
|
|
||||||
import com.google.gerrit.server.CurrentUser;
|
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.google.inject.Provider;
|
|
||||||
import com.google.inject.ProvisionException;
|
|
||||||
import com.google.inject.Singleton;
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
class SshIdentifiedUserProvider implements Provider<IdentifiedUser> {
|
|
||||||
private final Provider<SshSession> session;
|
|
||||||
private final IdentifiedUser.RequestFactory factory;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
SshIdentifiedUserProvider(Provider<SshSession> s,
|
|
||||||
IdentifiedUser.RequestFactory f) {
|
|
||||||
session = s;
|
|
||||||
factory = f;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IdentifiedUser get() {
|
|
||||||
final CurrentUser user = session.get().getCurrentUser();
|
|
||||||
if (user instanceof IdentifiedUser) {
|
|
||||||
return factory.create(user.getAccessPath(), //
|
|
||||||
((IdentifiedUser) user).getAccountId());
|
|
||||||
}
|
|
||||||
throw new ProvisionException(NotSignedInException.MESSAGE,
|
|
||||||
new NotSignedInException());
|
|
||||||
}
|
|
||||||
}
|
|
@@ -152,11 +152,6 @@ public class SshModule extends FactoryModule {
|
|||||||
bind(SocketAddress.class).annotatedWith(RemotePeer.class).toProvider(
|
bind(SocketAddress.class).annotatedWith(RemotePeer.class).toProvider(
|
||||||
SshRemotePeerProvider.class).in(SshScope.REQUEST);
|
SshRemotePeerProvider.class).in(SshScope.REQUEST);
|
||||||
|
|
||||||
bind(CurrentUser.class).toProvider(SshCurrentUserProvider.class).in(
|
|
||||||
SshScope.REQUEST);
|
|
||||||
bind(IdentifiedUser.class).toProvider(SshIdentifiedUserProvider.class).in(
|
|
||||||
SshScope.REQUEST);
|
|
||||||
|
|
||||||
bind(WorkQueue.Executor.class).annotatedWith(CommandExecutor.class)
|
bind(WorkQueue.Executor.class).annotatedWith(CommandExecutor.class)
|
||||||
.toProvider(CommandExecutorProvider.class).in(SshScope.REQUEST);
|
.toProvider(CommandExecutorProvider.class).in(SshScope.REQUEST);
|
||||||
|
|
||||||
|
@@ -14,8 +14,13 @@
|
|||||||
|
|
||||||
package com.google.gerrit.sshd;
|
package com.google.gerrit.sshd;
|
||||||
|
|
||||||
|
import com.google.gerrit.server.CurrentUser;
|
||||||
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
import com.google.gerrit.server.RequestCleanup;
|
import com.google.gerrit.server.RequestCleanup;
|
||||||
|
import com.google.gerrit.server.util.RequestContext;
|
||||||
|
import com.google.gerrit.server.util.ThreadLocalRequestContext;
|
||||||
import com.google.gerrit.server.util.ThreadLocalRequestScopePropagator;
|
import com.google.gerrit.server.util.ThreadLocalRequestScopePropagator;
|
||||||
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Key;
|
import com.google.inject.Key;
|
||||||
import com.google.inject.OutOfScopeException;
|
import com.google.inject.OutOfScopeException;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
@@ -26,10 +31,10 @@ import java.util.Map;
|
|||||||
|
|
||||||
/** Guice scopes for state during an SSH connection. */
|
/** Guice scopes for state during an SSH connection. */
|
||||||
class SshScope {
|
class SshScope {
|
||||||
static class Context {
|
|
||||||
private static final Key<RequestCleanup> RC_KEY =
|
private static final Key<RequestCleanup> RC_KEY =
|
||||||
Key.get(RequestCleanup.class);
|
Key.get(RequestCleanup.class);
|
||||||
|
|
||||||
|
class Context implements RequestContext {
|
||||||
private final RequestCleanup cleanup;
|
private final RequestCleanup cleanup;
|
||||||
private final SshSession session;
|
private final SshSession session;
|
||||||
private final String commandLine;
|
private final String commandLine;
|
||||||
@@ -56,10 +61,6 @@ class SshScope {
|
|||||||
finished = p.finished;
|
finished = p.finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
Context(final SshSession s, final String c) {
|
|
||||||
this(s, c, System.currentTimeMillis());
|
|
||||||
}
|
|
||||||
|
|
||||||
String getCommandLine() {
|
String getCommandLine() {
|
||||||
return commandLine;
|
return commandLine;
|
||||||
}
|
}
|
||||||
@@ -68,6 +69,16 @@ class SshScope {
|
|||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CurrentUser getCurrentUser() {
|
||||||
|
final CurrentUser user = session.getCurrentUser();
|
||||||
|
if (user instanceof IdentifiedUser) {
|
||||||
|
return userFactory.create(user.getAccessPath(), //
|
||||||
|
((IdentifiedUser) user).getAccountId());
|
||||||
|
}
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
synchronized <T> T get(Key<T> key, Provider<T> creator) {
|
synchronized <T> T get(Key<T> key, Provider<T> creator) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
T t = (T) map.get(key);
|
T t = (T) map.get(key);
|
||||||
@@ -100,15 +111,19 @@ class SshScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static class Propagator extends ThreadLocalRequestScopePropagator<Context> {
|
static class Propagator extends ThreadLocalRequestScopePropagator<Context> {
|
||||||
Propagator() {
|
private final SshScope sshScope;
|
||||||
super(REQUEST, current);
|
|
||||||
|
@Inject
|
||||||
|
Propagator(SshScope sshScope, ThreadLocalRequestContext local) {
|
||||||
|
super(REQUEST, current, local);
|
||||||
|
this.sshScope = sshScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Context continuingContext(Context ctx) {
|
protected Context continuingContext(Context ctx) {
|
||||||
// The cleanup is not chained, since the RequestScopePropagator executors
|
// The cleanup is not chained, since the RequestScopePropagator executors
|
||||||
// the Context's cleanup when finished executing.
|
// the Context's cleanup when finished executing.
|
||||||
return new Context(ctx, ctx.getSession(), ctx.getCommandLine());
|
return sshScope.newContinuingContext(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,9 +138,28 @@ class SshScope {
|
|||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final ThreadLocalRequestContext local;
|
||||||
|
private final IdentifiedUser.RequestFactory userFactory;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
SshScope(ThreadLocalRequestContext local,
|
||||||
|
IdentifiedUser.RequestFactory userFactory) {
|
||||||
|
this.local = local;
|
||||||
|
this.userFactory = userFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
Context newContext(SshSession session, String commandLine) {
|
||||||
|
return new Context(session, commandLine, System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Context newContinuingContext(Context ctx) {
|
||||||
|
return new Context(ctx, ctx.getSession(), ctx.getCommandLine());
|
||||||
|
}
|
||||||
|
|
||||||
Context set(Context ctx) {
|
Context set(Context ctx) {
|
||||||
Context old = current.get();
|
Context old = current.get();
|
||||||
current.set(ctx);
|
current.set(ctx);
|
||||||
|
local.setContext(ctx);
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -223,6 +223,7 @@ public class WebAppInitializer extends GuiceServletContextListener {
|
|||||||
|
|
||||||
private Injector createWebInjector() {
|
private Injector createWebInjector() {
|
||||||
final List<Module> modules = new ArrayList<Module>();
|
final List<Module> modules = new ArrayList<Module>();
|
||||||
|
modules.add(RequestContextFilter.module());
|
||||||
modules.add(sysInjector.getInstance(GitOverHttpModule.class));
|
modules.add(sysInjector.getInstance(GitOverHttpModule.class));
|
||||||
modules.add(sshInjector.getInstance(WebModule.class));
|
modules.add(sshInjector.getInstance(WebModule.class));
|
||||||
modules.add(sshInjector.getInstance(WebSshGlueModule.class));
|
modules.add(sshInjector.getInstance(WebSshGlueModule.class));
|
||||||
|
Reference in New Issue
Block a user