From 443e4ed16b82dd51b251723e6a365ec8dcc08618 Mon Sep 17 00:00:00 2001 From: Ke Wang Date: Thu, 19 Mar 2015 17:11:39 +0000 Subject: [PATCH] Environment bean needs to be created before refreshing the spring root context as it needs to collect the ModuleBeans. No need for AccessLogLocationBean @Component or @Autowired addAccessLog method in GrizzlyApplication class need to handle context where there are slashes in the context --- .../com/aol/micro/server/config/Classes.java | 27 ++--- .../server/module/ConfigureEnviroment.java | 25 ++++ .../aol/micro/server/module/Environment.java | 24 ++-- .../server/servers/AccessLogLocationBean.java | 8 +- .../servers/grizzly/GrizzlyApplication.java | 87 ++++++-------- .../spring/SpringApplicationConfigurator.java | 108 ++++++------------ .../module/ConfigureEnviromentTest.java | 32 ++++++ 7 files changed, 149 insertions(+), 162 deletions(-) create mode 100644 micro-core/src/main/java/com/aol/micro/server/module/ConfigureEnviroment.java create mode 100644 micro-core/src/test/java/com/aol/micro/server/module/ConfigureEnviromentTest.java diff --git a/micro-core/src/main/java/com/aol/micro/server/config/Classes.java b/micro-core/src/main/java/com/aol/micro/server/config/Classes.java index 65b72f07d..2b795f297 100644 --- a/micro-core/src/main/java/com/aol/micro/server/config/Classes.java +++ b/micro-core/src/main/java/com/aol/micro/server/config/Classes.java @@ -6,6 +6,7 @@ import nonautoscan.com.aol.micro.server.ScheduleAndAsyncConfig; import com.aol.micro.server.events.ConfigureActiveJobsAspect; +import com.aol.micro.server.module.ConfigureEnviroment; import com.aol.micro.server.rest.resources.ConfigureResources; import com.aol.micro.server.spring.datasource.DataSourceBuilder; import com.aol.micro.server.spring.datasource.JdbcConfig; @@ -28,31 +29,25 @@ * */ public enum Classes { - + /** * CORE CLASSES are the Core Microserver Spring Configuration classes * Property support, Guava Event Bus, Spring AOP & Scheduling * Codahale Metrics, Event tracking etc */ - CORE_CLASSES(PropertyFileConfig.class, - MiscellaneousConfig.class, AopConfig.class, CodahaleMetricsConfigurer.class, - ConfigureActiveJobsAspect.class, ScheduleAndAsyncConfig.class,ConfigureResources.class), - JDBC_CLASSES(JdbcConfig.class , - DAOProvider.class,DataSourceBuilder.class,SQL.class,SpringDataConfig.class), - ROMA_ROW_MAPPER(RomaRowMapperConfig.class), - HIBERNATE_CLASSES(HibernateConfig.class,JdbcConfig.class , - GenericHibernateService.class,DAOProvider.class,DataSourceBuilder.class,SQL.class), + CORE_CLASSES(PropertyFileConfig.class, MiscellaneousConfig.class, AopConfig.class, CodahaleMetricsConfigurer.class, + ConfigureActiveJobsAspect.class, ScheduleAndAsyncConfig.class, ConfigureResources.class, ConfigureEnviroment.class), + JDBC_CLASSES(JdbcConfig.class, DAOProvider.class, DataSourceBuilder.class, SQL.class, SpringDataConfig.class), + ROMA_ROW_MAPPER(RomaRowMapperConfig.class), + HIBERNATE_CLASSES(HibernateConfig.class, JdbcConfig.class, GenericHibernateService.class, DAOProvider.class, DataSourceBuilder.class, SQL.class), SPRING_DATA_CLASSES(SpringDataConfig.class), - DATASOURCE_CLASSES(JdbcConfig.class , - DataSourceBuilder.class); - + DATASOURCE_CLASSES(JdbcConfig.class, DataSourceBuilder.class); + @Getter private final Class[] classes; - - private Classes(Class... classes){ + + private Classes(Class... classes) { this.classes = classes; } - } - diff --git a/micro-core/src/main/java/com/aol/micro/server/module/ConfigureEnviroment.java b/micro-core/src/main/java/com/aol/micro/server/module/ConfigureEnviroment.java new file mode 100644 index 000000000..5429b1d64 --- /dev/null +++ b/micro-core/src/main/java/com/aol/micro/server/module/ConfigureEnviroment.java @@ -0,0 +1,25 @@ +package com.aol.micro.server.module; + +import java.util.Collection; +import java.util.Properties; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ConfigureEnviroment { + + @Autowired(required = false) + private Collection modules; + + @Bean + public Environment environment(@Qualifier("propertyFactory") Properties props) { + if (modules == null) { + return new Environment(props); + } + return new Environment(props, modules); + } + +} diff --git a/micro-core/src/main/java/com/aol/micro/server/module/Environment.java b/micro-core/src/main/java/com/aol/micro/server/module/Environment.java index 30c5d8583..49e6d1571 100644 --- a/micro-core/src/main/java/com/aol/micro/server/module/Environment.java +++ b/micro-core/src/main/java/com/aol/micro/server/module/Environment.java @@ -6,21 +6,16 @@ import java.util.Properties; import java.util.stream.Collectors; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; -//@Component public class Environment { private volatile Map modulePort; private final Properties properties; private volatile int nextPort = 8080; - - public Environment(Properties propertyFactory,Collection modules) { + public Environment(Properties propertyFactory, Collection modules) { modulePort = modules.stream().collect(Collectors.toMap(key -> key.getModule().getContext(), value -> value)); this.properties = propertyFactory; } @@ -30,24 +25,23 @@ public Environment(Properties propertyFactory) { this.properties = propertyFactory; } - + public ModuleBean getModuleBean(Module module) { return modulePort.get(module.getContext()); } + public void assureModule(Module module) { - if(!modulePort.containsKey(module.getContext())){ + if (!modulePort.containsKey(module.getContext())) { Map builder = Maps.newHashMap(); builder.putAll(modulePort); - builder.put(module.getContext(),ModuleBean.builder().port(getPort(module)).build()); + builder.put(module.getContext(), ModuleBean.builder().port(getPort(module)).build()); modulePort = ImmutableMap.copyOf(builder); } - - + } + private int getPort(Module module) { - - return Integer.valueOf(Optional.ofNullable( - properties.get(module.getContext()+".port")) - .orElse(nextPort++).toString()); + + return Integer.valueOf(Optional.ofNullable(properties.get(module.getContext() + ".port")).orElse(nextPort++).toString()); } } \ No newline at end of file diff --git a/micro-core/src/main/java/com/aol/micro/server/servers/AccessLogLocationBean.java b/micro-core/src/main/java/com/aol/micro/server/servers/AccessLogLocationBean.java index 0710417f5..1e106713a 100644 --- a/micro-core/src/main/java/com/aol/micro/server/servers/AccessLogLocationBean.java +++ b/micro-core/src/main/java/com/aol/micro/server/servers/AccessLogLocationBean.java @@ -2,18 +2,12 @@ import lombok.Getter; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -@Component @Getter public class AccessLogLocationBean { private final String accessLogLocation; - @Autowired - public AccessLogLocationBean(@Value("${access.log.output:./logs/}") String accessLogLocation) { + public AccessLogLocationBean(String accessLogLocation) { this.accessLogLocation = accessLogLocation; } diff --git a/micro-core/src/main/java/com/aol/micro/server/servers/grizzly/GrizzlyApplication.java b/micro-core/src/main/java/com/aol/micro/server/servers/grizzly/GrizzlyApplication.java index 40270f7b6..392a8a770 100644 --- a/micro-core/src/main/java/com/aol/micro/server/servers/grizzly/GrizzlyApplication.java +++ b/micro-core/src/main/java/com/aol/micro/server/servers/grizzly/GrizzlyApplication.java @@ -16,7 +16,6 @@ import org.glassfish.grizzly.http.server.accesslog.AccessLogBuilder; import org.glassfish.grizzly.servlet.ServletRegistration; import org.glassfish.grizzly.servlet.WebappContext; -import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.servlet.ServletContainer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,21 +31,21 @@ import com.aol.simple.react.exceptions.ExceptionSoftener; import com.google.common.collect.ImmutableList; -@AllArgsConstructor(access=AccessLevel.PRIVATE) -public class GrizzlyApplication implements ServerApplication { +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class GrizzlyApplication implements ServerApplication { private final Logger logger = LoggerFactory.getLogger(getClass()); private final ExceptionSoftener softener = ExceptionSoftener.singleton.factory.getInstance(); @Getter private final ServerData serverData; - + private final ImmutableList filterData; private final ImmutableList servletData; private final ImmutableList servletContextListenerData; @Wither private final SSLProperties SSLProperties; - + public GrizzlyApplication(AllData serverData) { this.serverData = serverData.getServerData(); this.filterData = serverData.getFilterDataList(); @@ -55,45 +54,42 @@ public GrizzlyApplication(AllData serverData) { this.SSLProperties = null; } - public void run(CompletableFuture start,CompletableFuture end) { + public void run(CompletableFuture start, CompletableFuture end) { WebappContext webappContext = new WebappContext("WebappContext", ""); - new ServletContextListenerConfigurer(serverData,servletContextListenerData); - + new ServletContextListenerConfigurer(serverData, servletContextListenerData); + addServlet(webappContext); - new ServletConfigurer(serverData,servletData).addServlets(webappContext); + new ServletConfigurer(serverData, servletData).addServlets(webappContext); - new FilterConfigurer(serverData,this.filterData).addFilters(webappContext); + new FilterConfigurer(serverData, this.filterData).addFilters(webappContext); addListeners(webappContext); - HttpServer httpServer = HttpServer.createSimpleServer(null, "0.0.0.0", - serverData.getPort()); + HttpServer httpServer = HttpServer.createSimpleServer(null, "0.0.0.0", serverData.getPort()); addAccessLog(httpServer); - if(SSLProperties!=null) + if (SSLProperties != null) this.createSSLListener(serverData.getPort()); - startServer(webappContext, httpServer,start,end); + startServer(webappContext, httpServer, start, end); } - private void startServer(WebappContext webappContext, HttpServer httpServer, CompletableFuture start, CompletableFuture end) { + private void startServer(WebappContext webappContext, HttpServer httpServer, CompletableFuture start, CompletableFuture end) { webappContext.deploy(httpServer); try { - logger.info("Starting application {} on port {}", serverData - .getModule().getContext(), serverData.getPort()); - logger.info("Browse to http://localhost:{}/{}/application.wadl", - serverData.getPort(), serverData.getModule().getContext()); + logger.info("Starting application {} on port {}", serverData.getModule().getContext(), serverData.getPort()); + logger.info("Browse to http://localhost:{}/{}/application.wadl", serverData.getPort(), serverData.getModule().getContext()); logger.info("Configured resource classes :-"); - serverData.extractResources() - .forEach(t -> logger.info(t.v1 + " : " + "http://localhost:"+serverData.getPort() - +"/"+serverData.getModule().getContext() + t.v2 ));; + serverData.extractResources().forEach( + t -> logger.info(t.v1 + " : " + "http://localhost:" + serverData.getPort() + "/" + serverData.getModule().getContext() + t.v2)); + ; httpServer.start(); start.complete(true); end.get(); - + } catch (IOException e) { softener.throwSoftenedException(e); } catch (ExecutionException e) { @@ -108,22 +104,19 @@ private void startServer(WebappContext webappContext, HttpServer httpServer, Com private void addAccessLog(HttpServer httpServer) { try { - String accessLogLocation = serverData.getRootContext() - .getBean(AccessLogLocationBean.class) - .getAccessLogLocation(); - final AccessLogBuilder builder = new AccessLogBuilder( - accessLogLocation + serverData.getModule().getContext() - + "-access.log"); + String accessLogLocation = serverData.getRootContext().getBean(AccessLogLocationBean.class).getAccessLogLocation(); + + accessLogLocation = accessLogLocation + + serverData.getModule().getContext().substring(0, serverData.getModule().getContext().indexOf("/")) + "-access.log"; + final AccessLogBuilder builder = new AccessLogBuilder(accessLogLocation); + builder.rotatedDaily(); builder.rotationPattern("yyyy-MM-dd"); builder.instrument(httpServer.getServerConfiguration()); } catch (Exception e) { - logger.error(ErrorCode.SERVER_STARTUP_FAILED_TO_CREATE_ACCESS_LOG - .toString() + ": " + e.getMessage()); + logger.error(ErrorCode.SERVER_STARTUP_FAILED_TO_CREATE_ACCESS_LOG.toString() + ": " + e.getMessage()); if (e.getCause() != null) - logger.error("CAUSED BY: " - + ErrorCode.SERVER_STARTUP_FAILED_TO_CREATE_ACCESS_LOG - .toString() + ": " + e.getCause().getMessage()); + logger.error("CAUSED BY: " + ErrorCode.SERVER_STARTUP_FAILED_TO_CREATE_ACCESS_LOG.toString() + ": " + e.getCause().getMessage()); } @@ -131,35 +124,27 @@ private void addAccessLog(HttpServer httpServer) { private void addServlet(WebappContext webappContext) { ServletContainer container = new ServletContainer(); - ServletRegistration servletRegistration = webappContext.addServlet( - "Jersey Spring Web Application", container); - servletRegistration.setInitParameter("javax.ws.rs.Application", - this.serverData.getModule().getJaxWsRsApplication()); - servletRegistration.setInitParameter( - "jersey.config.server.provider.packages", this.serverData - .getModule().getProviders()); + ServletRegistration servletRegistration = webappContext.addServlet("Jersey Spring Web Application", container); + servletRegistration.setInitParameter("javax.ws.rs.Application", this.serverData.getModule().getJaxWsRsApplication()); + servletRegistration.setInitParameter("jersey.config.server.provider.packages", this.serverData.getModule().getProviders()); servletRegistration.setLoadOnStartup(1); servletRegistration.addMapping(serverData.getBaseUrlPattern()); } + private NetworkListener createSSLListener(int port) { - - private NetworkListener createSSLListener(int port){ - - - SSLConfigurationBuilder sslBuilder = new SSLConfigurationBuilder(); NetworkListener listener = new NetworkListener("grizzly", "0.0.0.0", Integer.valueOf(port)); listener.getFileCache().setEnabled(false); - - listener.setSecure(true); - listener.setSSLEngineConfig(sslBuilder.build(SSLProperties)); - + + listener.setSecure(true); + listener.setSSLEngineConfig(sslBuilder.build(SSLProperties)); + return listener; } private void addListeners(WebappContext webappContext) { - + new ServletContextListenerConfigurer(serverData, servletContextListenerData).addListeners(webappContext); } diff --git a/micro-core/src/main/java/com/aol/micro/server/spring/SpringApplicationConfigurator.java b/micro-core/src/main/java/com/aol/micro/server/spring/SpringApplicationConfigurator.java index be3dbe5ee..b8aa69462 100644 --- a/micro-core/src/main/java/com/aol/micro/server/spring/SpringApplicationConfigurator.java +++ b/micro-core/src/main/java/com/aol/micro/server/spring/SpringApplicationConfigurator.java @@ -1,7 +1,5 @@ package com.aol.micro.server.spring; - -import java.util.Map; import java.util.Optional; import java.util.Properties; import java.util.stream.Stream; @@ -19,8 +17,6 @@ import com.aol.micro.server.config.Config; import com.aol.micro.server.config.ConfigAccessor; import com.aol.micro.server.config.Microserver; -import com.aol.micro.server.module.Environment; -import com.aol.micro.server.module.ModuleBean; import com.aol.micro.server.servers.AccessLogLocationBean; import com.aol.micro.server.spring.datasource.DataSourceBuilder; import com.aol.micro.server.spring.datasource.JdbcConfig; @@ -31,102 +27,68 @@ class SpringApplicationConfigurator implements SpringBuilder { private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public ConfigurableApplicationContext createSpringApp(Config config, Class...classes) { - + + public ConfigurableApplicationContext createSpringApp(Config config, Class... classes) { + logger.debug("Configuring Spring"); AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); rootContext.setAllowCircularReferences(config.isAllowCircularReferences()); rootContext.register(classes); - - Optional basePackage = Stream.of(classes) - .filter(cl -> cl.getAnnotation(Microserver.class)!=null) - .map(cl -> cl.getPackage()).findAny(); - basePackage.ifPresent( base-> - rootContext.scan(Stream.of(classes) - .map(cl -> cl.getAnnotation(Microserver.class)) - .filter(ano -> ano!=null) - .map(ano -> ((Microserver)ano).basePackages()) - .map(packages -> UsefulStaticMethods.eitherArray(packages,new String[]{base.getName()})) - .findFirst().get())); - - - + + Optional basePackage = Stream.of(classes).filter(cl -> cl.getAnnotation(Microserver.class) != null).map(cl -> cl.getPackage()) + .findAny(); + basePackage.ifPresent(base -> rootContext.scan(Stream.of(classes).map(cl -> cl.getAnnotation(Microserver.class)).filter(ano -> ano != null) + .map(ano -> ((Microserver) ano).basePackages()) + .map(packages -> UsefulStaticMethods.eitherArray(packages, new String[] { base.getName() })).findFirst().get())); + rootContext.refresh(); logger.debug("Configuring Additional Spring Beans"); ConfigurableListableBeanFactory beanFactory = ((ConfigurableApplicationContext) rootContext).getBeanFactory(); - beanFactory.registerSingleton(Environment.class.getCanonicalName(), createEnvironment( rootContext)); - beanFactory.registerSingleton(AccessLogLocationBean.class.getCanonicalName(), createAccessLogLocationBean( rootContext)); - + + beanFactory.registerSingleton(AccessLogLocationBean.class.getCanonicalName(), createAccessLogLocationBean(rootContext)); + config.getDataSources().keySet().stream().filter(it -> !new ConfigAccessor().get().getDefaultDataSourceName().equals(it)).forEach(name -> { JdbcConfig jdbc = buildJdbcProperties(rootContext, name); - DataSource dataSource = buildDataSource(name,jdbc); - SessionFactory sessionFactory = buildSession(name,config,dataSource,jdbc); - beanFactory.registerSingleton(name+"DataSource", dataSource); - beanFactory.registerSingleton(name+"SessionFactory",sessionFactory); - beanFactory.registerSingleton(name+"HibernateTransactionManager", buildTransactionManager(name,config, dataSource,jdbc)); - beanFactory.registerSingleton(name+"DAOProvider", buildDAOProvider(rootContext, sessionFactory)); - + DataSource dataSource = buildDataSource(name, jdbc); + SessionFactory sessionFactory = buildSession(name, config, dataSource, jdbc); + beanFactory.registerSingleton(name + "DataSource", dataSource); + beanFactory.registerSingleton(name + "SessionFactory", sessionFactory); + beanFactory.registerSingleton(name + "HibernateTransactionManager", buildTransactionManager(name, config, dataSource, jdbc)); + beanFactory.registerSingleton(name + "DAOProvider", buildDAOProvider(rootContext, sessionFactory)); + }); logger.debug("Finished Configuring Spring"); - + return rootContext; } - - - private DAOProvider buildDAOProvider( - AnnotationConfigWebApplicationContext rootContext, - SessionFactory sessionFactory) { - + private DAOProvider buildDAOProvider(AnnotationConfigWebApplicationContext rootContext, SessionFactory sessionFactory) { + return DAOBuilder.builder().applicationContext(rootContext).factory(sessionFactory).build().daoProvider(); } - - - - - - - private HibernateTransactionManager buildTransactionManager(String name,Config config,DataSource dataSource, JdbcConfig jdbc) { - return HibernateSessionBuilder.builder().packages(config.getDataSources().get(name)).dataSource(dataSource).env(jdbc).build().transactionManager(); + private HibernateTransactionManager buildTransactionManager(String name, Config config, DataSource dataSource, JdbcConfig jdbc) { + return HibernateSessionBuilder.builder().packages(config.getDataSources().get(name)).dataSource(dataSource).env(jdbc).build() + .transactionManager(); } - private SessionFactory buildSession(String name, Config config,DataSource dataSource, JdbcConfig jdbc) { - - return HibernateSessionBuilder.builder().packages(config.getDataSources().get(name)).dataSource(dataSource).env(jdbc).build().sessionFactory(); + private SessionFactory buildSession(String name, Config config, DataSource dataSource, JdbcConfig jdbc) { + + return HibernateSessionBuilder.builder().packages(config.getDataSources().get(name)).dataSource(dataSource).env(jdbc).build() + .sessionFactory(); } private DataSource buildDataSource(String name, JdbcConfig jdbc) { return DataSourceBuilder.builder().env(jdbc).build().mainDataSource(); } - - private JdbcConfig buildJdbcProperties(AnnotationConfigWebApplicationContext rootContext,String name) { - return JdbcConfig.builder().properties((Properties)rootContext.getBean("propertyFactory")).name(name).build(); + private JdbcConfig buildJdbcProperties(AnnotationConfigWebApplicationContext rootContext, String name) { + return JdbcConfig.builder().properties((Properties) rootContext.getBean("propertyFactory")).name(name).build(); } - - private AccessLogLocationBean createAccessLogLocationBean( - AnnotationConfigWebApplicationContext rootContext) { - Properties props = (Properties)rootContext.getBean("propertyFactory"); - String location = Optional.ofNullable((String)props.get("access.log.output")).orElse("./logs/"); + private AccessLogLocationBean createAccessLogLocationBean(AnnotationConfigWebApplicationContext rootContext) { + Properties props = (Properties) rootContext.getBean("propertyFactory"); + String location = Optional.ofNullable((String) props.get("access.log.output")).orElse("./logs/"); return new AccessLogLocationBean(location); } - - - - private Environment createEnvironment( - AnnotationConfigWebApplicationContext rootContext) { - Properties props = (Properties)rootContext.getBean("propertyFactory"); - Map moduleDefinitions = rootContext.getBeansOfType(ModuleBean.class); - if(moduleDefinitions ==null) - return new Environment(props); - return new Environment(props,moduleDefinitions.values()); - - } - - - - } diff --git a/micro-core/src/test/java/com/aol/micro/server/module/ConfigureEnviromentTest.java b/micro-core/src/test/java/com/aol/micro/server/module/ConfigureEnviromentTest.java new file mode 100644 index 000000000..4e390aade --- /dev/null +++ b/micro-core/src/test/java/com/aol/micro/server/module/ConfigureEnviromentTest.java @@ -0,0 +1,32 @@ +package com.aol.micro.server.module; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Properties; + +import org.junit.Before; +import org.junit.Test; + +public class ConfigureEnviromentTest { + + ConfigureEnviroment configureEnviroment = new ConfigureEnviroment(); + ModuleBean moduleBean; + + @Before + public void setUp() { + moduleBean = ModuleBean.builder().port(8080).host("host").module(() -> "simple").build(); + } + + @Test + public void testEnvironmentNoModules() { + Environment environment = configureEnviroment.environment(new Properties()); + assertThat(environment.getModuleBean(() -> "simple") == null, is(true)); + } + + @Test + public void testEnvironment() { + Environment environment = configureEnviroment.environment(new Properties()); + assertThat(environment.getModuleBean(() -> "simple") == null, is(true)); + } +}