View Javadoc
1   package net.avcompris.status.web;
2   
3   import static org.apache.commons.lang3.StringUtils.substringBeforeLast;
4   
5   import org.springframework.boot.SpringApplication;
6   import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
7   import org.springframework.boot.autoconfigure.SpringBootApplication;
8   import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
9   import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
10  import org.springframework.context.ApplicationContext;
11  import org.springframework.context.annotation.Bean;
12  import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
13  import org.springframework.web.servlet.config.annotation.CorsRegistry;
14  import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
15  import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
16  
17  import com.beust.jcommander.JCommander;
18  
19  import net.avcompris.commons3.client.DataBeanDeserializer;
20  import net.avcompris.commons3.client.SessionPropagator;
21  import net.avcompris.commons3.core.impl.PermissionsImpl;
22  import net.avcompris.commons3.dao.CorrelationDao;
23  import net.avcompris.commons3.dao.impl.CorrelationDaoInMemory;
24  import net.avcompris.commons3.notifier.impl.ErrorNotifierInMemory;
25  import net.avcompris.commons3.utils.ClockImpl;
26  import net.avcompris.commons3.web.AbstractApplication;
27  import net.avcompris.commons3.web.AbstractConfig;
28  import net.avcompris.commons3.web.ApplicationUtils;
29  import net.avcompris.status.api.InlineService;
30  import net.avcompris.status.core.impl.CorrelationServiceImpl;
31  import net.avcompris.status.core.impl.StatusServiceImpl;
32  import net.avcompris.status.dao.StatusDao;
33  import net.avcompris.status.dao.impl.CorrelationDaoInRDS;
34  import net.avcompris.status.dao.impl.StatusDaoInMemory;
35  import net.avcompris.status.dao.impl.StatusDaoInRDS;
36  
37  /**
38   * A Spring Boot applications.
39   */
40  @EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class })
41  @SpringBootApplication
42  public class Application extends AbstractApplication {
43  
44  	public static final String NAME = "avc-service-status";
45  
46  	public static final String API = "/api/v1";
47  
48  	/**
49  	 * Of the form "net.avcompris.status.avc-service-status".
50  	 */
51  	public static final String PACKAGE_PREFIX = substringBeforeLast(Application.class.getPackage().getName(), ".web");
52  
53  	private static boolean secure = true;
54  
55  	private static final class Config extends AbstractConfig {
56  
57  		private Config(final ApplicationArgs myargs) {
58  
59  			super(myargs);
60  		}
61  
62  		static Config load(final ApplicationArgs myargs) {
63  
64  			return new Config(myargs);
65  		}
66  	}
67  
68  	public static void main(final String... args) throws Exception {
69  
70  		// 1. APPLICATION ARGS
71  
72  		final ApplicationArgsrgs.html#ApplicationArgs">ApplicationArgs myargs = new ApplicationArgs();
73  
74  		JCommander.newBuilder().addObject(myargs).build().parse(args);
75  
76  		secure = !myargs.unsecure;
77  
78  		final Config config = Config.load(myargs);
79  
80  		// 2. SPRING BEANS
81  
82  		final ApplicationContext context = SpringApplication.run(new Class<?>[] {
83  
84  				Application.class,
85  
86  				ClockImpl.class,
87  
88  				CorrelationServiceImpl.class,
89  
90  				ErrorNotifierInMemory.class, // ErrorNotifierInRabbitMQ.class,
91  
92  				PermissionsImpl.class,
93  
94  				SessionPropagator.class,
95  
96  				StatusServiceImpl.class,
97  
98  				dao(CorrelationDao.class, //
99  						config.inMemory, CorrelationDaoInMemory.class, //
100 						config.rds, CorrelationDaoInRDS.class),
101 
102 				dao(StatusDao.class, //
103 						config.inMemory, StatusDaoInMemory.class, //
104 						config.rds, StatusDaoInRDS.class),
105 
106 		}, args);
107 
108 		ApplicationUtils.dumpBeans(context, System.out, //
109 				"net.avcompris", //
110 				"net.avcompris.status");
111 	}
112 
113 	@Bean
114 	public WebMvcConfigurer corsConfigurer() {
115 
116 		return new WebMvcConfigurerAdapter() {
117 
118 			@Override
119 			public void addCorsMappings(final CorsRegistry registry) {
120 
121 				registry.addMapping("/**").allowedMethods(
122 
123 						"HEAD", "GET", "POST", "PUT", "DELETE" //
124 				);
125 			}
126 		};
127 	}
128 
129 	public static boolean isSecure() {
130 
131 		final boolean secure = Application.secure;
132 
133 		if (!secure) {
134 			System.err.println("*** WARNING *** Application.secure = " + secure
135 					+ ", which means HTTP Cookies may be sent on non-SSL HTTP connections");
136 		}
137 
138 		return secure;
139 	}
140 
141 	public static boolean isHttpOnly() {
142 
143 		return true;
144 	}
145 
146 	/**
147 	 * Because we use interfaces for our DataBean classes (via our DataBeans
148 	 * utility), we must specify custom JSON deserializers here.
149 	 */
150 	@Bean
151 	public Jackson2ObjectMapperBuilderCustomizer addCustomDeserialization() {
152 
153 		return new Jackson2ObjectMapperBuilderCustomizer() {
154 
155 			@Override
156 			public void customize(final Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder) {
157 
158 				for (final Class<?> clazz : new Class<?>[] {
159 
160 						InlineService.class,
161 
162 				}) {
163 
164 					jackson2ObjectMapperBuilder.deserializerByType(clazz,
165 							DataBeanDeserializer.createDeserializer(clazz));
166 				}
167 			}
168 		};
169 	}
170 }