-
-
Save joschi/f706e394172988f9200b to your computer and use it in GitHub Desktop.
public class DropwizardHaKaZwei extends Application<MyConfiguration> { | |
// [...] | |
public void run(MyConfiguration config, Environment environment) { | |
// HK2 stuff | |
environment.jersey().register(new AbstractBinder() { | |
@Override | |
protected void configure() { | |
bind(config).to(MyConfiguration.class); | |
bind(environment).to(Environment.class); | |
bind(environment.lifecycle()).to(LifecycleEnvironment.class); | |
bind(environment.metrics()).to(MetricRegistry.class); | |
bind(environment.getValidator()).to(Validator.class); | |
bind(jdbi).to(DBI.class); | |
bind(myDao).to(MyDao.class); | |
} | |
}); | |
} | |
} |
@Path("/foobar") | |
public class MyResource { | |
@Inject | |
private DBI jdbi; | |
@Context | |
private ContainerRequest request; | |
@Timed | |
@GET | |
@Consumes(MediaType.APPLICATION_JSON) | |
public Response foobar(@HeaderParam() { | |
// [...] | |
return Response.accepted().build(); | |
} | |
} |
@luckyluke80 hey buddy the following code worked for me:
// Register JDBI
final DBIFactory factory = new DBIFactory();
final DBI jdbi = factory.build(environment, configuration.getDataSourceFactory(), "database");
// Import DAOs
final UserProfileDAO userProfileDAO = jdbi.onDemand(UserProfileDAO.class);
final UserLogDAO userLogDAO = jdbi.onDemand(UserLogDAO.class);
final UserPageDAO userPageDAO = jdbi.onDemand(UserPageDAO.class);
final AccountUserDAO accountUserDAO = jdbi.onDemand(AccountUserDAO.class);
final ClientDAO clientDAO = jdbi.onDemand(ClientDAO.class);
final AccountDAO accountDAO = jdbi.onDemand(AccountDAO.class);
final AccountFeeDAO accountFeeDAO = jdbi.onDemand(AccountFeeDAO.class);
final TransactionDAO transactionDAO = jdbi.onDemand(TransactionDAO.class);
final InvoiceDAO invoiceDAO = jdbi.onDemand(InvoiceDAO.class);
final InvoiceSettingsDAO invoiceSettingsDAO = jdbi.onDemand(InvoiceSettingsDAO.class);
final CustomerDAO customerDAO = jdbi.onDemand(CustomerDAO.class);
environment.jersey().register(new AbstractBinder() {
@Override
protected void configure() {
bind(configuration).to(MainApplicationConfiguration.class);
bind(environment).to(Environment.class);
bind(environment.lifecycle()).to(LifecycleEnvironment.class);
bind(environment.metrics()).to(MetricRegistry.class);
bind(environment.getValidator()).to(Validator.class);
bind(jdbi).to(DBI.class);
bind(userProfileDAO).to(UserProfileDAO.class);
bind(userLogDAO).to(UserLogDAO.class);
bind(userPageDAO).to(UserPageDAO.class);
bind(accountUserDAO).to(AccountUserDAO.class);
bind(clientDAO).to(ClientDAO.class);
bind(accountDAO).to(AccountDAO.class);
bind(resellerDAO).to(ResellerDAO.class);
bind(invoiceDAO).to(InvoiceDAO.class);
bind(invoiceSettingsDAO).to(InvoiceSettingsDAO.class);
bind(customerDAO).to(CustomerDAO.class);
bind(Tasks.class).to(Tasks.class);
bind(MainAuthenticator.class).to(MainAuthenticator.class);
bind(AuthFeature.class).to(AuthFeature.class);
}
});
// Add URL mapping
environment.jersey().register(LoginResource.class);
environment.jersey().register(UserResource.class);
environment.jersey().register(ClientResource.class);
environment.jersey().register(AccountResource.class);
environment.jersey().register(InvoiceResource.class);
environment.jersey().register(InvoiceSettingsResource.class);
environment.jersey().register(CustomerResource.class);
environment.jersey().register(GeneralSettingsResource.class);
environment.jersey().register(APIResource.class);
// Register Auth Service
environment.jersey().register(AuthFeature.class);
environment.jersey().register(RolesAllowedDynamicFeature.class);
environment.jersey().register(new AuthValueFactoryProvider.Binder<>(UserProfile.class));
and then I just used @Inject in my resources...
@joschi can you confirm the above approach? is this correct?
Also, can you give me some directions how can I use AuthDynamicFeature (dropwizard-auth) in this DI scenario? I need to use the above MainAuthenticator class, which has UserProfileDAO dependency to check user access to the system and roles... After a lot of tries, I just give up, and created a class exactly the same, but injecting my needed object:
public class AuthFeature implements DynamicFeature {
@Inject
private MainAuthenticator mainAuthenticator;
@Override
public void configure(ResourceInfo resourceInfo, FeatureContext context) {
final AnnotatedMethod am = new AnnotatedMethod(resourceInfo.getResourceMethod());
final Annotation[][] parameterAnnotations = am.getParameterAnnotations();
if (am.isAnnotationPresent(RolesAllowed.class) || am.isAnnotationPresent(DenyAll.class) ||
am.isAnnotationPresent(PermitAll.class)) {
context.register(new OAuthCredentialAuthFilter.Builder<UserProfile>()
.setAuthenticator(mainAuthenticator)
.setAuthorizer(new MainAuthorizer())
.setPrefix("Bearer")
.buildAuthFilter());
} else {
for (Annotation[] annotations : parameterAnnotations) {
for (Annotation annotation : annotations) {
if (annotation instanceof Auth) {
context.register(new OAuthCredentialAuthFilter.Builder<UserProfile>()
.setAuthenticator(mainAuthenticator)
.setAuthorizer(new MainAuthorizer())
.setPrefix("Bearer")
.buildAuthFilter());
return;
}
}
}
}
}
}
But I think it's not cool, also it's creating OAuthCredentialAuthFilter instead of use a singleton... Can you help me on that?
Thank you guys!
Have not tested, but you can do something like following in your Application's run method
environment.jersey().getResourceConfig().register(new ContainerLifecycleListener() {
public void onStartup(Container container) {
/*Get the HK2 Service Locator*/
ServiceLocator serviceLocator = container.getApplicationHandler().getServiceLocator();
/*Ask for Instance to ServiceLocator so that it resolves all Injections, Scopes, Qualifiers etc.*/
MyAuthFeatureOrWhatever object = serviceLocator.getService(MyAuthFeatureOrWhatever.class);
environment.jersey().register(object);
}
public void onReload(Container container) {/*...*/}
public void onShutdown(Container container) {/*...*/}
});
you can use the Factory based binding bindFactory() in HK2 configure() to construct a complex object line AuthFeature which transitively needs other objects.
@saumitrabhave I'm receiving an exception when I try to register that object in onStartup Lifecycle... This is the code that I added on the end of my run method:
environment.jersey().getResourceConfig().register(new ContainerLifecycleListener() {
public void onStartup(Container container) {
/*Get the HK2 Service Locator*/
ServiceLocator serviceLocator = container.getApplicationHandler().getServiceLocator();
MainAuthenticator mainAuthenticator = serviceLocator.getService(MainAuthenticator.class);
environment.jersey().register(new OAuthCredentialAuthFilter.Builder<UserProfile>()
.setAuthenticator(mainAuthenticator)
.setAuthorizer(new MainAuthorizer())
.setPrefix("Bearer")
.buildAuthFilter());
}
public void onReload(Container container) {/*...*/}
public void onShutdown(Container container) {/*...*/}
});
And this is the exception that I'm receiving:
Caused by: java.lang.IllegalStateException: The resource configuration is not modifiable in this context.
at org.glassfish.jersey.server.ResourceConfig$ImmutableState.register(ResourceConfig.java:274)
at org.glassfish.jersey.server.ResourceConfig$ImmutableState.register(ResourceConfig.java:221)
at org.glassfish.jersey.server.ResourceConfig.register(ResourceConfig.java:453)
at io.dropwizard.jersey.setup.JerseyEnvironment.register(JerseyEnvironment.java:36)
at com.check21.v2.MainApplication$3.onStartup(MainApplication.java:265)
at org.glassfish.jersey.server.ApplicationHandler.onStartup(ApplicationHandler.java:1180)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:179)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:369)
at javax.servlet.GenericServlet.init(GenericServlet.java:244)
at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:640)
... 41 more
awesome, thanks for the replys. your'e all great!
Can you make the binding of
bind(myDao).to(MyDao.class);
a little bit more clear?What has to come first?
PersonDAO dao = new PersonDAO(hibernateBundle.getSessionFactory());
environment.jersey().register(new PeopleResource(dao));
and then
bind(myDao).to(MyDao.class);
?