Search in sources :

Example 1 with ClassScanner

use of com.peterphi.std.guice.common.ClassScanner in project stdlib by petergeneric.

the class GuiceFactory method createInjector.

/**
 * Sets up a Guice Injector; this is achieved in the following stages:
 * <ol>
 * <li>Set up the Shutdown Manager</li>
 * <li>Set up the Metrics Registry</li>
 * <li>Call {@link GuiceRole#register} on all GuiceRoles - this allows modules supporting core plugin functionality to be set
 * up </li>
 * <li>Call {@link GuiceSetup#registerModules} on GuiceSetup to get the application's guice modules - this
 * allows the application to set up helper modules</li>
 * <li>Call {@link GuiceRole#injectorCreated} on all GuiceRoles with the newly-created {@link Injector} - this allows plugins
 * to do one-time
 * post-construction work that requires an Injector</li>
 * <li>Call {@link GuiceSetup#injectorCreated} with the newly-created {@link Injector} - this allows the
 * application
 * to do one-time post-construction work that requires an Injector</li>
 * </ol>
 *
 * @param registry
 * 		(optional) the {@link GuiceRegistry} to expose to the guice environment
 * @param scannerFactory
 * 		the classpath scanner
 * @param config
 * 		the system configuration
 * @param setup
 * 		the setup class
 * @param roles
 * 		guice roles to use
 *
 * @return
 */
private static Injector createInjector(GuiceRegistry registry, ClassScannerFactory scannerFactory, GuiceConfig config, GuiceSetup setup, List<GuiceRole> roles) {
    final long started = System.currentTimeMillis();
    AtomicReference<Injector> injectorRef = new AtomicReference<>();
    List<Module> modules = new ArrayList<>();
    final Stage stage = Stage.valueOf(config.get(GuiceProperties.STAGE_PROPERTY, Stage.DEVELOPMENT.name()));
    // Set up the shutdown module
    ShutdownModule shutdown = new ShutdownModule();
    // If a service manager endpoint is specified (and skip isn't set) then set up the service manager client
    if (config.get("service.service-manager.endpoint") != null && !config.getBoolean(GuiceProperties.SERVICE_MANAGER_SKIP, false)) {
        modules.add(new ServiceManagerClientGuiceModule(config, shutdown.getShutdownManager()));
    } else {
        // Don't store logs in memory waiting for the service manager, they will never be picked up
        ServiceManagerAppender.shutdown();
    }
    final MetricRegistry metricRegistry = CoreMetricsModule.buildRegistry();
    try {
        // Hold a strong reference to the ClassScanner instance to help the JVM not garbage collect it during startup
        // N.B. we don't actually do anything with the scanner in this method (other than read metrics)
        final ClassScanner scanner = scannerFactory.getInstance();
        modules.add(shutdown);
        if (registry != null)
            modules.add(new GuiceRegistryModule(registry));
        // Initialise all the roles
        for (GuiceRole role : roles) role.register(stage, scannerFactory, config, setup, modules, injectorRef, metricRegistry);
        // Initialise the Setup class
        setup.registerModules(modules, config);
        if (log.isTraceEnabled())
            log.trace("Creating Injector with modules: " + modules);
        final Injector injector = Guice.createInjector(stage, modules);
        injectorRef.set(injector);
        for (GuiceRole role : roles) role.injectorCreated(stage, scannerFactory, config, setup, modules, injectorRef, metricRegistry);
        setup.injectorCreated(injector);
        if (scannerFactory != null) {
            final long finished = System.currentTimeMillis();
            final String contextName = config.get(GuiceProperties.SERVLET_CONTEXT_NAME, "(app)");
            log.debug("Injector for " + contextName + " created in " + (finished - started) + " ms");
            if (scanner != null)
                log.debug("Class scanner stats: insts=" + scannerFactory.getMetricNewInstanceCount() + " cached createTime=" + scanner.getConstructionTime() + ", scanTime=" + scanner.getSearchTime());
        }
        return injector;
    } catch (Throwable t) {
        log.error("Error creating injector", t);
        shutdown.shutdown();
        throw t;
    }
}
Also used : MetricRegistry(com.codahale.metrics.MetricRegistry) ArrayList(java.util.ArrayList) AtomicReference(java.util.concurrent.atomic.AtomicReference) ServiceManagerClientGuiceModule(com.peterphi.std.guice.common.logging.ServiceManagerClientGuiceModule) GuiceRole(com.peterphi.std.guice.apploader.GuiceRole) NetworkConfigGuiceRole(com.peterphi.std.guice.common.serviceprops.net.NetworkConfigGuiceRole) ClassScanner(com.peterphi.std.guice.common.ClassScanner) Injector(com.google.inject.Injector) ShutdownModule(com.peterphi.std.guice.common.shutdown.ShutdownModule) Stage(com.google.inject.Stage) Module(com.google.inject.Module) ServiceManagerClientGuiceModule(com.peterphi.std.guice.common.logging.ServiceManagerClientGuiceModule) CoreMetricsModule(com.peterphi.std.guice.common.metrics.CoreMetricsModule) ShutdownModule(com.peterphi.std.guice.common.shutdown.ShutdownModule)

Example 2 with ClassScanner

use of com.peterphi.std.guice.common.ClassScanner in project stdlib by petergeneric.

the class AutoHibernateModule method configure.

@Override
protected void configure(final Configuration config) {
    final ClassScanner scanner = scannerFactory.getInstance();
    if (scanner == null)
        throw new IllegalArgumentException("No classpath scanner available, missing scan.packages?");
    for (Class<?> clazz : scanner.getAnnotatedClasses(Entity.class)) {
        log.trace("Registering @Entity class with hibernate: " + clazz.getName());
        config.addAnnotatedClass(clazz);
    }
}
Also used : ClassScanner(com.peterphi.std.guice.common.ClassScanner)

Example 3 with ClassScanner

use of com.peterphi.std.guice.common.ClassScanner in project stdlib by petergeneric.

the class BindEagerSingletonRole method register.

@Override
public void register(final Stage stage, final ClassScannerFactory scannerFactory, final GuiceConfig config, final GuiceSetup setup, final List<Module> modules, final AtomicReference<Injector> injectorRef, final MetricRegistry metrics) {
    final ClassScanner scanner = scannerFactory.getInstance();
    if (scanner != null) {
        final List<Class<?>> classes = scanner.getAnnotatedClasses(EagerSingleton.class);
        final boolean isTestEnvironment = config.getBoolean(GuiceProperties.UNIT_TEST, false);
        Iterator<Class<?>> it = classes.iterator();
        while (it.hasNext()) {
            final Class<?> clazz = it.next();
            if (isTestEnvironment) {
                final EagerSingleton annotation = clazz.getAnnotation(EagerSingleton.class);
                // We're in a test environment but inTests isn't true, so we should ignore this annotation
                if (!annotation.inTests()) {
                    log.trace("Ignoring eager singleton with inTests=false: " + clazz);
                    it.remove();
                    continue;
                }
            }
            log.trace("Binding eager singleton: " + clazz);
        }
        if (!classes.isEmpty())
            modules.add(new BindEagerSingletonModule(classes));
    }
}
Also used : EagerSingleton(com.peterphi.std.guice.common.eagersingleton.annotations.EagerSingleton) ClassScanner(com.peterphi.std.guice.common.ClassScanner)

Example 4 with ClassScanner

use of com.peterphi.std.guice.common.ClassScanner in project stdlib by petergeneric.

the class AutoJAXRSBindingGuiceRole method register.

@Override
public void register(final Stage stage, final ClassScannerFactory scannerFactory, final GuiceConfig config, final GuiceSetup setup, final List<Module> modules, final AtomicReference<Injector> injectorRef, final MetricRegistry metrics) {
    // TODO remove HACK Don't run if we're within a unit test (this is an ugly hack...)
    if (!config.getBoolean(GuiceProperties.UNIT_TEST, false)) {
        final ClassScanner scanner = scannerFactory.getInstance();
        if (scanner == null)
            throw new IllegalArgumentException("No classpath scanner available, missing scan.packages?");
        // Optionally set up JAX-RS Service and Client bindings
        if (config.getBoolean(GuiceProperties.ROLE_JAXRS_SERVER_AUTO, true)) {
            modules.add(new JAXRSAutoRegisterServicesModule(config, scannerFactory));
        }
        // Set up authentication and authorisation logic
        {
            // Set up authentication
            {
                // Set up provider for CurrentUser
                List<String> authProviderNames = config.getList(GuiceProperties.AUTH_PROVIDER_NAMES, null);
                // If no providers set, pick up the defaults based on what's configured
                if (authProviderNames == null || authProviderNames.size() == 0) {
                    authProviderNames = new ArrayList<>();
                    // Set up JWT if a jwt secret is set
                    if (config.containsKey(GuiceProperties.AUTH_JWT_SECRET))
                        authProviderNames.add(GuiceConstants.JAXRS_SERVER_WEBAUTH_JWT_PROVIDER);
                    // Set up OAuth2 if an OAuth2 endpoint is set
                    if (config.containsKey(GuiceProperties.OAUTH2_CLIENT_ENDPOINT)) {
                        // OAuth2 present, anonymous CurrentUser can be claimed by oauth2 provider
                        authProviderNames.add(GuiceConstants.JAXRS_SERVER_WEBAUTH_OAUTH2_PROVIDER);
                    } else {
                        // OAuth2 not present, anonymous CurrentUser can be claimed by servlet provider
                        authProviderNames.add(GuiceConstants.JAXRS_SERVER_WEBAUTH_SERVLET_PROVIDER);
                    }
                }
                // N.B. WebappAuthenticationModule handles JWT and Servlet providers
                if (authProviderNames.contains(GuiceConstants.JAXRS_SERVER_WEBAUTH_OAUTH2_PROVIDER))
                    modules.add(new OAuth2ClientModule());
                modules.add(new WebappAuthenticationModule(metrics, authProviderNames, config));
            }
            // Optionally set up authorisation
            if (config.getBoolean(GuiceProperties.AUTH_ENABLED, true))
                modules.add(new AuthConstraintInterceptorModule(metrics, config));
        }
    }
}
Also used : WebappAuthenticationModule(com.peterphi.std.guice.web.rest.auth.userprovider.WebappAuthenticationModule) ClassScanner(com.peterphi.std.guice.common.ClassScanner) OAuth2ClientModule(com.peterphi.std.guice.web.rest.auth.oauth2.OAuth2ClientModule) AuthConstraintInterceptorModule(com.peterphi.std.guice.web.rest.auth.interceptor.AuthConstraintInterceptorModule)

Aggregations

ClassScanner (com.peterphi.std.guice.common.ClassScanner)4 MetricRegistry (com.codahale.metrics.MetricRegistry)1 Injector (com.google.inject.Injector)1 Module (com.google.inject.Module)1 Stage (com.google.inject.Stage)1 GuiceRole (com.peterphi.std.guice.apploader.GuiceRole)1 EagerSingleton (com.peterphi.std.guice.common.eagersingleton.annotations.EagerSingleton)1 ServiceManagerClientGuiceModule (com.peterphi.std.guice.common.logging.ServiceManagerClientGuiceModule)1 CoreMetricsModule (com.peterphi.std.guice.common.metrics.CoreMetricsModule)1 NetworkConfigGuiceRole (com.peterphi.std.guice.common.serviceprops.net.NetworkConfigGuiceRole)1 ShutdownModule (com.peterphi.std.guice.common.shutdown.ShutdownModule)1 AuthConstraintInterceptorModule (com.peterphi.std.guice.web.rest.auth.interceptor.AuthConstraintInterceptorModule)1 OAuth2ClientModule (com.peterphi.std.guice.web.rest.auth.oauth2.OAuth2ClientModule)1 WebappAuthenticationModule (com.peterphi.std.guice.web.rest.auth.userprovider.WebappAuthenticationModule)1 ArrayList (java.util.ArrayList)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1