20
20
*/
21
21
package eu .openanalytics .containerproxy ;
22
22
23
+ import com .fasterxml .jackson .datatype .jsr353 .JSR353Module ;
23
24
import eu .openanalytics .containerproxy .util .ProxyMappingManager ;
24
25
import io .undertow .Handlers ;
25
26
import io .undertow .servlet .api .ServletSessionConfig ;
27
+ import org .apache .logging .log4j .LogManager ;
28
+ import org .apache .logging .log4j .Logger ;
26
29
import 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 ;
27
33
import org .springframework .boot .autoconfigure .SpringBootApplication ;
28
34
import org .springframework .boot .web .embedded .undertow .UndertowServletWebServerFactory ;
29
35
import org .springframework .boot .web .server .PortInUseException ;
30
36
import org .springframework .boot .web .servlet .FilterRegistrationBean ;
31
37
import org .springframework .context .annotation .Bean ;
32
38
import org .springframework .context .annotation .ComponentScan ;
33
- import org .springframework .context .event .ContextRefreshedEvent ;
34
- import org .springframework .context .event .EventListener ;
35
39
import org .springframework .core .env .Environment ;
40
+ import org .springframework .data .redis .connection .RedisConnectionFactory ;
36
41
import org .springframework .session .data .redis .config .ConfigureRedisAction ;
37
42
import org .springframework .web .filter .FormContentFilter ;
38
- import org .springframework .web .filter .HiddenHttpMethodFilter ;
39
-
40
- import com .fasterxml .jackson .datatype .jsr353 .JSR353Module ;
41
43
42
44
import javax .annotation .PostConstruct ;
43
45
import javax .inject .Inject ;
44
46
import java .net .InetAddress ;
45
47
import java .net .UnknownHostException ;
46
48
import java .nio .file .Files ;
47
49
import java .nio .file .Paths ;
50
+ import java .util .Objects ;
48
51
import java .util .Properties ;
49
- import org .apache .logging .log4j .LogManager ;
50
- import org .apache .logging .log4j .Logger ;
51
52
52
53
@ SpringBootApplication
53
54
@ ComponentScan ("eu.openanalytics" )
54
55
public class ContainerProxyApplication {
55
56
public static final String CONFIG_FILENAME = "application.yml" ;
56
57
public static final String CONFIG_DEMO_PROFILE = "demo" ;
57
-
58
+
58
59
@ Inject
59
60
private Environment environment ;
60
61
@@ -68,9 +69,9 @@ public static void main(String[] args) {
68
69
69
70
boolean hasExternalConfig = Files .exists (Paths .get (CONFIG_FILENAME ));
70
71
if (!hasExternalConfig ) app .setAdditionalProfiles (CONFIG_DEMO_PROFILE );
71
-
72
+
72
73
setDefaultProperties (app );
73
-
74
+
74
75
try {
75
76
app .setLogStartupInfo (false );
76
77
app .run (args );
@@ -81,13 +82,13 @@ public static void main(String[] args) {
81
82
if (e instanceof PortInUseException ) System .exit (-1 );
82
83
}
83
84
}
84
-
85
+
85
86
@ PostConstruct
86
- public void init () {
87
+ public void init () {
87
88
if (environment .getProperty ("server.use-forward-headers" ) != null ) {
88
89
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." );
89
90
}
90
- }
91
+ }
91
92
92
93
@ Bean
93
94
public UndertowServletWebServerFactory servletContainer () {
@@ -111,11 +112,11 @@ public UndertowServletWebServerFactory servletContainer() {
111
112
throw new IllegalArgumentException ("Invalid bind address specified" , e );
112
113
}
113
114
factory .setPort (Integer .parseInt (environment .getProperty ("proxy.port" , "8080" )));
114
- return factory ;
115
+ return factory ;
115
116
}
116
-
117
+
117
118
// Disable specific Spring filters that parse the request body, preventing it from being proxied.
118
-
119
+
119
120
@ Bean
120
121
public FilterRegistrationBean <FormContentFilter > registration2 (FormContentFilter filter ) {
121
122
FilterRegistrationBean <FormContentFilter > registration = new FilterRegistrationBean <>(filter );
@@ -125,6 +126,7 @@ public FilterRegistrationBean<FormContentFilter> registration2(FormContentFilter
125
126
126
127
/**
127
128
* Register the Jackson module which implements compatibility between javax.json and Jackson.
129
+ *
128
130
* @return
129
131
*/
130
132
@ Bean
@@ -134,30 +136,66 @@ public JSR353Module jsr353Module() {
134
136
135
137
/**
136
138
* Compatibility with AWS ElastiCache
139
+ *
137
140
* @return
138
141
*/
139
142
@ Bean
140
143
public static ConfigureRedisAction configureRedisAction () {
141
144
return ConfigureRedisAction .NO_OP ;
142
145
}
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 ) {
145
170
Properties properties = new Properties ();
146
- properties .put ("management.health.ldap.enabled" , false );
147
- properties .put ("management.endpoint.health.probes.enabled" , true );
148
-
171
+
149
172
// use in-memory session storage by default. Can be overwritten in application.yml
150
173
properties .put ("spring.session.store-type" , "none" );
151
-
174
+
152
175
// disable multi-part handling by Spring. We don't need this anywhere in the application.
153
176
// When enabled this will cause problems when proxying file-uploads to the shiny apps.
154
177
properties .put ("spring.servlet.multipart.enabled" , "false" );
155
-
178
+
156
179
// disable logging of requests, since this reads part of the requests and therefore undertow is unable to correctly handle those requests
157
180
properties .put ("logging.level.org.springframework.web.servlet.DispatcherServlet" , "INFO" );
158
-
181
+
159
182
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
+
160
198
app .setDefaultProperties (properties );
161
199
}
162
-
163
- }
200
+
201
+ }
0 commit comments