/*
* This software is licensed under the Apache License, Version 2.0
* (the "License") agreement; 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 org.moneta.config.springboot;
import net.admin4j.ui.servlets.MemoryMonitorStartupServlet;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.force66.correlate.RequestCorrelationFilter;
import org.moneta.MonetaPerformanceFilter;
import org.moneta.MonetaServlet;
import org.moneta.MonetaTopicListServlet;
import org.moneta.config.MonetaConfiguration;
import org.moneta.config.MonetaEnvironment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.jetty.JettyServerCustomizer;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import com.codahale.metrics.JmxReporter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.health.HealthCheckRegistry;
/**
* Spring boot application for Moneta
* @author D. Ashmore
*
*/
@Configuration
@EnableAutoConfiguration
@ConfigurationProperties
@ComponentScan("org.moneta")
@Component
public class MonetaSpringBootApplication extends SpringBootServletInitializer {
public static final Integer DEFAULT_SERVER_MAX_THREADS = 20;
public static final Integer DEFAULT_SERVER_MIN_THREADS = 2;
public static final Integer DEFAULT_SERVER_IDLE_TIMEOUT = 30;
private static Logger logger = LoggerFactory.getLogger(MonetaSpringBootApplication.class);
public static void main(String[] args) {
SpringApplication.run(MonetaSpringBootApplication.class, args);
// Find and read application configuration
MonetaConfiguration config = new MonetaConfiguration();
// Install all health checks
HealthCheckRegistry registry = new HealthCheckRegistry();
for (String checkName : MonetaEnvironment.getConfiguration()
.getHealthChecks()
.keySet()) {
registry.register(checkName, MonetaEnvironment.getConfiguration()
.getHealthChecks()
.get(checkName));
}
ActuatorHealthIndicator.setHealthCheckRegistry(registry);
// Install metrics and JMX
MetricRegistry metricRegistry = new MetricRegistry();
final JmxReporter jmxReporter = JmxReporter.forRegistry(metricRegistry)
.build();
jmxReporter.start();
}
@Value("${moneta.server.max.threads}")
private Integer serverMaxThreads;
@Value("${moneta.server.min.threads}")
private Integer serverMinThreads;
@Value("${moneta.server.idle.timeout}")
private Integer serverIdleTimeout;
protected Integer deriveValue(Integer configuredValue, Integer defaultValue) {
if (configuredValue == null) {
return defaultValue;
}
return configuredValue;
}
@Bean
public ServletRegistrationBean memoryMonitorStartupServlet() {
ServletRegistrationBean registration =
new ServletRegistrationBean(new MemoryMonitorStartupServlet(), "/admin4j/memory");
registration.setLoadOnStartup(1);
return registration;
}
/*
* Withdrawn after issue discovered with jetty
*/
// @Bean
// public ServletRegistrationBean threadStartupServlet() {
// ServletRegistrationBean registration =
// new ServletRegistrationBean(new ThreadMonitorStartupServlet(), "/admin4j/threads");
// registration.setLoadOnStartup(1);
// return registration;
// }
@Bean
public FilterRegistrationBean monetaPerformanceFilter() {
FilterRegistrationBean registration =
new FilterRegistrationBean(new MonetaPerformanceFilter(),
monetaServlet(), monetaTopicListServlet());
return registration;
}
@Bean
public ServletRegistrationBean monetaServlet() {
ServletRegistrationBean registration =
new ServletRegistrationBean(new MonetaServlet(),
"/moneta/topic/*");
registration.addInitParameter(
MonetaServlet.CONFIG_IGNORED_CONTEXT_PATH_NODES, "moneta,topic");
return registration;
}
@Bean
public ServletRegistrationBean monetaTopicListServlet() {
ServletRegistrationBean registration =
new ServletRegistrationBean(new MonetaTopicListServlet(),
"/moneta/topics/*");
return registration;
}
@Bean
public FilterRegistrationBean reportCorrelationFilter() {
FilterRegistrationBean registration =
new FilterRegistrationBean(new RequestCorrelationFilter(),
monetaServlet(), monetaTopicListServlet());
return registration;
}
@Bean
public EmbeddedServletContainerFactory servletContainer() {
JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory();
factory.addServerCustomizers(new JettyServerCustomizer() {
public void customize(final Server server) {
// Tweak the connection pool used by Jetty to handle incoming
// HTTP connections
Integer localServerMaxThreads = deriveValue(serverMaxThreads,
DEFAULT_SERVER_MAX_THREADS);
Integer localServerMinThreads = deriveValue(serverMinThreads,
DEFAULT_SERVER_MIN_THREADS);
Integer localServerIdleTimeout = deriveValue(serverIdleTimeout,
DEFAULT_SERVER_IDLE_TIMEOUT);
logger.info("Container Max Threads={}", localServerMaxThreads);
logger.info("Container Min Threads={}", localServerMinThreads);
logger.info("Container Idle Timeout={}", localServerIdleTimeout);
final QueuedThreadPool threadPool = server.getBean(QueuedThreadPool.class);
threadPool.setMaxThreads(Integer.valueOf(localServerMaxThreads));
threadPool.setMinThreads(Integer.valueOf(localServerMinThreads));
threadPool.setIdleTimeout(Integer.valueOf(localServerIdleTimeout));
}
});
return factory;
}
}