Skip to content

Instantly share code, notes, and snippets.

@kevints
Created September 2, 2014 21:19
Show Gist options
  • Save kevints/302f9fa1d5bd2697f1b7 to your computer and use it in GitHub Desktop.
Save kevints/302f9fa1d5bd2697f1b7 to your computer and use it in GitHub Desktop.
MVP of twitter.common.application+guice+jetty+shiro+jersey
package org.apache.aurora.scheduler.app;
import java.util.Arrays;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import com.google.inject.AbstractModule;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.Provides;
import com.google.inject.name.Names;
import com.google.inject.servlet.GuiceFilter;
import com.google.inject.servlet.GuiceServletContextListener;
import com.sun.jersey.guice.JerseyServletModule;
import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
import com.twitter.common.application.AbstractApplication;
import com.twitter.common.application.AppLauncher;
import com.twitter.common.args.Arg;
import com.twitter.common.args.ArgFilters;
import com.twitter.common.args.CmdLine;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.guice.web.ShiroWebModule;
import org.apache.shiro.realm.text.IniRealm;
import org.mortbay.jetty.Handler;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.webapp.WebAppContext;
import static java.util.Objects.requireNonNull;
/**
* Created by ksweeney on 8/29/14.
*/
public class SecureSchedulerMain extends AbstractApplication {
@CmdLine(name = "exclamation", help = "What to exclaim")
private static final Arg<String> EXCLAMATION = Arg.create("!");
public static void main(String... args) throws Exception {
AppLauncher.launch(
SecureSchedulerMain.class,
ArgFilters.selectClass(SecureSchedulerMain.class),
args);
}
@Inject
private Server server;
@Override
public void run() {
try {
server.start();
server.join();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public Iterable<? extends Module> getModules() {
return Arrays.asList(new AbstractModule() {
@Override
protected void configure() {
bind(GuiceServletContextListener.class).to(AuroraServletContextListener.class);
bind(AuroraServletContextListener.class).in(Singleton.class);
bind(Handler.class).to(WebAppContext.class);
bind(Handler.class).to(WebAppContext.class);
}
@Provides
private WebAppContext provideWebAppContext(GuiceServletContextListener listener) {
WebAppContext webAppContext = new WebAppContext();
webAppContext.setContextPath("/");
webAppContext.setResourceBase("src/main/webapp");
webAppContext.addFilter(GuiceFilter.class, "/*", Context.NO_SESSIONS);
webAppContext.addEventListener(listener);
return webAppContext;
}
@Provides
@Singleton
private Server provideServer(Handler handler) {
Server server = new Server(7070);
server.addHandler(handler);
return server;
}
});
}
static class AuroraServletContextListener extends GuiceServletContextListener {
private final Injector parentInjector;
private ServletContext servletContext;
@Inject
AuroraServletContextListener(Injector parentInjector) {
this.parentInjector = requireNonNull(parentInjector);
}
@Override
public void contextInitialized(ServletContextEvent event) {
this.servletContext = event.getServletContext();
super.contextInitialized(event);
}
@Override
protected Injector getInjector() {
return parentInjector.createChildInjector(
new ShiroWebModule(servletContext) {
@Override
protected void configureShiroWeb() {
// https://gist.github.com/kevints/5999b5379890c0b5dc6f
bindRealm().toInstance(new IniRealm("classpath:shiro.ini"));
addFilterChain("/api/**", AUTHC_BASIC);
addFilterChain("/**", ANON);
}
},
ShiroWebModule.guiceFilterModule(),
new JerseyServletModule() {
@Override
protected void configureServlets() {
serve("/api/*").with(GuiceContainer.class);
// GuiceContainer needs a handle to this Injector, not to the parent injector.
// bind here promotes it to an explicit binding, which causes it to be created in
// this injector rather than the parent injector. For context see
// https://groups.google.com/forum/#!topic/google-guice/Q592mWKTS1Q
bind(GuiceContainer.class);
bindConstant().annotatedWith(Names.named("serverName")).to("aurora");
bind(HelloResource.class);
}
}
);
}
@Path("hello")
public static class HelloResource {
private final String serverName;
@Inject
HelloResource(@Named("serverName") String serverName) {
this.serverName = requireNonNull(serverName);
}
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getHello(
@QueryParam("who") @DefaultValue("world") String who) {
return String.format(
"Hello to %s from %s via %s%s\n",
who,
SecurityUtils.getSubject().getPrincipal(),
serverName,
EXCLAMATION.get());
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment