All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.trino.gateway.baseapp.BaseApp Maven / Gradle / Ivy

/*
 * 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 io.trino.gateway.baseapp;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.MoreCollectors;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import io.airlift.log.Logger;
import io.dropwizard.auth.AuthDynamicFeature;
import io.dropwizard.auth.AuthFilter;
import io.dropwizard.core.Application;
import io.dropwizard.core.Configuration;
import io.dropwizard.core.server.DefaultServerFactory;
import io.dropwizard.core.setup.Environment;
import io.dropwizard.lifecycle.Managed;
import io.dropwizard.lifecycle.setup.LifecycleEnvironment;
import io.trino.gateway.ha.config.HaGatewayConfiguration;
import io.trino.gateway.ha.log.GatewayRequestLogFactory;
import io.trino.gateway.ha.module.RouterBaseModule;
import io.trino.gateway.ha.module.StochasticRoutingManagerProvider;
import io.trino.gateway.ha.resource.EntityEditorResource;
import io.trino.gateway.ha.resource.GatewayResource;
import io.trino.gateway.ha.resource.GatewayViewResource;
import io.trino.gateway.ha.resource.GatewayWebAppResource;
import io.trino.gateway.ha.resource.HaGatewayResource;
import io.trino.gateway.ha.resource.LoginResource;
import io.trino.gateway.ha.resource.PublicResource;
import io.trino.gateway.ha.resource.TrinoResource;
import io.trino.gateway.ha.security.AuthorizedExceptionMapper;
import org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import static java.lang.String.format;

/**
 * Supports Guice in Dropwizard.
 *
 * 

To use it, create a subclass and provide a list of modules you want to use with the {@link * #addModules} method. * *

Packages supplied in the constructor will be scanned for Resources, Providers, and Managed * classes, and added to the environment. * *

GuiceApplication also makes {@link com.codahale.metrics.MetricRegistry} available for * injection. */ public abstract class BaseApp extends Application { private static final Logger logger = Logger.get(BaseApp.class); private final ImmutableList.Builder appModules = ImmutableList.builder(); private Module newModule(String clazz, HaGatewayConfiguration configuration, Environment environment) { try { logger.info("Trying to load module [%s]", clazz); // Modules must have exactly one constructor. The signature must be either one: // public Module constructor(HaGatewayConfiguration) // public Module constructor(HaGatewayConfiguration, Environment) Constructor[] constructors = Class.forName(clazz).getConstructors(); if (constructors.length != 1) { throw new RuntimeException(format("Failed to load module [%s]. Multiple constructors exist.", clazz)); } Constructor constructor = constructors[0]; Object module = switch (constructor.getParameterCount()) { case 1 -> constructor.newInstance(configuration); case 2 -> constructor.newInstance(configuration, environment); default -> throw new RuntimeException(format("Failed to load module [%s]. Unsupported constructor.", clazz)); }; return ((Module) module); } catch (Exception e) { logger.error(e, "Could not instantiate module [%s]", clazz); onFatalError(e); } return null; } private void validateModules(List modules, HaGatewayConfiguration configuration, Environment environment) { Optional routerProvider = modules.stream() .filter(module -> module instanceof RouterBaseModule) .collect(MoreCollectors.toOptional()); if (routerProvider.isEmpty()) { logger.warn("Router provider doesn't exist in the config, using the StochasticRoutingManagerProvider"); String clazz = StochasticRoutingManagerProvider.class.getCanonicalName(); modules.add(newModule(clazz, configuration, environment)); } } @Override // Using Airlift logger protected void bootstrapLogging() {} /** * When the application runs, this is called after the bundles are run. * * @param configuration the parsed {@link Configuration} object * @param environment the application's {@link Environment} * @throws Exception if something goes wrong */ @Override public void run(HaGatewayConfiguration configuration, Environment environment) throws Exception { ((DefaultServerFactory) configuration.getServerFactory()).setRequestLogFactory(new GatewayRequestLogFactory()); configureGuice(configuration, environment); } private void configureGuice(HaGatewayConfiguration configuration, Environment environment) { appModules.add(new MetricRegistryModule(environment.metrics())); appModules.addAll(addModules(configuration, environment)); Injector injector = Guice.createInjector(appModules.build()); injector.injectMembers(this); registerWithInjector(configuration, environment, injector); } private void registerWithInjector(HaGatewayConfiguration configuration, Environment environment, Injector injector) { logger.info("op=register_start configuration=%s", configuration.toString()); registerAuthFilters(environment, injector); registerProviders(environment, injector); addManagedApps(configuration, environment, injector); registerResources(environment, injector); logger.info("op=register_end configuration=%s", configuration.toString()); } /** * Supply a list of modules to be used by Guice. * * @param configuration the app configuration * @return a list of modules to be provisioned by Guice */ protected List addModules(HaGatewayConfiguration configuration, Environment environment) { List modules = new ArrayList<>(); if (configuration.getModules() == null) { logger.warn("No modules to load."); return modules; } for (String clazz : configuration.getModules()) { modules.add(newModule(clazz, configuration, environment)); } validateModules(modules, configuration, environment); return modules; } /** * Supply a list of managed apps. */ protected List addManagedApps( HaGatewayConfiguration configuration, Environment environment, Injector injector) { List managedApps = new ArrayList<>(); if (configuration.getManagedApps() == null) { logger.error("No managed apps found"); return managedApps; } configuration .getManagedApps() .forEach( clazz -> { try { Class c = Class.forName(clazz); LifecycleEnvironment lifecycle = environment.lifecycle(); lifecycle.manage((Managed) injector.getInstance(c)); logger.info("op=register type=managed item=%s", c); } catch (Exception e) { logger.error(e, "Error loading managed app"); } }); return managedApps; } private void registerProviders(Environment environment, Injector injector) { final Set> classes = ImmutableSet.of(AuthorizedExceptionMapper.class); classes.forEach( c -> { environment.jersey().register(injector.getInstance(c)); logger.info("op=register type=provider item=%s", c); }); } private void registerResources(Environment environment, Injector injector) { final Set> classes = ImmutableSet.of( EntityEditorResource.class, GatewayResource.class, GatewayViewResource.class, GatewayWebAppResource.class, HaGatewayResource.class, LoginResource.class, PublicResource.class, TrinoResource.class); classes.forEach( c -> { environment.jersey().register(injector.getInstance(c)); logger.info("op=register type=resource item=%s", c); }); } private void registerAuthFilters(Environment environment, Injector injector) { environment .jersey() .register(new AuthDynamicFeature(injector.getInstance(AuthFilter.class))); logger.info("op=register type=auth filter item=%s", AuthFilter.class); environment.jersey().register(RolesAllowedDynamicFeature.class); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy