2020 */
2121package eu .openanalytics .containerproxy ;
2222
23+ import com .fasterxml .jackson .datatype .jsr353 .JSR353Module ;
2324import eu .openanalytics .containerproxy .util .ProxyMappingManager ;
2425import io .undertow .Handlers ;
2526import io .undertow .servlet .api .ServletSessionConfig ;
27+ import org .apache .logging .log4j .LogManager ;
28+ import org .apache .logging .log4j .Logger ;
2629import org .springframework .boot .SpringApplication ;
30+ import org .springframework .boot .actuate .health .Health ;
31+ import org .springframework .boot .actuate .health .HealthIndicator ;
32+ import org .springframework .boot .actuate .redis .RedisHealthIndicator ;
2733import org .springframework .boot .autoconfigure .SpringBootApplication ;
2834import org .springframework .boot .web .embedded .undertow .UndertowServletWebServerFactory ;
2935import org .springframework .boot .web .server .PortInUseException ;
3036import org .springframework .boot .web .servlet .FilterRegistrationBean ;
3137import org .springframework .context .annotation .Bean ;
3238import org .springframework .context .annotation .ComponentScan ;
33- import org .springframework .context .event .ContextRefreshedEvent ;
34- import org .springframework .context .event .EventListener ;
3539import org .springframework .core .env .Environment ;
40+ import org .springframework .data .redis .connection .RedisConnectionFactory ;
3641import org .springframework .session .data .redis .config .ConfigureRedisAction ;
3742import org .springframework .web .filter .FormContentFilter ;
38- import org .springframework .web .filter .HiddenHttpMethodFilter ;
39-
40- import com .fasterxml .jackson .datatype .jsr353 .JSR353Module ;
4143
4244import javax .annotation .PostConstruct ;
4345import javax .inject .Inject ;
4446import java .net .InetAddress ;
4547import java .net .UnknownHostException ;
4648import java .nio .file .Files ;
4749import java .nio .file .Paths ;
50+ import java .util .Objects ;
4851import java .util .Properties ;
49- import org .apache .logging .log4j .LogManager ;
50- import org .apache .logging .log4j .Logger ;
5152
5253@ SpringBootApplication
5354@ ComponentScan ("eu.openanalytics" )
5455public class ContainerProxyApplication {
5556 public static final String CONFIG_FILENAME = "application.yml" ;
5657 public static final String CONFIG_DEMO_PROFILE = "demo" ;
57-
58+
5859 @ Inject
5960 private Environment environment ;
6061
@@ -68,9 +69,9 @@ public static void main(String[] args) {
6869
6970 boolean hasExternalConfig = Files .exists (Paths .get (CONFIG_FILENAME ));
7071 if (!hasExternalConfig ) app .setAdditionalProfiles (CONFIG_DEMO_PROFILE );
71-
72+
7273 setDefaultProperties (app );
73-
74+
7475 try {
7576 app .setLogStartupInfo (false );
7677 app .run (args );
@@ -81,13 +82,13 @@ public static void main(String[] args) {
8182 if (e instanceof PortInUseException ) System .exit (-1 );
8283 }
8384 }
84-
85+
8586 @ PostConstruct
86- public void init () {
87+ public void init () {
8788 if (environment .getProperty ("server.use-forward-headers" ) != null ) {
8889 log .warn ("WARNING: Using server.use-forward-headers will not work in this ShinyProxy release. See https://shinyproxy.io/documentation/security/#https-ssl--tls on how to change your configuration." );
8990 }
90- }
91+ }
9192
9293 @ Bean
9394 public UndertowServletWebServerFactory servletContainer () {
@@ -111,11 +112,11 @@ public UndertowServletWebServerFactory servletContainer() {
111112 throw new IllegalArgumentException ("Invalid bind address specified" , e );
112113 }
113114 factory .setPort (Integer .parseInt (environment .getProperty ("proxy.port" , "8080" )));
114- return factory ;
115+ return factory ;
115116 }
116-
117+
117118 // Disable specific Spring filters that parse the request body, preventing it from being proxied.
118-
119+
119120 @ Bean
120121 public FilterRegistrationBean <FormContentFilter > registration2 (FormContentFilter filter ) {
121122 FilterRegistrationBean <FormContentFilter > registration = new FilterRegistrationBean <>(filter );
@@ -125,6 +126,7 @@ public FilterRegistrationBean<FormContentFilter> registration2(FormContentFilter
125126
126127 /**
127128 * Register the Jackson module which implements compatibility between javax.json and Jackson.
129+ *
128130 * @return
129131 */
130132 @ Bean
@@ -134,30 +136,66 @@ public JSR353Module jsr353Module() {
134136
135137 /**
136138 * Compatibility with AWS ElastiCache
139+ *
137140 * @return
138141 */
139142 @ Bean
140143 public static ConfigureRedisAction configureRedisAction () {
141144 return ConfigureRedisAction .NO_OP ;
142145 }
143-
144- private static void setDefaultProperties (SpringApplication app ) {
146+
147+ @ Bean
148+ public HealthIndicator redisSessionHealthIndicator (RedisConnectionFactory rdeRedisConnectionFactory ) {
149+ if (Objects .equals (environment .getProperty ("spring.session.store-type" ), "redis" )) {
150+ // if we are using redis for session -> use a proper health check for redis
151+ return new RedisHealthIndicator (rdeRedisConnectionFactory );
152+ } else {
153+ // not using redis for session -> just pretend it's always online
154+ return new HealthIndicator () {
155+
156+ @ Override
157+ public Health getHealth (boolean includeDetails ) {
158+ return Health .up ().build ();
159+ }
160+
161+ @ Override
162+ public Health health () {
163+ return Health .up ().build ();
164+ }
165+ };
166+ }
167+ }
168+
169+ private static void setDefaultProperties (SpringApplication app ) {
145170 Properties properties = new Properties ();
146- properties .put ("management.health.ldap.enabled" , false );
147- properties .put ("management.endpoint.health.probes.enabled" , true );
148-
171+
149172 // use in-memory session storage by default. Can be overwritten in application.yml
150173 properties .put ("spring.session.store-type" , "none" );
151-
174+
152175 // disable multi-part handling by Spring. We don't need this anywhere in the application.
153176 // When enabled this will cause problems when proxying file-uploads to the shiny apps.
154177 properties .put ("spring.servlet.multipart.enabled" , "false" );
155-
178+
156179 // disable logging of requests, since this reads part of the requests and therefore undertow is unable to correctly handle those requests
157180 properties .put ("logging.level.org.springframework.web.servlet.DispatcherServlet" , "INFO" );
158-
181+
159182 properties .put ("spring.application.name" , "ContainerProxy" );
183+
184+ // Health configuration
185+ // ====================
186+
187+ // enable redisSession check for the readiness probe
188+ properties .put ("management.endpoint.health.group.readiness.include" , "readinessProbe,redisSession" );
189+ // disable ldap health endpoint
190+ properties .put ("management.health.ldap.enabled" , false );
191+ // disable default redis health endpoint since it's managed by redisSession
192+ properties .put ("management.health.redis.enabled" , "false" );
193+ // enable Kubernetes porobes
194+ properties .put ("management.endpoint.health.probes.enabled" , true );
195+
196+ // ====================
197+
160198 app .setDefaultProperties (properties );
161199 }
162-
163- }
200+
201+ }
0 commit comments