Skip to content

Commit cd31927

Browse files
Daniel Reuterjoshiste
authored andcommitted
Allows Proxy-Settings for Notifiers
closes codecentric#423
1 parent 966cd68 commit cd31927

20 files changed

+173
-98
lines changed

spring-boot-admin-docs/src/main/asciidoc/server-notifications.adoc

Lines changed: 67 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,5 @@
11
=== Notifications ===
22

3-
4-
[[reminder-notifications]]
5-
==== Reminder Notifications ====
6-
The `RemindingNotifier` sends reminders for down/offline applications, it delegates the sending of notifications to another notifier.
7-
8-
By default a reminder is triggered when a registered application changes to `DOWN` or `OFFLINE`. You can alter this behaviour via `setReminderStatuses()`. The reminder ends when either the status changes to a non-triggering status or the regarding application gets deregistered.
9-
10-
By default the reminders are sent every 10 minutes, to change this use `setReminderPeriod()`. The `RemindingNotifier` itself doesn't start the background thread to send the reminders, you need to take care of this as shown in the given example below;
11-
12-
.How to configure reminders
13-
[source,java]
14-
----
15-
@Configuration
16-
public class NotifierConfiguration {
17-
@Autowired
18-
private Notifier notifier;
19-
20-
@Primary
21-
@Bean(initMethod = "start", destroyMethod = "stop")
22-
public RemindingNotifier remindingNotifier() {
23-
RemindingNotifier notifier = new RemindingNotifier(notifier, repository);
24-
notifier.setReminderPeriod(Duration.ofMinutes(10)); // <1>
25-
notifier.setCheckReminderInverval(Duration.ofSeconds(10)); //<2>
26-
return notifier;
27-
}
28-
}
29-
----
30-
<1> The reminders will be sent every 10 minutes.
31-
<2> Schedules sending of due reminders every 10 seconds.
32-
33-
34-
[[filtering-notifications]]
35-
==== Filtering Notifications ====
36-
The `FilteringNotifier` allows you to filter certain notification based on rules you can add/remove at runtime. It delegates the sending of notifications to another notifier.
37-
38-
If you add a `FilteringNotifier` to your `ApplicationContext` a RESTful interface on `notifications/filter` gets available.
39-
40-
This notifier is useful if you don't want receive notifications when deploying your applications. Before stopping the application you can add an (expiring) filter either via a `POST` request.
41-
42-
.How to configure filtering
43-
[source,java,indent=0]
44-
----
45-
include::{samples-dir}/spring-boot-admin-sample-servlet/src/main/java/de/codecentric/boot/admin/NotifierConfig.java[tags=configuration-filtering-notifier]
46-
----
47-
<1> Add the `FilteringNotifier` bean using a delegate (e.g. `MailNotifier` when configured)
48-
<2> Add the `RemindingNotifier` as primary bean using the `FilteringNotifier` as delegate.
49-
50-
TIP: This example combines the reminding and filtering notifiers. This allows you to get notifications after the deployed application hasn't restarted in a certain amount of time (until the filter expires).
51-
52-
533
[[mail-notifications]]
544
==== Mail Notifications ====
555

@@ -411,3 +361,70 @@ To enable Discord notifications you need to create a webhook and set the appropr
411361
| Text to send. SpEL-expressions are supported.
412362
| `+++"*#{instance.registration.name}* (#{instance.id}) is *#{event.statusInfo.status}*"+++`
413363
|===
364+
365+
366+
[[notification-proxy]]
367+
==== Notification Proxy Settings ====
368+
All Notifiers which are using a `RestTemplate` can be configured to use a proxy.
369+
370+
.Notification Proxy configuration options
371+
|===
372+
| Property name |Description |Default value
373+
374+
| spring.boot.admin.notify.proxy.host
375+
| The proxy host
376+
|
377+
378+
| spring.boot.admin.notify.proxy.port
379+
| The proxy port
380+
|
381+
|===
382+
383+
384+
[[reminder-notifications]]
385+
==== Notification Reminder ====
386+
The `RemindingNotifier` sends reminders for down/offline applications, it delegates the sending of notifications to another notifier.
387+
388+
By default a reminder is triggered when a registered application changes to `DOWN` or `OFFLINE`. You can alter this behaviour via `setReminderStatuses()`. The reminder ends when either the status changes to a non-triggering status or the regarding application gets deregistered.
389+
390+
By default the reminders are sent every 10 minutes, to change this use `setReminderPeriod()`. The `RemindingNotifier` itself doesn't start the background thread to send the reminders, you need to take care of this as shown in the given example below;
391+
392+
.How to configure reminders
393+
[source,java]
394+
----
395+
@Configuration
396+
public class NotifierConfiguration {
397+
@Autowired
398+
private Notifier notifier;
399+
400+
@Primary
401+
@Bean(initMethod = "start", destroyMethod = "stop")
402+
public RemindingNotifier remindingNotifier() {
403+
RemindingNotifier notifier = new RemindingNotifier(notifier, repository);
404+
notifier.setReminderPeriod(Duration.ofMinutes(10)); // <1>
405+
notifier.setCheckReminderInverval(Duration.ofSeconds(10)); //<2>
406+
return notifier;
407+
}
408+
}
409+
----
410+
<1> The reminders will be sent every 10 minutes.
411+
<2> Schedules sending of due reminders every 10 seconds.
412+
413+
414+
[[filtering-notifications]]
415+
==== Filtering Notifications ====
416+
The `FilteringNotifier` allows you to filter certain notification based on rules you can add/remove at runtime. It delegates the sending of notifications to another notifier.
417+
418+
If you add a `FilteringNotifier` to your `ApplicationContext` a RESTful interface on `notifications/filter` gets available.
419+
420+
This notifier is useful if you don't want receive notifications when deploying your applications. Before stopping the application you can add an (expiring) filter either via a `POST` request.
421+
422+
.How to configure filtering
423+
[source,java,indent=0]
424+
----
425+
include::{samples-dir}/spring-boot-admin-sample-servlet/src/main/java/de/codecentric/boot/admin/NotifierConfig.java[tags=configuration-filtering-notifier]
426+
----
427+
<1> Add the `FilteringNotifier` bean using a delegate (e.g. `MailNotifier` when configured)
428+
<2> Add the `RemindingNotifier` as primary bean using the `FilteringNotifier` as delegate.
429+
430+
TIP: This example combines the reminding and filtering notifiers. This allows you to get notifications after the deployed application hasn't restarted in a certain amount of time (until the filter expires).

spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/config/AdminServerNotifierAutoConfiguration.java

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,16 @@
2626
import de.codecentric.boot.admin.server.notify.MicrosoftTeamsNotifier;
2727
import de.codecentric.boot.admin.server.notify.NotificationTrigger;
2828
import de.codecentric.boot.admin.server.notify.Notifier;
29+
import de.codecentric.boot.admin.server.notify.NotifierProxyProperties;
2930
import de.codecentric.boot.admin.server.notify.OpsGenieNotifier;
3031
import de.codecentric.boot.admin.server.notify.PagerdutyNotifier;
3132
import de.codecentric.boot.admin.server.notify.SlackNotifier;
3233
import de.codecentric.boot.admin.server.notify.TelegramNotifier;
3334
import de.codecentric.boot.admin.server.notify.filter.FilteringNotifier;
3435
import de.codecentric.boot.admin.server.notify.filter.web.NotificationFilterController;
3536

37+
import java.net.InetSocketAddress;
38+
import java.net.Proxy;
3639
import java.nio.charset.StandardCharsets;
3740
import java.util.List;
3841
import org.reactivestreams.Publisher;
@@ -45,19 +48,23 @@
4548
import org.springframework.boot.autoconfigure.condition.NoneNestedConditions;
4649
import org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration;
4750
import org.springframework.boot.context.properties.ConfigurationProperties;
51+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
4852
import org.springframework.context.ApplicationContext;
4953
import org.springframework.context.annotation.Bean;
5054
import org.springframework.context.annotation.Conditional;
5155
import org.springframework.context.annotation.Configuration;
5256
import org.springframework.context.annotation.Primary;
57+
import org.springframework.http.client.SimpleClientHttpRequestFactory;
5358
import org.springframework.mail.MailSender;
5459
import org.springframework.mail.javamail.JavaMailSender;
60+
import org.springframework.web.client.RestTemplate;
5561
import org.thymeleaf.TemplateEngine;
5662
import org.thymeleaf.spring5.SpringTemplateEngine;
5763
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
5864
import org.thymeleaf.templatemode.TemplateMode;
5965

6066
@Configuration(proxyBeanMethods = false)
67+
@EnableConfigurationProperties(NotifierProxyProperties.class)
6168
@AutoConfigureAfter({MailSenderAutoConfiguration.class})
6269
public class AdminServerNotifierAutoConfiguration {
6370

@@ -152,8 +159,8 @@ public static class HipchatNotifierConfiguration {
152159
@Bean
153160
@ConditionalOnMissingBean
154161
@ConfigurationProperties("spring.boot.admin.notify.hipchat")
155-
public HipchatNotifier hipchatNotifier(InstanceRepository repository) {
156-
return new HipchatNotifier(repository);
162+
public HipchatNotifier hipchatNotifier(InstanceRepository repository, NotifierProxyProperties proxyProperties) {
163+
return new HipchatNotifier(repository, createNotifierRestTemplate(proxyProperties));
157164
}
158165
}
159166

@@ -167,8 +174,8 @@ public static class SlackNotifierConfiguration {
167174
@Bean
168175
@ConditionalOnMissingBean
169176
@ConfigurationProperties("spring.boot.admin.notify.slack")
170-
public SlackNotifier slackNotifier(InstanceRepository repository) {
171-
return new SlackNotifier(repository);
177+
public SlackNotifier slackNotifier(InstanceRepository repository, NotifierProxyProperties proxyProperties) {
178+
return new SlackNotifier(repository, createNotifierRestTemplate(proxyProperties));
172179
}
173180
}
174181

@@ -182,8 +189,8 @@ public static class LetsChatNotifierConfiguration {
182189
@Bean
183190
@ConditionalOnMissingBean
184191
@ConfigurationProperties("spring.boot.admin.notify.letschat")
185-
public LetsChatNotifier letsChatNotifier(InstanceRepository repository) {
186-
return new LetsChatNotifier(repository);
192+
public LetsChatNotifier letsChatNotifier(InstanceRepository repository, NotifierProxyProperties proxyProperties) {
193+
return new LetsChatNotifier(repository, createNotifierRestTemplate(proxyProperties));
187194
}
188195
}
189196

@@ -197,8 +204,8 @@ public static class PagerdutyNotifierConfiguration {
197204
@Bean
198205
@ConditionalOnMissingBean
199206
@ConfigurationProperties("spring.boot.admin.notify.pagerduty")
200-
public PagerdutyNotifier pagerdutyNotifier(InstanceRepository repository) {
201-
return new PagerdutyNotifier(repository);
207+
public PagerdutyNotifier pagerdutyNotifier(InstanceRepository repository, NotifierProxyProperties proxyProperties) {
208+
return new PagerdutyNotifier(repository, createNotifierRestTemplate(proxyProperties));
202209
}
203210
}
204211

@@ -212,8 +219,8 @@ public static class OpsGenieNotifierConfiguration {
212219
@Bean
213220
@ConditionalOnMissingBean
214221
@ConfigurationProperties("spring.boot.admin.notify.opsgenie")
215-
public OpsGenieNotifier opsgenieNotifier(InstanceRepository repository) {
216-
return new OpsGenieNotifier(repository);
222+
public OpsGenieNotifier opsgenieNotifier(InstanceRepository repository, NotifierProxyProperties proxyProperties) {
223+
return new OpsGenieNotifier(repository, createNotifierRestTemplate(proxyProperties));
217224
}
218225
}
219226

@@ -227,8 +234,8 @@ public static class MicrosoftTeamsNotifierConfiguration {
227234
@Bean
228235
@ConditionalOnMissingBean
229236
@ConfigurationProperties("spring.boot.admin.notify.ms-teams")
230-
public MicrosoftTeamsNotifier microsoftTeamsNotifier(InstanceRepository repository) {
231-
return new MicrosoftTeamsNotifier(repository);
237+
public MicrosoftTeamsNotifier microsoftTeamsNotifier(InstanceRepository repository, NotifierProxyProperties proxyProperties) {
238+
return new MicrosoftTeamsNotifier(repository, createNotifierRestTemplate(proxyProperties));
232239
}
233240
}
234241

@@ -242,8 +249,8 @@ public static class TelegramNotifierConfiguration {
242249
@Bean
243250
@ConditionalOnMissingBean
244251
@ConfigurationProperties("spring.boot.admin.notify.telegram")
245-
public TelegramNotifier telegramNotifier(InstanceRepository repository) {
246-
return new TelegramNotifier(repository);
252+
public TelegramNotifier telegramNotifier(InstanceRepository repository, NotifierProxyProperties proxyProperties) {
253+
return new TelegramNotifier(repository, createNotifierRestTemplate(proxyProperties));
247254
}
248255
}
249256

@@ -257,8 +264,19 @@ public static class DiscordNotifierConfiguration {
257264
@Bean
258265
@ConditionalOnMissingBean
259266
@ConfigurationProperties("spring.boot.admin.notify.discord")
260-
public DiscordNotifier discordNotifier(InstanceRepository repository) {
261-
return new DiscordNotifier(repository);
267+
public DiscordNotifier discordNotifier(InstanceRepository repository, NotifierProxyProperties proxyProperties) {
268+
return new DiscordNotifier(repository, createNotifierRestTemplate(proxyProperties));
262269
}
263270
}
271+
272+
private static RestTemplate createNotifierRestTemplate(NotifierProxyProperties proxyProperties) {
273+
RestTemplate restTemplate = new RestTemplate();
274+
if (proxyProperties.getHost() != null) {
275+
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
276+
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyProperties.getHost(), proxyProperties.getPort()));
277+
requestFactory.setProxy(proxy);
278+
restTemplate.setRequestFactory(requestFactory);
279+
}
280+
return restTemplate;
281+
}
264282
}

spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/DiscordNotifier.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
public class DiscordNotifier extends AbstractStatusChangeNotifier {
4545
private static final String DEFAULT_MESSAGE = "*#{instance.registration.name}* (#{instance.id}) is *#{event.statusInfo.status}*";
4646
private final SpelExpressionParser parser = new SpelExpressionParser();
47-
private RestTemplate restTemplate = new RestTemplate();
47+
private RestTemplate restTemplate;
4848
private Expression message;
4949

5050
/**
@@ -70,8 +70,9 @@ public class DiscordNotifier extends AbstractStatusChangeNotifier {
7070
@Nullable
7171
private String avatarUrl;
7272

73-
public DiscordNotifier(InstanceRepository repository) {
73+
public DiscordNotifier(InstanceRepository repository, RestTemplate restTemplate) {
7474
super(repository);
75+
this.restTemplate = restTemplate;
7576
this.message = parser.parseExpression(DEFAULT_MESSAGE, ParserContext.TEMPLATE_EXPRESSION);
7677
}
7778

spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/HipchatNotifier.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public class HipchatNotifier extends AbstractStatusChangeNotifier {
4747
private static final String DEFAULT_DESCRIPTION = "<strong>#{instance.registration.name}</strong>/#{instance.id} is <strong>#{event.statusInfo.status}</strong>";
4848

4949
private final SpelExpressionParser parser = new SpelExpressionParser();
50-
private RestTemplate restTemplate = new RestTemplate();
50+
private RestTemplate restTemplate;
5151

5252
/**
5353
* Base URL for HipChat API (i.e. https://ACCOUNT_NAME.hipchat.com/v2
@@ -77,8 +77,9 @@ public class HipchatNotifier extends AbstractStatusChangeNotifier {
7777
*/
7878
private Expression description;
7979

80-
public HipchatNotifier(InstanceRepository repository) {
80+
public HipchatNotifier(InstanceRepository repository, RestTemplate restTemplate) {
8181
super(repository);
82+
this.restTemplate = restTemplate;
8283
this.description = parser.parseExpression(DEFAULT_DESCRIPTION, ParserContext.TEMPLATE_EXPRESSION);
8384
}
8485

spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/LetsChatNotifier.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public class LetsChatNotifier extends AbstractStatusChangeNotifier {
4848
private static final String DEFAULT_MESSAGE = "*#{instance.registration.name}* (#{instance.id}) is *#{event.statusInfo.status}*";
4949

5050
private final SpelExpressionParser parser = new SpelExpressionParser();
51-
private RestTemplate restTemplate = new RestTemplate();
51+
private RestTemplate restTemplate;
5252

5353
/**
5454
* Host URL for Let´s Chat
@@ -78,8 +78,9 @@ public class LetsChatNotifier extends AbstractStatusChangeNotifier {
7878
*/
7979
private Expression message;
8080

81-
public LetsChatNotifier(InstanceRepository repository) {
81+
public LetsChatNotifier(InstanceRepository repository, RestTemplate restTemplate) {
8282
super(repository);
83+
this.restTemplate = restTemplate;
8384
this.message = parser.parseExpression(DEFAULT_MESSAGE, ParserContext.TEMPLATE_EXPRESSION);
8485
}
8586

spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/MicrosoftTeamsNotifier.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public class MicrosoftTeamsNotifier extends AbstractStatusChangeNotifier {
4747
private static final String HEALTH_URL_KEY = "Health URL";
4848
private static final String MANAGEMENT_URL_KEY = "Management URL";
4949
private static final String SOURCE_KEY = "Source";
50-
private RestTemplate restTemplate = new RestTemplate();
50+
private RestTemplate restTemplate;
5151

5252
/**
5353
* Webhook url for Microsoft Teams Channel Webhook connector (i.e.
@@ -100,8 +100,9 @@ public class MicrosoftTeamsNotifier extends AbstractStatusChangeNotifier {
100100
*/
101101
private String messageSummary = "Spring Boot Admin Notification";
102102

103-
public MicrosoftTeamsNotifier(InstanceRepository repository) {
103+
public MicrosoftTeamsNotifier(InstanceRepository repository, RestTemplate restTemplate) {
104104
super(repository);
105+
this.restTemplate = restTemplate;
105106
}
106107

107108
@Override
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2014-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package de.codecentric.boot.admin.server.notify;
18+
19+
import org.springframework.boot.context.properties.ConfigurationProperties;
20+
21+
@lombok.Data
22+
@ConfigurationProperties("spring.boot.admin.notify.proxy")
23+
public class NotifierProxyProperties {
24+
/**
25+
* Proxy-Host for sending notifications
26+
*/
27+
private String host;
28+
29+
/**
30+
* Proxy-Port for sending notifications
31+
*/
32+
private int port;
33+
}

0 commit comments

Comments
 (0)