Commit 62c665a0 by Johannes Edmeier

Merge pull request #174 from semeiser/multiple-notifiers

parents 9c142aa2 73d1d217
......@@ -15,18 +15,25 @@
*/
package de.codecentric.boot.admin.config;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.autoconfigure.condition.NoneNestedConditions;
import org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.mail.MailSender;
import de.codecentric.boot.admin.notify.CompositeNotifier;
import de.codecentric.boot.admin.notify.HipchatNotifier;
import de.codecentric.boot.admin.notify.MailNotifier;
import de.codecentric.boot.admin.notify.Notifier;
......@@ -50,9 +57,32 @@ public class NotifierConfiguration {
}
@Configuration
@ConditionalOnBean(Notifier.class)
@AutoConfigureBefore({ NotifierListenerConfiguration.class })
public static class CompositeNotifierConfiguration {
@Bean
@Primary
@Conditional(NoSingleNotifierCandidateCondition.class)
public CompositeNotifier compositeNotifier(List<Notifier> notifiers) {
return new CompositeNotifier(notifiers);
}
static class NoSingleNotifierCandidateCondition extends NoneNestedConditions {
NoSingleNotifierCandidateCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}
@ConditionalOnSingleCandidate(Notifier.class)
static class HasSingleNotifierInstance {
}
}
}
@Configuration
@ConditionalOnBean(MailSender.class)
@AutoConfigureAfter({ MailSenderAutoConfiguration.class })
@AutoConfigureBefore({ NotifierListenerConfiguration.class })
@AutoConfigureBefore({ NotifierListenerConfiguration.class,
CompositeNotifierConfiguration.class })
public static class MailNotifierConfiguration {
@Autowired
private MailSender mailSender;
......@@ -68,7 +98,8 @@ public class NotifierConfiguration {
@Configuration
@ConditionalOnProperty(prefix = "spring.boot.admin.notify.pagerduty", name = "service-key")
@AutoConfigureBefore({ NotifierListenerConfiguration.class })
@AutoConfigureBefore({ NotifierListenerConfiguration.class,
CompositeNotifierConfiguration.class })
public static class PagerdutyNotifierConfiguration {
@Bean
@ConditionalOnMissingBean
......@@ -81,14 +112,15 @@ public class NotifierConfiguration {
@Configuration
@ConditionalOnProperty(prefix = "spring.boot.admin.notify.hipchat", name = "url")
@AutoConfigureBefore({ NotifierListenerConfiguration.class })
@AutoConfigureBefore({ NotifierListenerConfiguration.class,
CompositeNotifierConfiguration.class })
public static class HipchatNotifierConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.boot.admin.notify.hipchat", name = "enabled", matchIfMissing = true)
@ConfigurationProperties("spring.boot.admin.notify.hipchat")
public HipchatNotifier hipchatNotifier() {
return new HipchatNotifier();
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.boot.admin.notify.hipchat", name = "enabled", matchIfMissing = true)
@ConfigurationProperties("spring.boot.admin.notify.hipchat")
public HipchatNotifier hipchatNotifier() {
return new HipchatNotifier();
}
}
}
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* 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 de.codecentric.boot.admin.notify;
import de.codecentric.boot.admin.event.ClientApplicationEvent;
/**
* A notifier delegating notifications to all specified notifiers.
*
* @author Sebastian Meiser
*/
public class CompositeNotifier implements Notifier {
private final Iterable<Notifier> notifiers;
public CompositeNotifier(Iterable<Notifier> notifiers) {
this.notifiers = notifiers;
}
@Override
public void notify(ClientApplicationEvent event) {
for (Notifier notifier : notifiers) {
notifier.notify(event);
}
}
}
......@@ -29,7 +29,6 @@ import org.junit.After;
import org.junit.Test;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration;
import org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration;
import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration;
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.cloud.client.discovery.noop.NoopDiscoveryClientAutoConfiguration;
......@@ -46,7 +45,6 @@ import de.codecentric.boot.admin.journal.store.HazelcastJournaledEventStore;
import de.codecentric.boot.admin.journal.store.JournaledEventStore;
import de.codecentric.boot.admin.journal.store.SimpleJournaledEventStore;
import de.codecentric.boot.admin.notify.MailNotifier;
import de.codecentric.boot.admin.notify.PagerdutyNotifier;
import de.codecentric.boot.admin.registry.store.ApplicationStore;
import de.codecentric.boot.admin.registry.store.HazelcastApplicationStore;
import de.codecentric.boot.admin.registry.store.SimpleApplicationStore;
......@@ -95,20 +93,6 @@ public class AdminServerWebConfigurationTest {
assertTrue(context.getBeansOfType(MailNotifier.class).isEmpty());
assertThat(context.getBean(JournaledEventStore.class),
is(instanceOf(SimpleJournaledEventStore.class)));
}
@Test
public void simpleConfig_mail() {
load("spring.mail.host:localhost");
assertThat(context.getBean(MailNotifier.class), is(instanceOf(MailNotifier.class)));
}
@Test
public void simpleConfig_pagerduty() {
load("spring.boot.admin.notify.pagerduty.service-key:foo");
assertThat(context.getBean(PagerdutyNotifier.class),
is(instanceOf(PagerdutyNotifier.class)));
}
@Test
......@@ -148,9 +132,7 @@ public class AdminServerWebConfigurationTest {
}
applicationContext.register(PropertyPlaceholderAutoConfiguration.class);
applicationContext.register(ServerPropertiesAutoConfiguration.class);
applicationContext.register(MailSenderAutoConfiguration.class);
applicationContext.register(HazelcastAutoConfiguration.class);
applicationContext.register(NotifierConfiguration.class);
applicationContext.register(HazelcastStoreConfiguration.class);
applicationContext.register(DiscoveryClientConfiguration.class);
applicationContext.register(AdminServerWebConfiguration.class);
......
......@@ -15,8 +15,10 @@
*/
package de.codecentric.boot.admin.config;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertThat;
import java.util.ArrayList;
......@@ -25,14 +27,22 @@ import java.util.List;
import org.junit.After;
import org.junit.Test;
import org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration;
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import de.codecentric.boot.admin.event.ClientApplicationEvent;
import de.codecentric.boot.admin.event.ClientApplicationStatusChangedEvent;
import de.codecentric.boot.admin.model.Application;
import de.codecentric.boot.admin.model.StatusInfo;
import de.codecentric.boot.admin.notify.CompositeNotifier;
import de.codecentric.boot.admin.notify.HipchatNotifier;
import de.codecentric.boot.admin.notify.MailNotifier;
import de.codecentric.boot.admin.notify.Notifier;
import de.codecentric.boot.admin.notify.NotifierListener;
import de.codecentric.boot.admin.notify.PagerdutyNotifier;
public class NotifierConfigurationTest {
private static final ClientApplicationEvent APP_DOWN = new ClientApplicationStatusChangedEvent(
......@@ -51,7 +61,7 @@ public class NotifierConfigurationTest {
@Test
public void test_notifierListener() {
load(TestNotifierConfig.class);
load(TestSingleNotifierConfig.class);
context.publishEvent(APP_DOWN);
assertThat(context.getBean(TestNotifier.class).getEvents(), is(Arrays.asList(APP_DOWN)));
}
......@@ -59,19 +69,55 @@ public class NotifierConfigurationTest {
@Test
public void test_no_notifierListener() {
load(null);
assertThat(context.getBeansOfType(Notifier.class).values(), empty());
assertThat(context.getBeansOfType(NotifierListener.class).values(), empty());
}
private void load(Class<?> config) {
@Test
public void test_mail() {
load(null, "spring.mail.host:localhost");
assertThat(context.getBean(MailNotifier.class), is(instanceOf(MailNotifier.class)));
}
@Test
public void test_pagerduty() {
load(null, "spring.boot.admin.notify.pagerduty.service-key:foo");
assertThat(context.getBean(PagerdutyNotifier.class),
is(instanceOf(PagerdutyNotifier.class)));
}
@Test
public void test_hipchat() {
load(null, "spring.boot.admin.notify.hipchat.url:http://example.com");
assertThat(context.getBean(HipchatNotifier.class), is(instanceOf(HipchatNotifier.class)));
}
@Test
public void test_multipleNotifiers() {
load(TestMultipleNotifierConfig.class);
assertThat(context.getBean(Notifier.class), is(instanceOf(CompositeNotifier.class)));
assertThat(context.getBeansOfType(Notifier.class).values(), hasSize(3));
}
@Test
public void test_multipleNotifiersWithPrimary() {
load(TestMultipleWithPrimaryNotifierConfig.class);
assertThat(context.getBean(Notifier.class), is(instanceOf(TestNotifier.class)));
assertThat(context.getBeansOfType(Notifier.class).values(), hasSize(2));
}
private void load(Class<?> config, String... environment) {
context = new AnnotationConfigWebApplicationContext();
if (config != null) {
context.register(config);
}
context.register(MailSenderAutoConfiguration.class);
context.register(NotifierConfiguration.class);
EnvironmentTestUtils.addEnvironment(context, environment);
context.refresh();
}
public static class TestNotifierConfig {
public static class TestSingleNotifierConfig {
@Bean
public Notifier testNotifier() {
return new TestNotifier();
......@@ -79,6 +125,31 @@ public class NotifierConfigurationTest {
}
private static class TestMultipleNotifierConfig {
@Bean
public Notifier testNotifier1() {
return new TestNotifier();
}
@Bean
public Notifier testNotifier2() {
return new TestNotifier();
}
}
private static class TestMultipleWithPrimaryNotifierConfig {
@Bean
@Primary
public Notifier testNotifierPrimary() {
return new TestNotifier();
}
@Bean
public Notifier testNotifier2() {
return new TestNotifier();
}
}
private static class TestNotifier implements Notifier {
private List<ClientApplicationEvent> events = new ArrayList<ClientApplicationEvent>();
......
package de.codecentric.boot.admin.notify;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import de.codecentric.boot.admin.event.ClientApplicationEvent;
import de.codecentric.boot.admin.event.ClientApplicationStatusChangedEvent;
import de.codecentric.boot.admin.model.Application;
import de.codecentric.boot.admin.model.StatusInfo;
public class CompositeNotifierTest {
private static final ClientApplicationEvent APP_DOWN = new ClientApplicationStatusChangedEvent(
Application.create("App").withId("id-1").withHealthUrl("http://health")
.withStatusInfo(StatusInfo.ofDown()).build(),
StatusInfo.ofUp(), StatusInfo.ofDown());
@Test
public void test_all_notifiers_get_notified() throws Exception {
TestNotifier notifier1 = new TestNotifier();
TestNotifier notifier2 = new TestNotifier();
CompositeNotifier compositeNotifier = new CompositeNotifier(Arrays.<Notifier>asList(notifier1,notifier2));
compositeNotifier.notify(APP_DOWN);
assertThat(notifier1.getEvents(), is(Arrays.asList(APP_DOWN)));
assertThat(notifier2.getEvents(), is(Arrays.asList(APP_DOWN)));
}
private static class TestNotifier implements Notifier {
private List<ClientApplicationEvent> events = new ArrayList<ClientApplicationEvent>();
@Override
public void notify(ClientApplicationEvent event) {
this.events.add(event);
}
public List<ClientApplicationEvent> getEvents() {
return events;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment