From 0d617f88ad5d688ba2c50cb610b4cf035f8eed2f Mon Sep 17 00:00:00 2001 From: F43nd1r Date: Fri, 6 May 2022 16:58:10 +0200 Subject: [PATCH] Codestyle + License Header (#312) * update code style to use eclipse formatter * format all files * set up license template * apply license to all files * format after rebase * fix ci * add comment to push.yml --- .github/workflows/push.yml | 2 + .../monkey/assaults/ChaosMonkeyAssault.java | 20 +- .../ChaosMonkeyLatencyAssaultExecutor.java | 17 +- .../assaults/ChaosMonkeyRequestAssault.java | 18 +- .../assaults/ChaosMonkeyRuntimeAssault.java | 17 +- .../chaos/monkey/assaults/CpuAssault.java | 265 ++++----- .../monkey/assaults/ExceptionAssault.java | 47 +- .../chaos/monkey/assaults/KillAppAssault.java | 97 ++-- .../chaos/monkey/assaults/LatencyAssault.java | 82 ++- .../assaults/LatencyAssaultExecutor.java | 29 +- .../chaos/monkey/assaults/MemoryAssault.java | 242 ++++----- .../chaos/monkey/assaults/SizeConverter.java | 35 +- .../component/ChaosMonkeyRequestScope.java | 195 +++---- .../component/ChaosMonkeyRuntimeScope.java | 52 +- .../component/ChaosMonkeyScheduler.java | 128 ++--- .../chaos/monkey/component/ChaosTarget.java | 40 +- .../component/MetricEventPublisher.java | 48 +- .../chaos/monkey/component/MetricType.java | 84 +-- .../boot/chaos/monkey/component/Metrics.java | 81 +-- .../configuration/AssaultException.java | 204 +++---- .../configuration/AssaultProperties.java | 108 ++-- .../configuration/ChaosMonkeyCondition.java | 17 +- .../ChaosMonkeyConfiguration.java | 373 ++++++------- .../ChaosMonkeyLoadTimeWeaving.java | 23 +- .../configuration/ChaosMonkeyProperties.java | 27 +- .../ChaosMonkeyRestTemplateConfiguration.java | 53 +- .../configuration/ChaosMonkeySettings.java | 20 +- .../ChaosMonkeyWebClientConfiguration.java | 48 +- .../UnleashChaosConfiguration.java | 27 +- .../configuration/WatcherProperties.java | 23 +- .../toggles/ChaosToggleNameMapper.java | 35 +- .../configuration/toggles/ChaosToggles.java | 17 +- .../toggles/DefaultChaosToggleNameMapper.java | 37 +- .../toggles/DefaultChaosToggles.java | 23 +- .../toggles/UnleashChaosToggles.java | 31 +- .../endpoints/BaseChaosMonkeyEndpoint.java | 107 ++-- .../endpoints/ChaosMonkeyJmxEndpoint.java | 117 ++-- .../endpoints/ChaosMonkeyRestEndpoint.java | 146 +++-- .../dto/AssaultPropertiesUpdate.java | 244 +++++---- .../endpoints/dto/ChaosMonkeySettingsDto.java | 26 +- .../dto/ChaosMonkeyStatusResponseDto.java | 88 +-- .../dto/WatcherPropertiesUpdate.java | 74 ++- .../AssaultExceptionConstraint.java | 21 +- .../validation/AssaultExceptionValidator.java | 46 +- ...ropertiesUpdateLatencyRangeConstraint.java | 22 +- ...PropertiesUpdateLatencyRangeValidator.java | 37 +- .../boot/chaos/monkey/events/MetricEvent.java | 105 ++-- .../watcher/aspect/ChaosMonkeyBaseAspect.java | 38 +- .../aspect/ChaosMonkeyBeanPostProcessor.java | 110 ++-- .../SpringBootHealthIndicatorAspect.java | 51 +- .../watcher/aspect/SpringComponentAspect.java | 47 +- .../aspect/SpringControllerAspect.java | 40 +- .../aspect/SpringRepositoryAspectJDBC.java | 40 +- .../aspect/SpringRepositoryAspectJPA.java | 40 +- .../aspect/SpringRestControllerAspect.java | 41 +- .../watcher/aspect/SpringServiceAspect.java | 41 +- .../ChaosMonkeyRestTemplateCustomizer.java | 35 +- .../ChaosMonkeyRestTemplatePostProcessor.java | 37 +- .../ChaosMonkeyRestTemplateWatcher.java | 148 ++--- .../ChaosMonkeyWebClientCustomizer.java | 31 +- .../ChaosMonkeyWebClientPostProcessor.java | 45 +- .../outgoing/ChaosMonkeyWebClientWatcher.java | 126 +++-- ...ionChaosMonkeyRequestScopeProfileTest.java | 102 ++-- ...haosDemoApplicationDefaultProfileTest.java | 66 +-- .../DefaultSettingsIntegrationTest.java | 67 ++- .../assaults/CPUAssaultIntegration.java | 223 ++++---- .../monkey/assaults/ExceptionAssaultTest.java | 221 ++++---- .../monkey/assaults/KillAppAssaultTest.java | 52 +- .../assaults/LatencyAssaultRangeTest.java | 74 +-- .../monkey/assaults/LatencyAssaultTest.java | 65 +-- .../MemoryAssaultIntegrationTest.java | 302 +++++------ .../ChaosMonkeyRequestScopeTest.java | 412 +++++++------- .../component/ChaosMonkeySchedulerTest.java | 206 +++---- .../configuration/AssaultExceptionTest.java | 259 +++++---- .../ChaosMonkeyConditionTest.java | 49 +- .../ChaosMonkeyRequestScopeSettingsTest.java | 232 ++++---- .../DefaultChaosToggleNameMapperTest.java | 43 +- .../toggles/DefaultChaosTogglesTest.java | 35 +- .../toggles/UnleashChaosTogglesTest.java | 57 +- ...haosMonkeyRequestScopeJmxEndpointTest.java | 181 +++--- ...peRestEndpointDisabledIntegrationTest.java | 37 +- ...questScopeRestEndpointIntegrationTest.java | 513 +++++++++--------- .../ChaosMonkeyRestEndpointTest.java | 85 +-- ...ltPropertiesLatencyRangeValidatorTest.java | 97 ++-- .../ChaosMonkeyBeanPostProcessorTest.java | 93 ++-- ...tHealthIndicatorAspectIntegrationTest.java | 89 +-- .../SpringComponentAspectIntegrationTest.java | 226 ++++---- .../aspect/SpringComponentAspectTest.java | 130 +++-- .../aspect/SpringControllerAspectTest.java | 130 +++-- .../SpringRepositoryAspectJDBCTest.java | 129 +++-- .../aspect/SpringRepositoryAspectJPATest.java | 130 +++-- ...positoryAspectRepositoryInterfaceTest.java | 25 +- .../SpringRestControllerAspectTest.java | 130 +++-- .../aspect/SpringServiceAspectTest.java | 129 +++-- ...keyRestTemplateWatcherIntegrationTest.java | 101 ++-- ...MonkeyWebClientWatcherIntegrationTest.java | 79 +-- .../chaos/monkey/ChaosDemoApplication.java | 44 +- .../boot/demo/chaos/monkey/bean/DemoBean.java | 21 +- .../ApplicationListenerComponent.java | 13 +- .../component/BeanPostProcessorComponent.java | 28 +- .../chaos/monkey/component/DemoComponent.java | 11 +- .../component/FactoryBeanComponent.java | 29 +- .../monkey/component/FinalDemoComponent.java | 11 +- .../demo/chaos/monkey/component/Widget.java | 25 +- .../monkey/controller/DemoController.java | 13 +- .../monkey/repository/CrudDemoRepository.java | 7 +- .../monkey/repository/DemoRepository.java | 7 +- .../monkey/repository/DemoRepositoryImpl.java | 101 ++-- .../monkey/repository/DemoRepositoryJDBC.java | 11 +- .../demo/chaos/monkey/repository/Hello.java | 55 +- .../restcontroller/DemoRestController.java | 13 +- .../service/DemoRestTemplateService.java | 29 +- .../chaos/monkey/service/DemoService.java | 11 +- .../monkey/service/DemoWebClientService.java | 34 +- code-style.xml | 9 + .../chaosdemo/ChaosDemoApplication.java | 11 +- .../chaosdemo/controller/HelloController.java | 27 +- .../ChaosDemoApplicationIntegrationTest.java | 18 +- .../chaosdemo/ChaosDemoApplicationTests.java | 10 +- .../HelloControllerIntegrationTest.java | 65 +-- .../controller/HelloControllerTest.java | 28 +- .../chaosdemo/ChaosDemoApplication.java | 11 +- .../controller/GreetingController.java | 23 +- .../controller/GreetingRestController.java | 23 +- .../chaosdemo/controller/HelloController.java | 75 ++- .../chaos/monkey/chaosdemo/repo/Hello.java | 55 +- .../monkey/chaosdemo/repo/HelloRepo.java | 18 +- .../chaosdemo/repo/HelloRepoAnnotation.java | 19 +- .../monkey/chaosdemo/repo/HelloRepoJpa.java | 18 +- .../repo/HelloRepoSearchAndSorting.java | 18 +- .../chaosdemo/service/GreetingService.java | 89 +-- .../chaosdemo/ChaosDemoApplicationTests.java | 24 +- .../controller/GreetingControllerTest.java | 29 +- .../GreetingRestControllerTest.java | 29 +- .../HelloControllerIntegrationTest.java | 65 +-- .../controller/HelloControllerTest.java | 71 +-- .../monkey/chaosdemo/repo/HelloTest.java | 51 +- .../service/GreetingServiceTest.java | 171 +++--- .../toggledemo/ChaosDemoApplication.java | 66 +-- .../monkey/toggledemo/MyAppToggleMapper.java | 33 +- .../toggledemo/UserAwareFakeUnleash.java | 109 ++-- .../monkey/toggledemo/WebSecurityConfig.java | 72 ++- .../toggledemo/component/HelloComponent.java | 21 +- .../controller/GreetingController.java | 34 +- .../controller/GreetingRestController.java | 23 +- .../controller/HelloController.java | 51 +- .../toggledemo/repo/SimpleRepository.java | 21 +- .../toggledemo/service/GreetingService.java | 35 +- .../toggledemo/ChaosDemoApplicationTests.java | 21 +- .../HelloControllerIntegrationTest.java | 79 ++- .../service/GreetingServiceTest.java | 52 +- .../chaosdemo/ChaosDemoApplication.java | 11 +- .../monkey/chaosdemo/bean/HelloBean.java | 21 +- .../chaosdemo/bean/HelloConfiguration.java | 23 +- .../chaosdemo/component/HelloComponent.java | 21 +- .../controller/GreetingController.java | 45 +- .../controller/GreetingRestController.java | 23 +- .../chaosdemo/controller/HelloController.java | 75 ++- .../chaos/monkey/chaosdemo/repo/Hello.java | 55 +- .../monkey/chaosdemo/repo/HelloRepo.java | 18 +- .../chaosdemo/repo/HelloRepoAnnotation.java | 19 +- .../monkey/chaosdemo/repo/HelloRepoJpa.java | 18 +- .../repo/HelloRepoSearchAndSorting.java | 18 +- .../chaosdemo/service/GreetingService.java | 89 +-- .../chaosdemo/ChaosDemoApplicationTests.java | 21 +- .../controller/GreetingControllerTest.java | 51 +- .../GreetingRestControllerTest.java | 29 +- .../HelloComponentIntegrationTest.java | 34 +- .../HelloControllerIntegrationTest.java | 78 ++- .../controller/HelloControllerTest.java | 71 +-- .../monkey/chaosdemo/repo/HelloTest.java | 51 +- .../service/GreetingServiceTest.java | 171 +++--- .../chaosdemo/ChaosDemoApplication.java | 11 +- .../monkey/chaosdemo/RouterConfiguration.java | 25 +- .../chaosdemo/component/HelloComponent.java | 23 +- .../chaosdemo/ChaosDemoApplicationTests.java | 21 +- license.template.txt | 15 + pom.xml | 16 +- 178 files changed, 6619 insertions(+), 5708 deletions(-) create mode 100644 code-style.xml create mode 100644 license.template.txt diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 5aa8fe7a..31fed395 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -18,6 +18,8 @@ jobs: steps: - uses: actions/checkout@v3 + with: + fetch-depth: 0 # need git history for spotless license header - name: Set up JDK ${{ matrix.java }} uses: actions/setup-java@v3 with: diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ChaosMonkeyAssault.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ChaosMonkeyAssault.java index 948aec73..4b21d433 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ChaosMonkeyAssault.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ChaosMonkeyAssault.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,22 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.assaults; /** - * A way to interfere with the application. Implementations will be either {@link - * ChaosMonkeyRuntimeAssault} or {@link ChaosMonkeyRequestAssault}, depending if the interference is - * on the request or runtime level. + * A way to interfere with the application. Implementations will be either + * {@link ChaosMonkeyRuntimeAssault} or {@link ChaosMonkeyRequestAssault}, + * depending if the interference is on the request or runtime level. * - *

Implementing this interface directly is discouraged, and will generally be treated as a - * Request-level assault + *

+ * Implementing this interface directly is discouraged, and will generally be + * treated as a Request-level assault * * @author Thorsten Deelmann */ public interface ChaosMonkeyAssault { - boolean isActive(); + boolean isActive(); - void attack(); + void attack(); } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ChaosMonkeyLatencyAssaultExecutor.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ChaosMonkeyLatencyAssaultExecutor.java index 0f2dce49..bc7baf13 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ChaosMonkeyLatencyAssaultExecutor.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ChaosMonkeyLatencyAssaultExecutor.java @@ -1,6 +1,21 @@ +/* + * Copyright 2018-2022 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 + * + * https://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.spring.boot.chaos.monkey.assaults; public interface ChaosMonkeyLatencyAssaultExecutor { - void execute(long duration); + void execute(long duration); } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ChaosMonkeyRequestAssault.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ChaosMonkeyRequestAssault.java index a3066581..71bfd983 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ChaosMonkeyRequestAssault.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ChaosMonkeyRequestAssault.java @@ -1,3 +1,19 @@ +/* + * Copyright 2018-2022 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 + * + * https://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.spring.boot.chaos.monkey.assaults; -public interface ChaosMonkeyRequestAssault extends ChaosMonkeyAssault {} +public interface ChaosMonkeyRequestAssault extends ChaosMonkeyAssault { +} diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ChaosMonkeyRuntimeAssault.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ChaosMonkeyRuntimeAssault.java index bcc032b8..1a5686de 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ChaosMonkeyRuntimeAssault.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ChaosMonkeyRuntimeAssault.java @@ -1,7 +1,22 @@ +/* + * Copyright 2018-2022 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 + * + * https://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.spring.boot.chaos.monkey.assaults; import de.codecentric.spring.boot.chaos.monkey.configuration.AssaultProperties; public interface ChaosMonkeyRuntimeAssault extends ChaosMonkeyAssault { - String getCronExpression(AssaultProperties assaultProperties); + String getCronExpression(AssaultProperties assaultProperties); } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/CpuAssault.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/CpuAssault.java index 11bd79ed..676ddba7 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/CpuAssault.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/CpuAssault.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.assaults; import com.sun.management.OperatingSystemMXBean; @@ -11,148 +26,144 @@ import org.slf4j.LoggerFactory; public class CpuAssault implements ChaosMonkeyRuntimeAssault { - private static final double leeway = 0.05; - private static final Logger Logger = LoggerFactory.getLogger(CpuAssault.class); - - private final ChaosMonkeySettings settings; - - private final MetricEventPublisher metricEventPublisher; - private final OperatingSystemMXBean os; - - public CpuAssault( - OperatingSystemMXBean os, - ChaosMonkeySettings settings, - MetricEventPublisher metricEventPublisher) { - this.os = os; - this.settings = settings; - this.metricEventPublisher = metricEventPublisher; - } - - @Override - public boolean isActive() { - return settings.getAssaultProperties().isCpuActive(); - } - - @Override - public void attack() { - Logger.info("Chaos Monkey - cpu assault"); - - // metrics - if (metricEventPublisher != null) { - metricEventPublisher.publishMetricEvent(MetricType.CPU_ASSAULT); - } - double load = settings.getAssaultProperties().getCpuLoadTargetFraction(); - - if (os.getProcessCpuLoad() >= 0) { - ThreadManager threadManager = new ThreadManager(os, load); - // initial ramp up - while (os.getProcessCpuLoad() < load && isActive()) { - threadManager.tick(); - } - final long targetMs = - System.currentTimeMillis() + settings.getAssaultProperties().getCpuMillisecondsHoldLoad(); - // hold for specified time - while (targetMs > System.currentTimeMillis() && isActive()) { - threadManager.tick(); - } - threadManager.stop(); - Logger.info("Chaos Monkey - cpu assault cleaned up"); - } else { - Logger.warn("Chaos Monkey - cpu information not available, assault not executed"); - } - } + private static final double leeway = 0.05; + private static final Logger Logger = LoggerFactory.getLogger(CpuAssault.class); - @Override - public String getCronExpression(AssaultProperties assaultProperties) { - return assaultProperties.getCpuCronExpression() != null - ? assaultProperties.getCpuCronExpression() - : assaultProperties.getRuntimeAssaultCronExpression(); - } + private final ChaosMonkeySettings settings; - private static class ThreadManager { + private final MetricEventPublisher metricEventPublisher; private final OperatingSystemMXBean os; - private final double targetLoad; - private final List runningThreads = new ArrayList<>(); - private final List pausedThreads = new ArrayList<>(); - private double lastLoad; - - private ThreadManager(OperatingSystemMXBean os, double targetLoad) { - this.os = os; - this.targetLoad = targetLoad; + + public CpuAssault(OperatingSystemMXBean os, ChaosMonkeySettings settings, MetricEventPublisher metricEventPublisher) { + this.os = os; + this.settings = settings; + this.metricEventPublisher = metricEventPublisher; } - public void tick() { - double load = os.getProcessCpuLoad(); - // only change things if we have new data - if (load != lastLoad) { - lastLoad = load; - if (load < targetLoad) { - WorkerThread thread; - if (pausedThreads.isEmpty()) { - thread = new WorkerThread("CPU Assault thread " + runningThreads.size()); - thread.start(); - } else { - thread = pausedThreads.remove(0); - synchronized (thread) { - thread.shouldPause = false; - thread.notify(); - } - } - runningThreads.add(thread); - } else if (load > targetLoad + leeway && !runningThreads.isEmpty()) { - WorkerThread thread = runningThreads.remove(0); - thread.shouldPause = true; - pausedThreads.add(thread); + @Override + public boolean isActive() { + return settings.getAssaultProperties().isCpuActive(); + } + + @Override + public void attack() { + Logger.info("Chaos Monkey - cpu assault"); + + // metrics + if (metricEventPublisher != null) { + metricEventPublisher.publishMetricEvent(MetricType.CPU_ASSAULT); } - // make sure the managing thread doesn't generate too much load - try { - Thread.sleep(200); - } catch (InterruptedException ignored) { + double load = settings.getAssaultProperties().getCpuLoadTargetFraction(); + + if (os.getProcessCpuLoad() >= 0) { + ThreadManager threadManager = new ThreadManager(os, load); + // initial ramp up + while (os.getProcessCpuLoad() < load && isActive()) { + threadManager.tick(); + } + final long targetMs = System.currentTimeMillis() + settings.getAssaultProperties().getCpuMillisecondsHoldLoad(); + // hold for specified time + while (targetMs > System.currentTimeMillis() && isActive()) { + threadManager.tick(); + } + threadManager.stop(); + Logger.info("Chaos Monkey - cpu assault cleaned up"); + } else { + Logger.warn("Chaos Monkey - cpu information not available, assault not executed"); } - } } - public void stop() { - runningThreads.addAll(pausedThreads); - for (Thread thread : runningThreads) { - thread.interrupt(); - while (thread.isAlive()) { - try { - thread.join(); - } catch (InterruptedException e) { - thread.interrupt(); - } - } - } + @Override + public String getCronExpression(AssaultProperties assaultProperties) { + return assaultProperties.getCpuCronExpression() != null + ? assaultProperties.getCpuCronExpression() + : assaultProperties.getRuntimeAssaultCronExpression(); } - } - private static class WorkerThread extends Thread { - private volatile boolean shouldPause = false; + private static class ThreadManager { + private final OperatingSystemMXBean os; + private final double targetLoad; + private final List runningThreads = new ArrayList<>(); + private final List pausedThreads = new ArrayList<>(); + private double lastLoad; + + private ThreadManager(OperatingSystemMXBean os, double targetLoad) { + this.os = os; + this.targetLoad = targetLoad; + } + + public void tick() { + double load = os.getProcessCpuLoad(); + // only change things if we have new data + if (load != lastLoad) { + lastLoad = load; + if (load < targetLoad) { + WorkerThread thread; + if (pausedThreads.isEmpty()) { + thread = new WorkerThread("CPU Assault thread " + runningThreads.size()); + thread.start(); + } else { + thread = pausedThreads.remove(0); + synchronized (thread) { + thread.shouldPause = false; + thread.notify(); + } + } + runningThreads.add(thread); + } else if (load > targetLoad + leeway && !runningThreads.isEmpty()) { + WorkerThread thread = runningThreads.remove(0); + thread.shouldPause = true; + pausedThreads.add(thread); + } + // make sure the managing thread doesn't generate too much load + try { + Thread.sleep(200); + } catch (InterruptedException ignored) { + } + } + } - public WorkerThread(String name) { - super(name); + public void stop() { + runningThreads.addAll(pausedThreads); + for (Thread thread : runningThreads) { + thread.interrupt(); + while (thread.isAlive()) { + try { + thread.join(); + } catch (InterruptedException e) { + thread.interrupt(); + } + } + } + } } - @Override - public void run() { - long f1 = 0; - long f2 = 1; - while (!interrupted()) { - try { - if (shouldPause) { - synchronized (this) { - wait(); + private static class WorkerThread extends Thread { + private volatile boolean shouldPause = false; + + public WorkerThread(String name) { + super(name); + } + + @Override + public void run() { + long f1 = 0; + long f2 = 1; + while (!interrupted()) { + try { + if (shouldPause) { + synchronized (this) { + wait(); + } + } + // next fibonacci number + f2 = f1 + f2; + f1 = f2 - f1; + } catch (InterruptedException e) { + // set interrupt flag for outer check + interrupt(); + } } - } - // next fibonacci number - f2 = f1 + f2; - f1 = f2 - f1; - } catch (InterruptedException e) { - // set interrupt flag for outer check - interrupt(); } - } } - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ExceptionAssault.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ExceptionAssault.java index 06c5946e..da931657 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ExceptionAssault.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/ExceptionAssault.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.assaults; import de.codecentric.spring.boot.chaos.monkey.component.MetricEventPublisher; @@ -26,33 +25,33 @@ /** @author Thorsten Deelmann */ public class ExceptionAssault implements ChaosMonkeyRequestAssault { - private static final Logger Logger = LoggerFactory.getLogger(ExceptionAssault.class); + private static final Logger Logger = LoggerFactory.getLogger(ExceptionAssault.class); - private final ChaosMonkeySettings settings; + private final ChaosMonkeySettings settings; - private MetricEventPublisher metricEventPublisher; + private MetricEventPublisher metricEventPublisher; - public ExceptionAssault(ChaosMonkeySettings settings, MetricEventPublisher metricEventPublisher) { - this.settings = settings; - this.metricEventPublisher = metricEventPublisher; - } + public ExceptionAssault(ChaosMonkeySettings settings, MetricEventPublisher metricEventPublisher) { + this.settings = settings; + this.metricEventPublisher = metricEventPublisher; + } - @Override - public boolean isActive() { - return settings.getAssaultProperties().isExceptionsActive(); - } + @Override + public boolean isActive() { + return settings.getAssaultProperties().isExceptionsActive(); + } - @Override - public void attack() { - Logger.info("Chaos Monkey - exception"); + @Override + public void attack() { + Logger.info("Chaos Monkey - exception"); - AssaultException assaultException = this.settings.getAssaultProperties().getException(); + AssaultException assaultException = this.settings.getAssaultProperties().getException(); - // metrics - if (metricEventPublisher != null) { - metricEventPublisher.publishMetricEvent(MetricType.EXCEPTION_ASSAULT); - } + // metrics + if (metricEventPublisher != null) { + metricEventPublisher.publishMetricEvent(MetricType.EXCEPTION_ASSAULT); + } - assaultException.throwExceptionInstance(); - } + assaultException.throwExceptionInstance(); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/KillAppAssault.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/KillAppAssault.java index 954ea83f..dd805364 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/KillAppAssault.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/KillAppAssault.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.assaults; import de.codecentric.spring.boot.chaos.monkey.component.MetricEventPublisher; @@ -31,61 +30,61 @@ /** @author Thorsten Deelmann */ public class KillAppAssault implements ChaosMonkeyRuntimeAssault, ApplicationContextAware { - private static final Logger Logger = LoggerFactory.getLogger(KillAppAssault.class); - - private final ChaosMonkeySettings settings; - - private ApplicationContext context; + private static final Logger Logger = LoggerFactory.getLogger(KillAppAssault.class); - private MetricEventPublisher metricEventPublisher; + private final ChaosMonkeySettings settings; - public KillAppAssault(ChaosMonkeySettings settings, MetricEventPublisher metricEventPublisher) { - this.settings = settings; - this.metricEventPublisher = metricEventPublisher; - } + private ApplicationContext context; - @Override - public boolean isActive() { - return settings.getAssaultProperties().isKillApplicationActive(); - } + private MetricEventPublisher metricEventPublisher; - @Override - public void attack() { - try { - Logger.info("Chaos Monkey - I am killing your Application!"); - - if (metricEventPublisher != null) { - metricEventPublisher.publishMetricEvent(MetricType.KILLAPP_ASSAULT); - } + public KillAppAssault(ChaosMonkeySettings settings, MetricEventPublisher metricEventPublisher) { + this.settings = settings; + this.metricEventPublisher = metricEventPublisher; + } - int exit = SpringApplication.exit(context, (ExitCodeGenerator) () -> 0); + @Override + public boolean isActive() { + return settings.getAssaultProperties().isKillApplicationActive(); + } - long remaining = 5000; - long end = System.currentTimeMillis() + remaining; - while (true) { + @Override + public void attack() { try { - TimeUnit.MILLISECONDS.sleep(remaining); // wait before kill to deliver some metrics - break; - } catch (InterruptedException ignored) { - remaining = end - System.currentTimeMillis(); + Logger.info("Chaos Monkey - I am killing your Application!"); + + if (metricEventPublisher != null) { + metricEventPublisher.publishMetricEvent(MetricType.KILLAPP_ASSAULT); + } + + int exit = SpringApplication.exit(context, (ExitCodeGenerator) () -> 0); + + long remaining = 5000; + long end = System.currentTimeMillis() + remaining; + while (true) { + try { + TimeUnit.MILLISECONDS.sleep(remaining); // wait before kill to deliver some metrics + break; + } catch (InterruptedException ignored) { + remaining = end - System.currentTimeMillis(); + } + } + + System.exit(exit); + } catch (Exception e) { + Logger.info("Chaos Monkey - Unable to kill the App, I am not the BOSS!"); } - } - - System.exit(exit); - } catch (Exception e) { - Logger.info("Chaos Monkey - Unable to kill the App, I am not the BOSS!"); } - } - @Override - public void setApplicationContext(ApplicationContext applicationContext) { - this.context = applicationContext; - } + @Override + public void setApplicationContext(ApplicationContext applicationContext) { + this.context = applicationContext; + } - @Override - public String getCronExpression(AssaultProperties assaultProperties) { - return assaultProperties.getKillApplicationCronExpression() != null - ? assaultProperties.getKillApplicationCronExpression() - : assaultProperties.getRuntimeAssaultCronExpression(); - } + @Override + public String getCronExpression(AssaultProperties assaultProperties) { + return assaultProperties.getKillApplicationCronExpression() != null + ? assaultProperties.getKillApplicationCronExpression() + : assaultProperties.getRuntimeAssaultCronExpression(); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/LatencyAssault.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/LatencyAssault.java index 594f8aa8..d20cc441 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/LatencyAssault.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/LatencyAssault.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.assaults; import de.codecentric.spring.boot.chaos.monkey.component.MetricEventPublisher; @@ -27,58 +26,55 @@ /** @author Thorsten Deelmann */ public class LatencyAssault implements ChaosMonkeyRequestAssault { - private static final Logger Logger = LoggerFactory.getLogger(LatencyAssault.class); + private static final Logger Logger = LoggerFactory.getLogger(LatencyAssault.class); + + private final ChaosMonkeySettings settings; - private final ChaosMonkeySettings settings; + private final ChaosMonkeyLatencyAssaultExecutor assaultExecutor; - private final ChaosMonkeyLatencyAssaultExecutor assaultExecutor; + private MetricEventPublisher metricEventPublisher; - private MetricEventPublisher metricEventPublisher; + private AtomicInteger atomicTimeoutGauge; - private AtomicInteger atomicTimeoutGauge; + public LatencyAssault(ChaosMonkeySettings settings, MetricEventPublisher metricEventPublisher, ChaosMonkeyLatencyAssaultExecutor executor) { + this.settings = settings; + this.metricEventPublisher = metricEventPublisher; + this.atomicTimeoutGauge = new AtomicInteger(0); + this.assaultExecutor = executor; + } - public LatencyAssault( - ChaosMonkeySettings settings, - MetricEventPublisher metricEventPublisher, - ChaosMonkeyLatencyAssaultExecutor executor) { - this.settings = settings; - this.metricEventPublisher = metricEventPublisher; - this.atomicTimeoutGauge = new AtomicInteger(0); - this.assaultExecutor = executor; - } + public LatencyAssault(ChaosMonkeySettings settings, MetricEventPublisher metricEventPublisher) { + this(settings, metricEventPublisher, new LatencyAssaultExecutor()); + } - public LatencyAssault(ChaosMonkeySettings settings, MetricEventPublisher metricEventPublisher) { - this(settings, metricEventPublisher, new LatencyAssaultExecutor()); - } + @Override + public boolean isActive() { + return settings.getAssaultProperties().isLatencyActive(); + } - @Override - public boolean isActive() { - return settings.getAssaultProperties().isLatencyActive(); - } + @Override + public void attack() { + Logger.debug("Chaos Monkey - timeout"); - @Override - public void attack() { - Logger.debug("Chaos Monkey - timeout"); + atomicTimeoutGauge.set(determineLatency()); - atomicTimeoutGauge.set(determineLatency()); + // metrics + if (metricEventPublisher != null) { + metricEventPublisher.publishMetricEvent(MetricType.LATENCY_ASSAULT); + metricEventPublisher.publishMetricEvent(MetricType.LATENCY_ASSAULT, atomicTimeoutGauge); + } - // metrics - if (metricEventPublisher != null) { - metricEventPublisher.publishMetricEvent(MetricType.LATENCY_ASSAULT); - metricEventPublisher.publishMetricEvent(MetricType.LATENCY_ASSAULT, atomicTimeoutGauge); + assaultExecutor.execute(atomicTimeoutGauge.get()); } - assaultExecutor.execute(atomicTimeoutGauge.get()); - } - - private int determineLatency() { - final int latencyRangeStart = settings.getAssaultProperties().getLatencyRangeStart(); - final int latencyRangeEnd = settings.getAssaultProperties().getLatencyRangeEnd(); + private int determineLatency() { + final int latencyRangeStart = settings.getAssaultProperties().getLatencyRangeStart(); + final int latencyRangeEnd = settings.getAssaultProperties().getLatencyRangeEnd(); - if (latencyRangeStart == latencyRangeEnd) { - return latencyRangeStart; - } else { - return ThreadLocalRandom.current().nextInt(latencyRangeStart, latencyRangeEnd); + if (latencyRangeStart == latencyRangeEnd) { + return latencyRangeStart; + } else { + return ThreadLocalRandom.current().nextInt(latencyRangeStart, latencyRangeEnd); + } } - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/LatencyAssaultExecutor.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/LatencyAssaultExecutor.java index c7d97121..bc2078e9 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/LatencyAssaultExecutor.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/LatencyAssaultExecutor.java @@ -1,13 +1,28 @@ +/* + * Copyright 2019-2022 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 + * + * https://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.spring.boot.chaos.monkey.assaults; public class LatencyAssaultExecutor implements ChaosMonkeyLatencyAssaultExecutor { - @Override - public void execute(long durationInMillis) { - try { - Thread.sleep(durationInMillis); - } catch (InterruptedException e) { - // do nothing + @Override + public void execute(long durationInMillis) { + try { + Thread.sleep(durationInMillis); + } catch (InterruptedException e) { + // do nothing + } } - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/MemoryAssault.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/MemoryAssault.java index 39a9c4f6..7ba5748d 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/MemoryAssault.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/MemoryAssault.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.assaults; import de.codecentric.spring.boot.chaos.monkey.component.MetricEventPublisher; @@ -31,151 +30,142 @@ /** @author Benjamin Wilms */ public class MemoryAssault implements ChaosMonkeyRuntimeAssault { - private static final Logger Logger = LoggerFactory.getLogger(MemoryAssault.class); - - private static final AtomicLong stolenMemory = new AtomicLong(0); + private static final Logger Logger = LoggerFactory.getLogger(MemoryAssault.class); - private final Runtime runtime; + private static final AtomicLong stolenMemory = new AtomicLong(0); - private final AtomicBoolean inAttack = new AtomicBoolean(false); + private final Runtime runtime; - private final ChaosMonkeySettings settings; + private final AtomicBoolean inAttack = new AtomicBoolean(false); - private final MetricEventPublisher metricEventPublisher; + private final ChaosMonkeySettings settings; - public MemoryAssault( - Runtime runtime, ChaosMonkeySettings settings, MetricEventPublisher metricEventPublisher) { - this.runtime = runtime; - this.settings = settings; - this.metricEventPublisher = metricEventPublisher; - } + private final MetricEventPublisher metricEventPublisher; - @Override - public boolean isActive() { - return settings.getAssaultProperties().isMemoryActive(); - } - - @Override - @Async - public void attack() { - Logger.info("Chaos Monkey - memory assault"); + public MemoryAssault(Runtime runtime, ChaosMonkeySettings settings, MetricEventPublisher metricEventPublisher) { + this.runtime = runtime; + this.settings = settings; + this.metricEventPublisher = metricEventPublisher; + } - // metrics - if (metricEventPublisher != null) { - metricEventPublisher.publishMetricEvent(MetricType.MEMORY_ASSAULT); + @Override + public boolean isActive() { + return settings.getAssaultProperties().isMemoryActive(); } - if (inAttack.compareAndSet(false, true)) { - try { - Logger.debug("Detected java version: " + System.getProperty("java.version")); - eatFreeMemory(); - } finally { - inAttack.set(false); - } + @Override + @Async + public void attack() { + Logger.info("Chaos Monkey - memory assault"); + + // metrics + if (metricEventPublisher != null) { + metricEventPublisher.publishMetricEvent(MetricType.MEMORY_ASSAULT); + } + + if (inAttack.compareAndSet(false, true)) { + try { + Logger.debug("Detected java version: " + System.getProperty("java.version")); + eatFreeMemory(); + } finally { + inAttack.set(false); + } + } + + Logger.info("Chaos Monkey - memory assault cleaned up"); } - Logger.info("Chaos Monkey - memory assault cleaned up"); - } + private void eatFreeMemory() { + @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") + Vector memoryVector = new Vector<>(); + + long stolenMemoryTotal = 0L; + + while (isActive()) { + // overview of memory methods in java https://stackoverflow.com/a/18375641 + long freeMemory = runtime.freeMemory(); + long usedMemory = runtime.totalMemory() - freeMemory; + + if (cannotAllocateMoreMemory()) { + Logger.debug("Cannot allocate more memory"); + break; + } + + Logger.debug("Used memory in bytes: " + usedMemory); - private void eatFreeMemory() { - @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") - Vector memoryVector = new Vector<>(); + stolenMemoryTotal = stealMemory(memoryVector, stolenMemoryTotal, getBytesToSteal()); + waitUntil(settings.getAssaultProperties().getMemoryMillisecondsWaitNextIncrease()); + } - long stolenMemoryTotal = 0L; + // Hold memory level and cleanUp after, only if experiment is running + if (isActive()) { + Logger.info("Memory fill reached, now sleeping and holding memory"); + waitUntil(settings.getAssaultProperties().getMemoryMillisecondsHoldFilledMemory()); + } - while (isActive()) { - // overview of memory methods in java https://stackoverflow.com/a/18375641 - long freeMemory = runtime.freeMemory(); - long usedMemory = runtime.totalMemory() - freeMemory; + // clean Vector + memoryVector.clear(); + // quickly run gc for reuse + runtime.gc(); - if (cannotAllocateMoreMemory()) { - Logger.debug("Cannot allocate more memory"); - break; - } + long stolenAfterComplete = MemoryAssault.stolenMemory.addAndGet(-stolenMemoryTotal); + metricEventPublisher.publishMetricEvent(MetricType.MEMORY_ASSAULT_MEMORY_STOLEN, stolenAfterComplete); + } + + private boolean cannotAllocateMoreMemory() { + double limit = runtime.maxMemory() * settings.getAssaultProperties().getMemoryFillTargetFraction(); + return runtime.totalMemory() > Math.floor(limit); + } + + private int getBytesToSteal() { + int amount = (int) (runtime.freeMemory() * settings.getAssaultProperties().getMemoryFillIncrementFraction()); + boolean isJava8 = System.getProperty("java.version").startsWith("1.8"); - Logger.debug("Used memory in bytes: " + usedMemory); + // TODO: Check again when JAVA 8 can be dropped. + // seems filling more than 256 MB per slice is bad on java 8 + // we keep running into heap errors and other OOMs. + return isJava8 ? Math.min(SizeConverter.toBytes(256), amount) : amount; + } + + private long stealMemory(Vector memoryVector, long stolenMemoryTotal, int bytesToSteal) { + memoryVector.add(createDirtyMemorySlice(bytesToSteal)); - stolenMemoryTotal = stealMemory(memoryVector, stolenMemoryTotal, getBytesToSteal()); - waitUntil(settings.getAssaultProperties().getMemoryMillisecondsWaitNextIncrease()); + stolenMemoryTotal += bytesToSteal; + long newStolenTotal = MemoryAssault.stolenMemory.addAndGet(bytesToSteal); + metricEventPublisher.publishMetricEvent(MetricType.MEMORY_ASSAULT_MEMORY_STOLEN, newStolenTotal); + Logger.debug("Chaos Monkey - memory assault increase, free memory: " + SizeConverter.toMegabytes(runtime.freeMemory())); + + return stolenMemoryTotal; } - // Hold memory level and cleanUp after, only if experiment is running - if (isActive()) { - Logger.info("Memory fill reached, now sleeping and holding memory"); - waitUntil(settings.getAssaultProperties().getMemoryMillisecondsHoldFilledMemory()); + private byte[] createDirtyMemorySlice(int size) { + byte[] b = new byte[size]; + for (int idx = 0; idx < size; idx += 4096) { // 4096 + // is commonly the size of a memory page, forcing a commit + b[idx] = 19; + } + + return b; } - // clean Vector - memoryVector.clear(); - // quickly run gc for reuse - runtime.gc(); - - long stolenAfterComplete = MemoryAssault.stolenMemory.addAndGet(-stolenMemoryTotal); - metricEventPublisher.publishMetricEvent( - MetricType.MEMORY_ASSAULT_MEMORY_STOLEN, stolenAfterComplete); - } - - private boolean cannotAllocateMoreMemory() { - double limit = - runtime.maxMemory() * settings.getAssaultProperties().getMemoryFillTargetFraction(); - return runtime.totalMemory() > Math.floor(limit); - } - - private int getBytesToSteal() { - int amount = - (int) - (runtime.freeMemory() - * settings.getAssaultProperties().getMemoryFillIncrementFraction()); - boolean isJava8 = System.getProperty("java.version").startsWith("1.8"); - - // TODO: Check again when JAVA 8 can be dropped. - // seems filling more than 256 MB per slice is bad on java 8 - // we keep running into heap errors and other OOMs. - return isJava8 ? Math.min(SizeConverter.toBytes(256), amount) : amount; - } - - private long stealMemory(Vector memoryVector, long stolenMemoryTotal, int bytesToSteal) { - memoryVector.add(createDirtyMemorySlice(bytesToSteal)); - - stolenMemoryTotal += bytesToSteal; - long newStolenTotal = MemoryAssault.stolenMemory.addAndGet(bytesToSteal); - metricEventPublisher.publishMetricEvent( - MetricType.MEMORY_ASSAULT_MEMORY_STOLEN, newStolenTotal); - Logger.debug( - "Chaos Monkey - memory assault increase, free memory: " - + SizeConverter.toMegabytes(runtime.freeMemory())); - - return stolenMemoryTotal; - } - - private byte[] createDirtyMemorySlice(int size) { - byte[] b = new byte[size]; - for (int idx = 0; idx < size; idx += 4096) { // 4096 - // is commonly the size of a memory page, forcing a commit - b[idx] = 19; + private void waitUntil(int ms) { + final long startNano = System.nanoTime(); + long now = startNano; + while (startNano + TimeUnit.MILLISECONDS.toNanos(ms) > now && isActive()) { + try { + long elapsed = TimeUnit.NANOSECONDS.toMillis(startNano - now); + Thread.sleep(Math.min(100, ms - elapsed)); + now = System.nanoTime(); + } catch (InterruptedException e) { + break; + } + } } - return b; - } - - private void waitUntil(int ms) { - final long startNano = System.nanoTime(); - long now = startNano; - while (startNano + TimeUnit.MILLISECONDS.toNanos(ms) > now && isActive()) { - try { - long elapsed = TimeUnit.NANOSECONDS.toMillis(startNano - now); - Thread.sleep(Math.min(100, ms - elapsed)); - now = System.nanoTime(); - } catch (InterruptedException e) { - break; - } + @Override + public String getCronExpression(AssaultProperties assaultProperties) { + return assaultProperties.getMemoryCronExpression() != null + ? assaultProperties.getMemoryCronExpression() + : assaultProperties.getRuntimeAssaultCronExpression(); } - } - - @Override - public String getCronExpression(AssaultProperties assaultProperties) { - return assaultProperties.getMemoryCronExpression() != null - ? assaultProperties.getMemoryCronExpression() - : assaultProperties.getRuntimeAssaultCronExpression(); - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/SizeConverter.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/SizeConverter.java index 14317a8e..e4dab5dd 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/SizeConverter.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/assaults/SizeConverter.java @@ -1,18 +1,33 @@ +/* + * Copyright 2019-2022 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 + * + * https://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.spring.boot.chaos.monkey.assaults; class SizeConverter { - private static final int FACTOR = 1024; + private static final int FACTOR = 1024; - static long toMegabytes(long bytes) { - return bytes / FACTOR / FACTOR; - } + static long toMegabytes(long bytes) { + return bytes / FACTOR / FACTOR; + } - static long toMegabytes(double bytes) { - return toMegabytes((long) bytes); - } + static long toMegabytes(double bytes) { + return toMegabytes((long) bytes); + } - static int toBytes(int megabytes) { - return megabytes * FACTOR * FACTOR; - } + static int toBytes(int megabytes) { + return megabytes * FACTOR * FACTOR; + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeyRequestScope.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeyRequestScope.java index 488cc601..26b1e52b 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeyRequestScope.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeyRequestScope.java @@ -1,20 +1,18 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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.spring.boot.chaos.monkey.component; import static org.springframework.util.CollectionUtils.isEmpty; @@ -36,124 +34,105 @@ /** @author Benjamin Wilms */ public class ChaosMonkeyRequestScope { - private final ChaosMonkeySettings chaosMonkeySettings; - - private final List assaults; - private final ChaosToggles chaosToggles; - private final ChaosToggleNameMapper chaosToggleNameMapper; - - private MetricEventPublisher metricEventPublisher; - - private final AtomicInteger assaultCounter; - - public ChaosMonkeyRequestScope( - ChaosMonkeySettings chaosMonkeySettings, - List assaults, - List legacyAssaults, - MetricEventPublisher metricEventPublisher, - ChaosToggles chaosToggles, - ChaosToggleNameMapper chaosToggleNameMapper) { - List assaultAdapters = - legacyAssaults.stream() - .filter( - it -> - !(it instanceof ChaosMonkeyRequestAssault - || it instanceof ChaosMonkeyRuntimeAssault)) - .map(RequestAssaultAdapter::new) - .collect(Collectors.toList()); - List requestAssaults = new ArrayList<>(); - requestAssaults.addAll(assaults); - requestAssaults.addAll(assaultAdapters); - - this.chaosMonkeySettings = chaosMonkeySettings; - this.assaults = requestAssaults; - this.metricEventPublisher = metricEventPublisher; - this.chaosToggles = chaosToggles; - this.chaosToggleNameMapper = chaosToggleNameMapper; - this.assaultCounter = new AtomicInteger(0); - } - - public void callChaosMonkey(ChaosTarget type, String simpleName) { - if (isEnabled(type, simpleName) && isTrouble()) { - - if (metricEventPublisher != null) { - metricEventPublisher.publishMetricEvent(MetricType.APPLICATION_REQ_COUNT, "type", "total"); - } - - // Custom watched services can be defined at runtime, if there are any, only - // these will be attacked! - AssaultProperties assaultProps = chaosMonkeySettings.getAssaultProperties(); - if (assaultProps.isWatchedCustomServicesActive()) { - if (assaultProps.getWatchedCustomServices().stream().anyMatch(simpleName::startsWith)) { - // only all listed custom methods will be attacked - chooseAndRunAttack(); + private final ChaosMonkeySettings chaosMonkeySettings; + + private final List assaults; + private final ChaosToggles chaosToggles; + private final ChaosToggleNameMapper chaosToggleNameMapper; + + private MetricEventPublisher metricEventPublisher; + + private final AtomicInteger assaultCounter; + + public ChaosMonkeyRequestScope(ChaosMonkeySettings chaosMonkeySettings, List assaults, + List legacyAssaults, MetricEventPublisher metricEventPublisher, ChaosToggles chaosToggles, + ChaosToggleNameMapper chaosToggleNameMapper) { + List assaultAdapters = legacyAssaults.stream() + .filter(it -> !(it instanceof ChaosMonkeyRequestAssault || it instanceof ChaosMonkeyRuntimeAssault)).map(RequestAssaultAdapter::new) + .collect(Collectors.toList()); + List requestAssaults = new ArrayList<>(); + requestAssaults.addAll(assaults); + requestAssaults.addAll(assaultAdapters); + + this.chaosMonkeySettings = chaosMonkeySettings; + this.assaults = requestAssaults; + this.metricEventPublisher = metricEventPublisher; + this.chaosToggles = chaosToggles; + this.chaosToggleNameMapper = chaosToggleNameMapper; + this.assaultCounter = new AtomicInteger(0); + } + + public void callChaosMonkey(ChaosTarget type, String simpleName) { + if (isEnabled(type, simpleName) && isTrouble()) { + + if (metricEventPublisher != null) { + metricEventPublisher.publishMetricEvent(MetricType.APPLICATION_REQ_COUNT, "type", "total"); + } + + // Custom watched services can be defined at runtime, if there are any, only + // these will be attacked! + AssaultProperties assaultProps = chaosMonkeySettings.getAssaultProperties(); + if (assaultProps.isWatchedCustomServicesActive()) { + if (assaultProps.getWatchedCustomServices().stream().anyMatch(simpleName::startsWith)) { + // only all listed custom methods will be attacked + chooseAndRunAttack(); + } + } else { + // default attack if no custom watched service is defined + chooseAndRunAttack(); + } } - } else { - // default attack if no custom watched service is defined - chooseAndRunAttack(); - } } - } - private void chooseAndRunAttack() { - List activeAssaults = - assaults.stream().filter(ChaosMonkeyAssault::isActive).collect(Collectors.toList()); - if (isEmpty(activeAssaults)) { - return; + private void chooseAndRunAttack() { + List activeAssaults = assaults.stream().filter(ChaosMonkeyAssault::isActive).collect(Collectors.toList()); + if (isEmpty(activeAssaults)) { + return; + } + getRandomFrom(activeAssaults).attack(); + + if (metricEventPublisher != null) { + metricEventPublisher.publishMetricEvent(MetricType.APPLICATION_REQ_COUNT, "type", "assaulted"); + } } - getRandomFrom(activeAssaults).attack(); - if (metricEventPublisher != null) { - metricEventPublisher.publishMetricEvent( - MetricType.APPLICATION_REQ_COUNT, "type", "assaulted"); + private ChaosMonkeyAssault getRandomFrom(List activeAssaults) { + int exceptionRand = chaosMonkeySettings.getAssaultProperties().chooseAssault(activeAssaults.size()); + return activeAssaults.get(exceptionRand); } - } - - private ChaosMonkeyAssault getRandomFrom(List activeAssaults) { - int exceptionRand = - chaosMonkeySettings.getAssaultProperties().chooseAssault(activeAssaults.size()); - return activeAssaults.get(exceptionRand); - } - - private boolean isTrouble() { - if (chaosMonkeySettings.getAssaultProperties().isDeterministic()) { - return assaultCounter.incrementAndGet() - % chaosMonkeySettings.getAssaultProperties().getLevel() - == 0; - } else { - return chaosMonkeySettings.getAssaultProperties().getTroubleRandom() - >= chaosMonkeySettings.getAssaultProperties().getLevel(); + + private boolean isTrouble() { + if (chaosMonkeySettings.getAssaultProperties().isDeterministic()) { + return assaultCounter.incrementAndGet() % chaosMonkeySettings.getAssaultProperties().getLevel() == 0; + } else { + return chaosMonkeySettings.getAssaultProperties().getTroubleRandom() >= chaosMonkeySettings.getAssaultProperties().getLevel(); + } } - } - private boolean isEnabled(ChaosTarget type, String name) { - return this.chaosMonkeySettings.getChaosMonkeyProperties().isEnabled() - && chaosToggles.isEnabled(chaosToggleNameMapper.mapName(type, name)); - } + private boolean isEnabled(ChaosTarget type, String name) { + return this.chaosMonkeySettings.getChaosMonkeyProperties().isEnabled() && chaosToggles.isEnabled(chaosToggleNameMapper.mapName(type, name)); + } - private static class RequestAssaultAdapter implements ChaosMonkeyRequestAssault { + private static class RequestAssaultAdapter implements ChaosMonkeyRequestAssault { - private static final Logger Logger = LoggerFactory.getLogger(RequestAssaultAdapter.class); + private static final Logger Logger = LoggerFactory.getLogger(RequestAssaultAdapter.class); - private final ChaosMonkeyAssault rawAssault; + private final ChaosMonkeyAssault rawAssault; - private RequestAssaultAdapter(ChaosMonkeyAssault rawAssault) { - Logger.warn( - "Adapting a " - + rawAssault.getClass().getSimpleName() - + " into a request assault. The class should extend its proper parent"); + private RequestAssaultAdapter(ChaosMonkeyAssault rawAssault) { + Logger.warn("Adapting a " + rawAssault.getClass().getSimpleName() + " into a request assault. The class should extend its proper parent"); - this.rawAssault = rawAssault; - } + this.rawAssault = rawAssault; + } - @Override - public boolean isActive() { - return rawAssault.isActive(); - } + @Override + public boolean isActive() { + return rawAssault.isActive(); + } - @Override - public void attack() { - rawAssault.attack(); + @Override + public void attack() { + rawAssault.attack(); + } } - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeyRuntimeScope.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeyRuntimeScope.java index 1381d4d8..ccbdd31b 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeyRuntimeScope.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeyRuntimeScope.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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.spring.boot.chaos.monkey.component; import de.codecentric.spring.boot.chaos.monkey.assaults.ChaosMonkeyAssault; @@ -14,30 +29,29 @@ */ public class ChaosMonkeyRuntimeScope { - private static final Logger Logger = LoggerFactory.getLogger(ChaosMonkeyRuntimeScope.class); + private static final Logger Logger = LoggerFactory.getLogger(ChaosMonkeyRuntimeScope.class); - private final ChaosMonkeySettings chaosMonkeySettings; + private final ChaosMonkeySettings chaosMonkeySettings; - private final List assaults; + private final List assaults; - public ChaosMonkeyRuntimeScope( - ChaosMonkeySettings chaosMonkeySettings, List assaults) { - this.chaosMonkeySettings = chaosMonkeySettings; - this.assaults = assaults; - } + public ChaosMonkeyRuntimeScope(ChaosMonkeySettings chaosMonkeySettings, List assaults) { + this.chaosMonkeySettings = chaosMonkeySettings; + this.assaults = assaults; + } - public void callChaosMonkey() { - if (isEnabled()) { - Logger.info("Executing all runtime-scoped attacks"); - chooseAndRunAttacks(); + public void callChaosMonkey() { + if (isEnabled()) { + Logger.info("Executing all runtime-scoped attacks"); + chooseAndRunAttacks(); + } } - } - private void chooseAndRunAttacks() { - assaults.stream().filter(ChaosMonkeyAssault::isActive).forEach(ChaosMonkeyAssault::attack); - } + private void chooseAndRunAttacks() { + assaults.stream().filter(ChaosMonkeyAssault::isActive).forEach(ChaosMonkeyAssault::attack); + } - private boolean isEnabled() { - return this.chaosMonkeySettings.getChaosMonkeyProperties().isEnabled(); - } + private boolean isEnabled() { + return this.chaosMonkeySettings.getChaosMonkeyProperties().isEnabled(); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeyScheduler.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeyScheduler.java index e6b0fd7e..a492a3b2 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeyScheduler.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeyScheduler.java @@ -1,3 +1,18 @@ +/* + * Copyright 2019-2022 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 + * + * https://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.spring.boot.chaos.monkey.component; import de.codecentric.spring.boot.chaos.monkey.assaults.ChaosMonkeyRuntimeAssault; @@ -13,81 +28,68 @@ public class ChaosMonkeyScheduler { - private static final Logger Logger = LoggerFactory.getLogger(ChaosMonkeyScheduler.class); + private static final Logger Logger = LoggerFactory.getLogger(ChaosMonkeyScheduler.class); - private final ScheduledTaskRegistrar scheduler; + private final ScheduledTaskRegistrar scheduler; - private final AssaultProperties config; - private final List assaults; + private final AssaultProperties config; + private final List assaults; - private final Map currentTasks = new HashMap<>(); + private final Map currentTasks = new HashMap<>(); - public ChaosMonkeyScheduler( - ScheduledTaskRegistrar scheduler, - AssaultProperties config, - List assaults) { - this.scheduler = scheduler; - this.config = config; - this.assaults = assaults; + public ChaosMonkeyScheduler(ScheduledTaskRegistrar scheduler, AssaultProperties config, List assaults) { + this.scheduler = scheduler; + this.config = config; + this.assaults = assaults; - reloadConfig(); - } + reloadConfig(); + } + + public void reloadConfig() { + Map cronExpressions = getCronExpressions(); + if (!currentTasks.isEmpty()) { + removeUnchangedExpressions(cronExpressions); + cancelOldTasks(cronExpressions); + } + + scheduleNewTasks(cronExpressions); + } + + private Map getCronExpressions() { + return assaults.stream().collect(Collectors.toMap(Function.identity(), assault -> assault.getCronExpression(config))); + } - public void reloadConfig() { - Map cronExpressions = getCronExpressions(); - if (!currentTasks.isEmpty()) { - removeUnchangedExpressions(cronExpressions); - cancelOldTasks(cronExpressions); + private void removeUnchangedExpressions(Map cronExpressions) { + cronExpressions.entrySet().removeIf(entry -> { + ScheduledTask task = currentTasks.get(entry.getKey()); + return task != null && task.getTask() instanceof CronTask + && Objects.equals(((CronTask) task.getTask()).getExpression(), entry.getValue()); + }); } - scheduleNewTasks(cronExpressions); - } - - private Map getCronExpressions() { - return assaults.stream() - .collect( - Collectors.toMap(Function.identity(), assault -> assault.getCronExpression(config))); - } - - private void removeUnchangedExpressions(Map cronExpressions) { - cronExpressions - .entrySet() - .removeIf( - entry -> { - ScheduledTask task = currentTasks.get(entry.getKey()); - return task != null - && task.getTask() instanceof CronTask - && Objects.equals(((CronTask) task.getTask()).getExpression(), entry.getValue()); - }); - } - - private void cancelOldTasks(Map cronExpressions) { - cronExpressions.forEach( - (assault, expression) -> { - ScheduledTask task = currentTasks.remove(assault); - if (task != null) task.cancel(); + private void cancelOldTasks(Map cronExpressions) { + cronExpressions.forEach((assault, expression) -> { + ScheduledTask task = currentTasks.remove(assault); + if (task != null) + task.cancel(); }); - } + } - private void scheduleNewTasks(Map cronExpressions) { - cronExpressions.forEach( - (assault, expression) -> { - if (expression != null && !"OFF".equals(expression)) - scheduleRuntimeAssault(scheduler, assault, expression); + private void scheduleNewTasks(Map cronExpressions) { + cronExpressions.forEach((assault, expression) -> { + if (expression != null && !"OFF".equals(expression)) + scheduleRuntimeAssault(scheduler, assault, expression); }); - } + } - private void scheduleRuntimeAssault( - ScheduledTaskRegistrar scheduler, ChaosMonkeyRuntimeAssault assault, String cron) { + private void scheduleRuntimeAssault(ScheduledTaskRegistrar scheduler, ChaosMonkeyRuntimeAssault assault, String cron) { - final CronTask cronTask = - new CronTask( - () -> { - if (assault.isActive()) assault.attack(); - }, - cron); + final CronTask cronTask = new CronTask(() -> { + if (assault.isActive()) + assault.attack(); + }, cron); - final ScheduledTask scheduledTask = scheduler.scheduleCronTask(cronTask); - currentTasks.put(assault, scheduledTask); - } + final ScheduledTask scheduledTask = scheduler.scheduleCronTask(cronTask); + currentTasks.put(assault, scheduledTask); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosTarget.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosTarget.java index a0a5ac60..4e0d97a6 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosTarget.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosTarget.java @@ -1,23 +1,31 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.component; public enum ChaosTarget { - CONTROLLER("controller"), - REST_CONTROLLER("restController"), - REPOSITORY("repository"), - COMPONENT("component"), - SERVICE("service"), - REST_TEMPLATE("restTemplate"), - WEB_CLIENT("webClient"), - ACTUATOR_HEALTH("actuatorHealth"), - BEAN("bean"); + CONTROLLER("controller"), REST_CONTROLLER("restController"), REPOSITORY("repository"), COMPONENT("component"), SERVICE("service"), REST_TEMPLATE( + "restTemplate"), WEB_CLIENT("webClient"), ACTUATOR_HEALTH("actuatorHealth"), BEAN("bean"); - private final String name; + private final String name; - ChaosTarget(String name) { - this.name = name; - } + ChaosTarget(String name) { + this.name = name; + } - public String getName() { - return name; - } + public String getName() { + return name; + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/MetricEventPublisher.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/MetricEventPublisher.java index aa999969..d0c35fc0 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/MetricEventPublisher.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/MetricEventPublisher.java @@ -1,20 +1,18 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2018-2022 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 + * https://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.spring.boot.chaos.monkey.component; import de.codecentric.spring.boot.chaos.monkey.events.MetricEvent; @@ -25,32 +23,32 @@ /** @author Benjamin Wilms */ public class MetricEventPublisher implements ApplicationEventPublisherAware { - private ApplicationEventPublisher publisher; + private ApplicationEventPublisher publisher; - public void publishMetricEvent(String signature, MetricType metricType, String... tags) { - MetricEvent metricEvent = new MetricEvent(this, metricType, signature, tags); + public void publishMetricEvent(String signature, MetricType metricType, String... tags) { + MetricEvent metricEvent = new MetricEvent(this, metricType, signature, tags); - publisher.publishEvent(metricEvent); - } + publisher.publishEvent(metricEvent); + } - public void publishMetricEvent(MetricType metricType, String... tags) { - MetricEvent metricEvent = new MetricEvent(this, metricType, tags); + public void publishMetricEvent(MetricType metricType, String... tags) { + MetricEvent metricEvent = new MetricEvent(this, metricType, tags); - publisher.publishEvent(metricEvent); - } + publisher.publishEvent(metricEvent); + } - public void publishMetricEvent(MetricType metricType, AtomicInteger atomicTimeoutGauge) { - final long gaugeValue = (atomicTimeoutGauge == null) ? -1 : atomicTimeoutGauge.longValue(); - MetricEvent metricEvent = new MetricEvent(this, metricType, gaugeValue, null); - publisher.publishEvent(metricEvent); - } + public void publishMetricEvent(MetricType metricType, AtomicInteger atomicTimeoutGauge) { + final long gaugeValue = (atomicTimeoutGauge == null) ? -1 : atomicTimeoutGauge.longValue(); + MetricEvent metricEvent = new MetricEvent(this, metricType, gaugeValue, null); + publisher.publishEvent(metricEvent); + } - public void publishMetricEvent(MetricType type, long metricValue) { - publisher.publishEvent(new MetricEvent(this, type, metricValue, null)); - } + public void publishMetricEvent(MetricType type, long metricValue) { + publisher.publishEvent(new MetricEvent(this, type, metricValue, null)); + } - @Override - public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { - this.publisher = applicationEventPublisher; - } + @Override + public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { + this.publisher = applicationEventPublisher; + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/MetricType.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/MetricType.java index 99adacf4..239a1899 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/MetricType.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/MetricType.java @@ -1,43 +1,51 @@ +/* + * Copyright 2018-2022 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 + * + * https://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.spring.boot.chaos.monkey.component; /** @author Benjamin Wilms */ public enum MetricType { - CONTROLLER("controller", true, false), - RESTCONTROLLER("restController", true, false), - REPOSITORY("repository", true, false), - COMPONENT("component", true, false), - SERVICE("service", true, false), - BEAN("bean", true, false), - LATENCY_ASSAULT("assault.latency.count", false, false), - EXCEPTION_ASSAULT("assault.exception.count", false, false), - KILLAPP_ASSAULT("assault.killapp.count", false, true), - APPLICATION_REQ_COUNT("application.request.count", false, true), - MEMORY_ASSAULT("assault.memory.count", false, false), - MEMORY_ASSAULT_MEMORY_STOLEN("assault.memory.bytes_stolen", false, false), - CPU_ASSAULT("assault.cpu.count", false, false); - - private final String metricName; - - private final boolean signatureEvent; - - private final boolean tagEvent; - - MetricType(String metricName, boolean signatureEvent, boolean tagEvent) { - this.metricName = metricName; - this.signatureEvent = signatureEvent; - this.tagEvent = tagEvent; - } - - public String getMetricName() { - String metricBaseName = "chaos.monkey."; - return metricBaseName + metricName; - } - - public boolean isSignatureOnlyEvent() { - return signatureEvent; - } - - public boolean isTagEvent() { - return tagEvent; - } + CONTROLLER("controller", true, false), RESTCONTROLLER("restController", true, false), REPOSITORY("repository", true, false), COMPONENT( + "component", true, false), SERVICE("service", true, false), BEAN("bean", true, false), LATENCY_ASSAULT("assault.latency.count", false, + false), EXCEPTION_ASSAULT("assault.exception.count", false, false), KILLAPP_ASSAULT("assault.killapp.count", false, + true), APPLICATION_REQ_COUNT("application.request.count", false, true), MEMORY_ASSAULT("assault.memory.count", false, + false), MEMORY_ASSAULT_MEMORY_STOLEN("assault.memory.bytes_stolen", false, + false), CPU_ASSAULT("assault.cpu.count", false, false); + + private final String metricName; + + private final boolean signatureEvent; + + private final boolean tagEvent; + + MetricType(String metricName, boolean signatureEvent, boolean tagEvent) { + this.metricName = metricName; + this.signatureEvent = signatureEvent; + this.tagEvent = tagEvent; + } + + public String getMetricName() { + String metricBaseName = "chaos.monkey."; + return metricBaseName + metricName; + } + + public boolean isSignatureOnlyEvent() { + return signatureEvent; + } + + public boolean isTagEvent() { + return tagEvent; + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/Metrics.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/Metrics.java index f91a5e3a..49f3ab15 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/Metrics.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/component/Metrics.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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.spring.boot.chaos.monkey.component; import de.codecentric.spring.boot.chaos.monkey.events.MetricEvent; @@ -7,46 +22,44 @@ /** @author Benjamin Wilms */ public class Metrics implements ApplicationListener { - private MeterRegistry meterRegistry; + private MeterRegistry meterRegistry; - public Metrics() { - this.meterRegistry = io.micrometer.core.instrument.Metrics.globalRegistry; - } + public Metrics() { + this.meterRegistry = io.micrometer.core.instrument.Metrics.globalRegistry; + } + + private void counter(MetricType type, String... tags) { + if (meterRegistry != null && tags != null) { + meterRegistry.counter(type.getMetricName(), tags).increment(); + } + } - private void counter(MetricType type, String... tags) { - if (meterRegistry != null && tags != null) { - meterRegistry.counter(type.getMetricName(), tags).increment(); + private void counterWatcher(MetricType type, String name) { + if (meterRegistry != null) { + meterRegistry.counter(type.getMetricName() + ".watcher", "component", extractComponent(name)).increment(); + } } - } - private void counterWatcher(MetricType type, String name) { - if (meterRegistry != null) { - meterRegistry - .counter(type.getMetricName() + ".watcher", "component", extractComponent(name)) - .increment(); + private void gauge(MetricType type, double number) { + if (meterRegistry != null) { + meterRegistry.gauge(type.getMetricName() + ".gauge.", number); + } } - } - private void gauge(MetricType type, double number) { - if (meterRegistry != null) { - meterRegistry.gauge(type.getMetricName() + ".gauge.", number); + private String extractComponent(String name) { + return name.replaceAll("execution.", ""); } - } - - private String extractComponent(String name) { - return name.replaceAll("execution.", ""); - } - - @Override - public void onApplicationEvent(MetricEvent event) { - if (event.getMetricType().isSignatureOnlyEvent()) { - counterWatcher(event.getMetricType(), event.getMethodSignature()); - } else if (event.getMetricType().isTagEvent()) { - counter(event.getMetricType(), event.getTags()); - } else { // untagged and without method signature -> metric value is the interesting - // part - gauge(event.getMetricType(), event.getMetricValue()); - counter(event.getMetricType(), event.getTags()); + + @Override + public void onApplicationEvent(MetricEvent event) { + if (event.getMetricType().isSignatureOnlyEvent()) { + counterWatcher(event.getMetricType(), event.getMethodSignature()); + } else if (event.getMetricType().isTagEvent()) { + counter(event.getMetricType(), event.getTags()); + } else { // untagged and without method signature -> metric value is the interesting + // part + gauge(event.getMetricType(), event.getMetricValue()); + counter(event.getMetricType(), event.getTags()); + } } - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/AssaultException.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/AssaultException.java index 56f1066a..dbfbf843 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/AssaultException.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/AssaultException.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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.spring.boot.chaos.monkey.configuration; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -18,121 +33,124 @@ @Data public class AssaultException { - private static final Logger Logger = LoggerFactory.getLogger(AssaultException.class); + private static final Logger Logger = LoggerFactory.getLogger(AssaultException.class); - private static final ObjectMapper objectMapper = new ObjectMapper(); + private static final ObjectMapper objectMapper = new ObjectMapper(); - /** - * special value used to represent constructors. "" was chosen because it is used as jvm - * internal name for constructors, which means no method could be named like this. - */ - private static final String CONSTRUCTOR = ""; + /** + * special value used to represent constructors. "" was chosen because it + * is used as jvm internal name for constructors, which means no method could be + * named like this. + */ + private static final String CONSTRUCTOR = ""; - @NotNull private String type = "java.lang.RuntimeException"; + @NotNull + private String type = "java.lang.RuntimeException"; - @NotNull private String method = CONSTRUCTOR; + @NotNull + private String method = CONSTRUCTOR; - @NotNull @NestedConfigurationProperty - private List arguments = - Collections.singletonList( - new ExceptionArgument(String.class.getName(), "Chaos Monkey - RuntimeException")); + @NotNull + @NestedConfigurationProperty + private List arguments = Collections + .singletonList(new ExceptionArgument(String.class.getName(), "Chaos Monkey - RuntimeException")); - @SneakyThrows - @JsonIgnore - public void throwExceptionInstance() { - throw getThrowable(); - } + @SneakyThrows + @JsonIgnore + public void throwExceptionInstance() { + throw getThrowable(); + } - @JsonIgnore - private Throwable getThrowable() { - Throwable instance; - try { - ThrowableCreator creator = getCreator(); - instance = creator.create(getExceptionArgumentValues()); - } catch (ReflectiveOperationException | ClassCastException | JsonProcessingException e) { - Logger.warn("Failed to create custom exception. Fallback: Throw RuntimeException"); - instance = new RuntimeException("Chaos Monkey - RuntimeException (Fallback)", e); + @JsonIgnore + private Throwable getThrowable() { + Throwable instance; + try { + ThrowableCreator creator = getCreator(); + instance = creator.create(getExceptionArgumentValues()); + } catch (ReflectiveOperationException | ClassCastException | JsonProcessingException e) { + Logger.warn("Failed to create custom exception. Fallback: Throw RuntimeException"); + instance = new RuntimeException("Chaos Monkey - RuntimeException (Fallback)", e); + } + return instance; } - return instance; - } - - @JsonIgnore - public ThrowableCreator getCreator() throws ReflectiveOperationException { - Class exceptionClass = getExceptionClass(); - Class[] argumentTypes = getExceptionArgumentTypes().toArray(new Class[0]); - if (CONSTRUCTOR.equals(method)) { - return new ThrowableConstructor( - exceptionClass.asSubclass(Throwable.class).getConstructor(argumentTypes)); - } else { - return new ThrowableStaticInitializer(exceptionClass.getMethod(method, argumentTypes)); + + @JsonIgnore + public ThrowableCreator getCreator() throws ReflectiveOperationException { + Class exceptionClass = getExceptionClass(); + Class[] argumentTypes = getExceptionArgumentTypes().toArray(new Class[0]); + if (CONSTRUCTOR.equals(method)) { + return new ThrowableConstructor(exceptionClass.asSubclass(Throwable.class).getConstructor(argumentTypes)); + } else { + return new ThrowableStaticInitializer(exceptionClass.getMethod(method, argumentTypes)); + } } - } - @JsonIgnore - public Class getExceptionClass() throws ClassNotFoundException { - return Class.forName(type); - } + @JsonIgnore + public Class getExceptionClass() throws ClassNotFoundException { + return Class.forName(type); + } - private List> getExceptionArgumentTypes() throws ClassNotFoundException { - List> exceptionArgumentTypes = new ArrayList<>(); - for (ExceptionArgument argument : arguments) { - exceptionArgumentTypes.add(argument.getClassType()); + private List> getExceptionArgumentTypes() throws ClassNotFoundException { + List> exceptionArgumentTypes = new ArrayList<>(); + for (ExceptionArgument argument : arguments) { + exceptionArgumentTypes.add(argument.getClassType()); + } + return exceptionArgumentTypes; } - return exceptionArgumentTypes; - } - - private List getExceptionArgumentValues() - throws ClassNotFoundException, JsonProcessingException { - List exceptionArgumentValues = new ArrayList<>(); - for (ExceptionArgument argument : arguments) { - Class classType = argument.getClassType(); - String value = argument.getValue(); - try { - // this mostly works for primitive values and strings - exceptionArgumentValues.add(objectMapper.convertValue(value, classType)); - } catch (IllegalArgumentException e) { - // treat value as json encoded otherwise - exceptionArgumentValues.add(objectMapper.readValue(value, classType)); - } + + private List getExceptionArgumentValues() throws ClassNotFoundException, JsonProcessingException { + List exceptionArgumentValues = new ArrayList<>(); + for (ExceptionArgument argument : arguments) { + Class classType = argument.getClassType(); + String value = argument.getValue(); + try { + // this mostly works for primitive values and strings + exceptionArgumentValues.add(objectMapper.convertValue(value, classType)); + } catch (IllegalArgumentException e) { + // treat value as json encoded otherwise + exceptionArgumentValues.add(objectMapper.readValue(value, classType)); + } + } + return exceptionArgumentValues; } - return exceptionArgumentValues; - } - @Data - @NoArgsConstructor - @AllArgsConstructor - public static class ExceptionArgument { - @NotNull private String type; + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class ExceptionArgument { + @NotNull + private String type; - @NotNull private String value; + @NotNull + private String value; - @JsonIgnore - public Class getClassType() throws ClassNotFoundException { - return ClassUtils.forName(type, null); + @JsonIgnore + public Class getClassType() throws ClassNotFoundException { + return ClassUtils.forName(type, null); + } } - } - private interface ThrowableCreator { - Throwable create(List arguments) throws ReflectiveOperationException; - } + private interface ThrowableCreator { + Throwable create(List arguments) throws ReflectiveOperationException; + } - @RequiredArgsConstructor - private static class ThrowableConstructor implements ThrowableCreator { - private final Constructor constructor; + @RequiredArgsConstructor + private static class ThrowableConstructor implements ThrowableCreator { + private final Constructor constructor; - @Override - public Throwable create(List arguments) throws ReflectiveOperationException { - return constructor.newInstance(arguments.toArray()); + @Override + public Throwable create(List arguments) throws ReflectiveOperationException { + return constructor.newInstance(arguments.toArray()); + } } - } - @RequiredArgsConstructor - private static class ThrowableStaticInitializer implements ThrowableCreator { - private final Method initializer; + @RequiredArgsConstructor + private static class ThrowableStaticInitializer implements ThrowableCreator { + private final Method initializer; - @Override - public Throwable create(List arguments) throws ReflectiveOperationException { - return (Throwable) initializer.invoke(null, arguments.toArray()); + @Override + public Throwable create(List arguments) throws ReflectiveOperationException { + return (Throwable) initializer.invoke(null, arguments.toArray()); + } } - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/AssaultProperties.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/AssaultProperties.java index 9346a448..f048006f 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/AssaultProperties.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/AssaultProperties.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.configuration; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -31,80 +30,83 @@ @NoArgsConstructor @ConfigurationProperties(prefix = "chaos.monkey.assaults") public class AssaultProperties { - private int level = 1; + private int level = 1; - private boolean deterministic = false; + private boolean deterministic = false; - private int latencyRangeStart = 1000; + private int latencyRangeStart = 1000; - private int latencyRangeEnd = 3000; + private int latencyRangeEnd = 3000; - private boolean latencyActive = false; + private boolean latencyActive = false; - private boolean exceptionsActive = false; + private boolean exceptionsActive = false; - @NestedConfigurationProperty private AssaultException exception; + @NestedConfigurationProperty + private AssaultException exception; - private boolean killApplicationActive = false; + private boolean killApplicationActive = false; - // TODO change this to "OFF" when runtimeAssaultCronExpression is removed - private String killApplicationCronExpression = null; + // TODO change this to "OFF" when runtimeAssaultCronExpression is removed + private String killApplicationCronExpression = null; - private volatile boolean memoryActive = false; + private volatile boolean memoryActive = false; - private int memoryMillisecondsHoldFilledMemory = 90000; + private int memoryMillisecondsHoldFilledMemory = 90000; - private int memoryMillisecondsWaitNextIncrease = 1000; + private int memoryMillisecondsWaitNextIncrease = 1000; - private double memoryFillIncrementFraction = 0.15; + private double memoryFillIncrementFraction = 0.15; - private double memoryFillTargetFraction = 0.25; + private double memoryFillTargetFraction = 0.25; - // TODO change this to "OFF" when runtimeAssaultCronExpression is removed - private String memoryCronExpression = null; + // TODO change this to "OFF" when runtimeAssaultCronExpression is removed + private String memoryCronExpression = null; - private volatile boolean cpuActive = false; + private volatile boolean cpuActive = false; - private int cpuMillisecondsHoldLoad = 90000; + private int cpuMillisecondsHoldLoad = 90000; - private double cpuLoadTargetFraction = 0.9; + private double cpuLoadTargetFraction = 0.9; - // TODO change this to "OFF" when runtimeAssaultCronExpression is removed - private String cpuCronExpression = null; + // TODO change this to "OFF" when runtimeAssaultCronExpression is removed + private String cpuCronExpression = null; - /** - * @deprecated please use {@link #killApplicationCronExpression}, {@link #memoryCronExpression} or - * {@link #cpuCronExpression} instead - */ - @Deprecated private String runtimeAssaultCronExpression = "OFF"; + /** + * @deprecated please use {@link #killApplicationCronExpression}, + * {@link #memoryCronExpression} or {@link #cpuCronExpression} + * instead + */ + @Deprecated + private String runtimeAssaultCronExpression = "OFF"; - private List watchedCustomServices; + private List watchedCustomServices; - public AssaultException getException() { - return exception == null ? new AssaultException() : exception; - } + public AssaultException getException() { + return exception == null ? new AssaultException() : exception; + } - public void setException(AssaultException exception) { - this.exception = exception; - } + public void setException(AssaultException exception) { + this.exception = exception; + } - @JsonIgnore - public int getTroubleRandom() { - return ThreadLocalRandom.current().nextInt(1, getLevel() + 1); - } + @JsonIgnore + public int getTroubleRandom() { + return ThreadLocalRandom.current().nextInt(1, getLevel() + 1); + } - @JsonIgnore - public int chooseAssault(int amount) { - return ThreadLocalRandom.current().nextInt(0, amount); - } + @JsonIgnore + public int chooseAssault(int amount) { + return ThreadLocalRandom.current().nextInt(0, amount); + } - @JsonIgnore - public boolean isWatchedCustomServicesActive() { - return !CollectionUtils.isEmpty(watchedCustomServices); - } + @JsonIgnore + public boolean isWatchedCustomServicesActive() { + return !CollectionUtils.isEmpty(watchedCustomServices); + } - public AssaultPropertiesUpdate toDto() { - ObjectMapper mapper = new ObjectMapper(); - return mapper.convertValue(this, AssaultPropertiesUpdate.class); - } + public AssaultPropertiesUpdate toDto() { + ObjectMapper mapper = new ObjectMapper(); + return mapper.convertValue(this, AssaultPropertiesUpdate.class); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyCondition.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyCondition.java index c8a5037d..2fb5a408 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyCondition.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyCondition.java @@ -1,20 +1,18 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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.spring.boot.chaos.monkey.configuration; import org.springframework.context.annotation.Condition; @@ -24,11 +22,10 @@ /** @author Daekwon Kang */ public class ChaosMonkeyCondition implements Condition { - @Override - public boolean matches( - ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { + @Override + public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { - return conditionContext.getEnvironment().acceptsProfiles(Profiles.of("chaos-monkey")) - || Boolean.parseBoolean(System.getProperty("LOAD_CHAOS_MONKEY")); - } + return conditionContext.getEnvironment().acceptsProfiles(Profiles.of("chaos-monkey")) + || Boolean.parseBoolean(System.getProperty("LOAD_CHAOS_MONKEY")); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyConfiguration.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyConfiguration.java index 71d9b8ff..c083ee69 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyConfiguration.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyConfiguration.java @@ -1,20 +1,18 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2017-2022 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 + * https://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.spring.boot.chaos.monkey.configuration; import com.sun.management.OperatingSystemMXBean; @@ -48,206 +46,175 @@ @Configuration @Conditional(ChaosMonkeyCondition.class) -@EnableConfigurationProperties({ - ChaosMonkeyProperties.class, - AssaultProperties.class, - WatcherProperties.class -}) -@Import({ - UnleashChaosConfiguration.class, - ChaosMonkeyWebClientConfiguration.class, - ChaosMonkeyRestTemplateConfiguration.class -}) +@EnableConfigurationProperties({ChaosMonkeyProperties.class, AssaultProperties.class, WatcherProperties.class}) +@Import({UnleashChaosConfiguration.class, ChaosMonkeyWebClientConfiguration.class, ChaosMonkeyRestTemplateConfiguration.class}) @EnableScheduling public class ChaosMonkeyConfiguration { - private static final Logger Logger = LoggerFactory.getLogger(ChaosMonkeyConfiguration.class); - - private static final String CHAOS_MONKEY_TASK_SCHEDULER = "chaosMonkeyTaskScheduler"; - - private final ChaosMonkeyProperties chaosMonkeyProperties; - - private final WatcherProperties watcherProperties; - - private final AssaultProperties assaultProperties; - - public ChaosMonkeyConfiguration( - ChaosMonkeyProperties chaosMonkeyProperties, - WatcherProperties watcherProperties, - AssaultProperties assaultProperties) { - this.chaosMonkeyProperties = chaosMonkeyProperties; - this.watcherProperties = watcherProperties; - this.assaultProperties = assaultProperties; - - try { - String chaosLogo = - StreamUtils.copyToString( - new ClassPathResource("chaos-logo.txt").getInputStream(), Charset.defaultCharset()); - Logger.info(chaosLogo); - } catch (IOException e) { - Logger.info("Chaos Monkey - ready to do evil"); - } - } - - @Bean - @ConditionalOnClass(name = "io.micrometer.core.instrument.MeterRegistry") - public Metrics metrics() { - return new Metrics(); - } - - @Bean - public MetricEventPublisher publisher() { - return new MetricEventPublisher(); - } - - @Bean - public ChaosMonkeySettings settings() { - return new ChaosMonkeySettings(chaosMonkeyProperties, assaultProperties, watcherProperties); - } - - @Bean - public LatencyAssault latencyAssault() { - return new LatencyAssault(settings(), publisher()); - } - - @Bean - public ExceptionAssault exceptionAssault() { - return new ExceptionAssault(settings(), publisher()); - } - - @Bean - public KillAppAssault killAppAssault() { - return new KillAppAssault(settings(), publisher()); - } - - @Bean - public MemoryAssault memoryAssault() { - return new MemoryAssault(Runtime.getRuntime(), settings(), publisher()); - } - - @Bean - public CpuAssault cpuAssault() { - return new CpuAssault( - ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class), settings(), publisher()); - } - - @Bean - public ChaosMonkeyRequestScope chaosMonkeyRequestScope( - List chaosMonkeyAssaults, - List allAssaults, - ChaosToggles chaosToggles, - ChaosToggleNameMapper chaosToggleNameMapper) { - return new ChaosMonkeyRequestScope( - settings(), - chaosMonkeyAssaults, - allAssaults, - publisher(), - chaosToggles, - chaosToggleNameMapper); - } - - @Bean - @ConditionalOnMissingBean(ChaosToggleNameMapper.class) - public ChaosToggleNameMapper chaosToggleNameMapper(ChaosMonkeyProperties chaosMonkeyProperties) { - return new DefaultChaosToggleNameMapper(chaosMonkeyProperties.getTogglePrefix()); - } - - @Bean - @ConditionalOnMissingBean(ChaosToggles.class) - public ChaosToggles chaosToggles() { - return new DefaultChaosToggles(); - } - - @Bean - public ChaosMonkeyScheduler chaosMonkeyScheduler( - @Qualifier(CHAOS_MONKEY_TASK_SCHEDULER) TaskScheduler scheduler, - List assaults) { - ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar(); - registrar.setTaskScheduler(scheduler); - return new ChaosMonkeyScheduler(registrar, assaultProperties, assaults); - } - - @Bean(name = CHAOS_MONKEY_TASK_SCHEDULER) - public TaskScheduler chaosMonkeyTaskScheduler() { - return new ThreadPoolTaskScheduler(); - } - - @Bean - public ChaosMonkeyRuntimeScope chaosMonkeyRuntimeScope( - List chaosMonkeyAssaults) { - return new ChaosMonkeyRuntimeScope(settings(), chaosMonkeyAssaults); - } - - @Bean - @DependsOn("chaosMonkeyRequestScope") - public SpringControllerAspect controllerAspect(ChaosMonkeyRequestScope chaosMonkeyRequestScope) { - return new SpringControllerAspect(chaosMonkeyRequestScope, publisher(), watcherProperties); - } - - @Bean - @DependsOn("chaosMonkeyRequestScope") - public SpringRestControllerAspect restControllerAspect( - ChaosMonkeyRequestScope chaosMonkeyRequestScope) { - return new SpringRestControllerAspect(chaosMonkeyRequestScope, publisher(), watcherProperties); - } - - @Bean - @DependsOn("chaosMonkeyRequestScope") - public SpringServiceAspect serviceAspect(ChaosMonkeyRequestScope chaosMonkeyRequestScope) { - return new SpringServiceAspect(chaosMonkeyRequestScope, publisher(), watcherProperties); - } - - @Bean - @DependsOn("chaosMonkeyRequestScope") - public SpringComponentAspect componentAspect(ChaosMonkeyRequestScope chaosMonkeyRequestScope) { - return new SpringComponentAspect(chaosMonkeyRequestScope, publisher(), watcherProperties); - } - - @Bean - @DependsOn("chaosMonkeyRequestScope") - @ConditionalOnClass(name = "org.springframework.data.repository.Repository") - // Creates aspects that match interfaces annotated with @Repository - public SpringRepositoryAspectJPA repositoryAspectJpa( - ChaosMonkeyRequestScope chaosMonkeyRequestScope) { - return new SpringRepositoryAspectJPA(chaosMonkeyRequestScope, publisher(), watcherProperties); - } - - @Bean - @DependsOn("chaosMonkeyRequestScope") - // creates aspects that match simple classes annotated with @repository - public SpringRepositoryAspectJDBC repositoryAspectJdbc( - ChaosMonkeyRequestScope chaosMonkeyRequestScope) { - return new SpringRepositoryAspectJDBC(chaosMonkeyRequestScope, publisher(), watcherProperties); - } - - @Bean - @DependsOn("chaosMonkeyRequestScope") - @ConditionalOnClass(name = "org.springframework.boot.actuate.health.HealthIndicator") - public SpringBootHealthIndicatorAspect springBootHealthIndicatorAspect( - ChaosMonkeyRequestScope chaosMonkeyRequestScope) { - return new SpringBootHealthIndicatorAspect(chaosMonkeyRequestScope, watcherProperties); - } - - @Bean - @DependsOn("chaosMonkeyRequestScope") - public ChaosMonkeyBeanPostProcessor chaosMonkeyBeanPostProcessor( - ChaosMonkeyRequestScope chaosMonkeyRequestScope) { - return new ChaosMonkeyBeanPostProcessor( - watcherProperties, chaosMonkeyRequestScope, publisher()); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnAvailableEndpoint - public ChaosMonkeyRestEndpoint chaosMonkeyRestEndpoint( - ChaosMonkeyRuntimeScope runtimeScope, ChaosMonkeyScheduler scheduler) { - return new ChaosMonkeyRestEndpoint(settings(), runtimeScope, scheduler); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnAvailableEndpoint - public ChaosMonkeyJmxEndpoint chaosMonkeyJmxEndpoint() { - return new ChaosMonkeyJmxEndpoint(settings()); - } + private static final Logger Logger = LoggerFactory.getLogger(ChaosMonkeyConfiguration.class); + + private static final String CHAOS_MONKEY_TASK_SCHEDULER = "chaosMonkeyTaskScheduler"; + + private final ChaosMonkeyProperties chaosMonkeyProperties; + + private final WatcherProperties watcherProperties; + + private final AssaultProperties assaultProperties; + + public ChaosMonkeyConfiguration(ChaosMonkeyProperties chaosMonkeyProperties, WatcherProperties watcherProperties, + AssaultProperties assaultProperties) { + this.chaosMonkeyProperties = chaosMonkeyProperties; + this.watcherProperties = watcherProperties; + this.assaultProperties = assaultProperties; + + try { + String chaosLogo = StreamUtils.copyToString(new ClassPathResource("chaos-logo.txt").getInputStream(), Charset.defaultCharset()); + Logger.info(chaosLogo); + } catch (IOException e) { + Logger.info("Chaos Monkey - ready to do evil"); + } + } + + @Bean + @ConditionalOnClass(name = "io.micrometer.core.instrument.MeterRegistry") + public Metrics metrics() { + return new Metrics(); + } + + @Bean + public MetricEventPublisher publisher() { + return new MetricEventPublisher(); + } + + @Bean + public ChaosMonkeySettings settings() { + return new ChaosMonkeySettings(chaosMonkeyProperties, assaultProperties, watcherProperties); + } + + @Bean + public LatencyAssault latencyAssault() { + return new LatencyAssault(settings(), publisher()); + } + + @Bean + public ExceptionAssault exceptionAssault() { + return new ExceptionAssault(settings(), publisher()); + } + + @Bean + public KillAppAssault killAppAssault() { + return new KillAppAssault(settings(), publisher()); + } + + @Bean + public MemoryAssault memoryAssault() { + return new MemoryAssault(Runtime.getRuntime(), settings(), publisher()); + } + + @Bean + public CpuAssault cpuAssault() { + return new CpuAssault(ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class), settings(), publisher()); + } + + @Bean + public ChaosMonkeyRequestScope chaosMonkeyRequestScope(List chaosMonkeyAssaults, List allAssaults, + ChaosToggles chaosToggles, ChaosToggleNameMapper chaosToggleNameMapper) { + return new ChaosMonkeyRequestScope(settings(), chaosMonkeyAssaults, allAssaults, publisher(), chaosToggles, chaosToggleNameMapper); + } + + @Bean + @ConditionalOnMissingBean(ChaosToggleNameMapper.class) + public ChaosToggleNameMapper chaosToggleNameMapper(ChaosMonkeyProperties chaosMonkeyProperties) { + return new DefaultChaosToggleNameMapper(chaosMonkeyProperties.getTogglePrefix()); + } + + @Bean + @ConditionalOnMissingBean(ChaosToggles.class) + public ChaosToggles chaosToggles() { + return new DefaultChaosToggles(); + } + + @Bean + public ChaosMonkeyScheduler chaosMonkeyScheduler(@Qualifier(CHAOS_MONKEY_TASK_SCHEDULER) TaskScheduler scheduler, + List assaults) { + ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar(); + registrar.setTaskScheduler(scheduler); + return new ChaosMonkeyScheduler(registrar, assaultProperties, assaults); + } + + @Bean(name = CHAOS_MONKEY_TASK_SCHEDULER) + public TaskScheduler chaosMonkeyTaskScheduler() { + return new ThreadPoolTaskScheduler(); + } + + @Bean + public ChaosMonkeyRuntimeScope chaosMonkeyRuntimeScope(List chaosMonkeyAssaults) { + return new ChaosMonkeyRuntimeScope(settings(), chaosMonkeyAssaults); + } + + @Bean + @DependsOn("chaosMonkeyRequestScope") + public SpringControllerAspect controllerAspect(ChaosMonkeyRequestScope chaosMonkeyRequestScope) { + return new SpringControllerAspect(chaosMonkeyRequestScope, publisher(), watcherProperties); + } + + @Bean + @DependsOn("chaosMonkeyRequestScope") + public SpringRestControllerAspect restControllerAspect(ChaosMonkeyRequestScope chaosMonkeyRequestScope) { + return new SpringRestControllerAspect(chaosMonkeyRequestScope, publisher(), watcherProperties); + } + + @Bean + @DependsOn("chaosMonkeyRequestScope") + public SpringServiceAspect serviceAspect(ChaosMonkeyRequestScope chaosMonkeyRequestScope) { + return new SpringServiceAspect(chaosMonkeyRequestScope, publisher(), watcherProperties); + } + + @Bean + @DependsOn("chaosMonkeyRequestScope") + public SpringComponentAspect componentAspect(ChaosMonkeyRequestScope chaosMonkeyRequestScope) { + return new SpringComponentAspect(chaosMonkeyRequestScope, publisher(), watcherProperties); + } + + @Bean + @DependsOn("chaosMonkeyRequestScope") + @ConditionalOnClass(name = "org.springframework.data.repository.Repository") + // Creates aspects that match interfaces annotated with @Repository + public SpringRepositoryAspectJPA repositoryAspectJpa(ChaosMonkeyRequestScope chaosMonkeyRequestScope) { + return new SpringRepositoryAspectJPA(chaosMonkeyRequestScope, publisher(), watcherProperties); + } + + @Bean + @DependsOn("chaosMonkeyRequestScope") + // creates aspects that match simple classes annotated with @repository + public SpringRepositoryAspectJDBC repositoryAspectJdbc(ChaosMonkeyRequestScope chaosMonkeyRequestScope) { + return new SpringRepositoryAspectJDBC(chaosMonkeyRequestScope, publisher(), watcherProperties); + } + + @Bean + @DependsOn("chaosMonkeyRequestScope") + @ConditionalOnClass(name = "org.springframework.boot.actuate.health.HealthIndicator") + public SpringBootHealthIndicatorAspect springBootHealthIndicatorAspect(ChaosMonkeyRequestScope chaosMonkeyRequestScope) { + return new SpringBootHealthIndicatorAspect(chaosMonkeyRequestScope, watcherProperties); + } + + @Bean + @DependsOn("chaosMonkeyRequestScope") + public ChaosMonkeyBeanPostProcessor chaosMonkeyBeanPostProcessor(ChaosMonkeyRequestScope chaosMonkeyRequestScope) { + return new ChaosMonkeyBeanPostProcessor(watcherProperties, chaosMonkeyRequestScope, publisher()); + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnAvailableEndpoint + public ChaosMonkeyRestEndpoint chaosMonkeyRestEndpoint(ChaosMonkeyRuntimeScope runtimeScope, ChaosMonkeyScheduler scheduler) { + return new ChaosMonkeyRestEndpoint(settings(), runtimeScope, scheduler); + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnAvailableEndpoint + public ChaosMonkeyJmxEndpoint chaosMonkeyJmxEndpoint() { + return new ChaosMonkeyJmxEndpoint(settings()); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyLoadTimeWeaving.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyLoadTimeWeaving.java index 1b625925..a673f6da 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyLoadTimeWeaving.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyLoadTimeWeaving.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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.spring.boot.chaos.monkey.configuration; import org.springframework.context.annotation.Conditional; @@ -13,8 +28,8 @@ @EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED) public class ChaosMonkeyLoadTimeWeaving extends LoadTimeWeavingConfiguration { - @Override - public LoadTimeWeaver loadTimeWeaver() { - return new ReflectiveLoadTimeWeaver(); - } + @Override + public LoadTimeWeaver loadTimeWeaver() { + return new ReflectiveLoadTimeWeaver(); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyProperties.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyProperties.java index 5553d43c..89e2afb2 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyProperties.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyProperties.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.configuration; import lombok.AccessLevel; @@ -28,19 +27,19 @@ @ConfigurationProperties(prefix = "chaos.monkey") public class ChaosMonkeyProperties { - private boolean enabled = false; + private boolean enabled = false; - @Nullable - @Setter(AccessLevel.NONE) - private Long lastEnabledToggleTimestamp = null; + @Nullable + @Setter(AccessLevel.NONE) + private Long lastEnabledToggleTimestamp = null; - private String togglePrefix = "chaos.monkey"; + private String togglePrefix = "chaos.monkey"; - @Nullable - public void setEnabled(boolean enabled) { - if (this.enabled != enabled) { - lastEnabledToggleTimestamp = System.currentTimeMillis(); - this.enabled = enabled; + @Nullable + public void setEnabled(boolean enabled) { + if (this.enabled != enabled) { + lastEnabledToggleTimestamp = System.currentTimeMillis(); + this.enabled = enabled; + } } - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyRestTemplateConfiguration.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyRestTemplateConfiguration.java index ac0a31bd..497e4841 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyRestTemplateConfiguration.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyRestTemplateConfiguration.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.configuration; import de.codecentric.spring.boot.chaos.monkey.component.ChaosMonkeyRequestScope; @@ -12,32 +27,24 @@ import org.springframework.web.client.RestTemplate; @Configuration -@ConditionalOnProperty( - prefix = "chaos.monkey.watcher", - value = "rest-template", - havingValue = "true") +@ConditionalOnProperty(prefix = "chaos.monkey.watcher", value = "rest-template", havingValue = "true") @ConditionalOnClass(value = RestTemplate.class) class ChaosMonkeyRestTemplateConfiguration { - @Bean - public ChaosMonkeyRestTemplatePostProcessor chaosMonkeyRestTemplatePostProcessor( - final ChaosMonkeyRestTemplateCustomizer restTemplateCustomizer) { - return new ChaosMonkeyRestTemplatePostProcessor(restTemplateCustomizer); - } + @Bean + public ChaosMonkeyRestTemplatePostProcessor chaosMonkeyRestTemplatePostProcessor(final ChaosMonkeyRestTemplateCustomizer restTemplateCustomizer) { + return new ChaosMonkeyRestTemplatePostProcessor(restTemplateCustomizer); + } - @Bean - public ChaosMonkeyRestTemplateCustomizer chaosMonkeyRestTemplateCustomizer( - final ChaosMonkeyRestTemplateWatcher chaosMonkeyRestTemplateWatcher) { - return new ChaosMonkeyRestTemplateCustomizer(chaosMonkeyRestTemplateWatcher); - } + @Bean + public ChaosMonkeyRestTemplateCustomizer chaosMonkeyRestTemplateCustomizer(final ChaosMonkeyRestTemplateWatcher chaosMonkeyRestTemplateWatcher) { + return new ChaosMonkeyRestTemplateCustomizer(chaosMonkeyRestTemplateWatcher); + } - @Bean - @DependsOn("chaosMonkeyRequestScope") - public ChaosMonkeyRestTemplateWatcher chaosMonkeyRestTemplateInterceptor( - final ChaosMonkeyRequestScope chaosMonkeyRequestScope, - final WatcherProperties watcherProperties, - final AssaultProperties assaultProperties) { - return new ChaosMonkeyRestTemplateWatcher( - chaosMonkeyRequestScope, watcherProperties, assaultProperties); - } + @Bean + @DependsOn("chaosMonkeyRequestScope") + public ChaosMonkeyRestTemplateWatcher chaosMonkeyRestTemplateInterceptor(final ChaosMonkeyRequestScope chaosMonkeyRequestScope, + final WatcherProperties watcherProperties, final AssaultProperties assaultProperties) { + return new ChaosMonkeyRestTemplateWatcher(chaosMonkeyRequestScope, watcherProperties, assaultProperties); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeySettings.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeySettings.java index 6ad73e3a..6c5f7960 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeySettings.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeySettings.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.configuration; import de.codecentric.spring.boot.chaos.monkey.endpoints.dto.ChaosMonkeySettingsDto; @@ -28,13 +27,16 @@ @Data public class ChaosMonkeySettings { - @NotNull private ChaosMonkeyProperties chaosMonkeyProperties; + @NotNull + private ChaosMonkeyProperties chaosMonkeyProperties; - @NotNull private AssaultProperties assaultProperties; + @NotNull + private AssaultProperties assaultProperties; - @NotNull private WatcherProperties watcherProperties; + @NotNull + private WatcherProperties watcherProperties; - public ChaosMonkeySettingsDto toDto() { - return new ChaosMonkeySettingsDto(chaosMonkeyProperties, assaultProperties, watcherProperties); - } + public ChaosMonkeySettingsDto toDto() { + return new ChaosMonkeySettingsDto(chaosMonkeyProperties, assaultProperties, watcherProperties); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyWebClientConfiguration.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyWebClientConfiguration.java index 0a748ea7..0ba98adf 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyWebClientConfiguration.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyWebClientConfiguration.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.configuration; import de.codecentric.spring.boot.chaos.monkey.component.ChaosMonkeyRequestScope; @@ -16,25 +31,20 @@ @ConditionalOnClass(value = WebClient.class) class ChaosMonkeyWebClientConfiguration { - @Bean - public ChaosMonkeyWebClientPostProcessor chaosMonkeyWebClientPostProcessor( - final ChaosMonkeyWebClientWatcher chaosMonkeyWebClientWatcher) { - return new ChaosMonkeyWebClientPostProcessor(chaosMonkeyWebClientWatcher); - } + @Bean + public ChaosMonkeyWebClientPostProcessor chaosMonkeyWebClientPostProcessor(final ChaosMonkeyWebClientWatcher chaosMonkeyWebClientWatcher) { + return new ChaosMonkeyWebClientPostProcessor(chaosMonkeyWebClientWatcher); + } - @Bean - public ChaosMonkeyWebClientCustomizer chaosMonkeyWebClientCustomizer( - final ChaosMonkeyWebClientWatcher chaosMonkeyWebClientWatcher) { - return new ChaosMonkeyWebClientCustomizer(chaosMonkeyWebClientWatcher); - } + @Bean + public ChaosMonkeyWebClientCustomizer chaosMonkeyWebClientCustomizer(final ChaosMonkeyWebClientWatcher chaosMonkeyWebClientWatcher) { + return new ChaosMonkeyWebClientCustomizer(chaosMonkeyWebClientWatcher); + } - @Bean - @DependsOn("chaosMonkeyRequestScope") - public ChaosMonkeyWebClientWatcher chaosMonkeyWebClientWatcher( - final ChaosMonkeyRequestScope chaosMonkeyRequestScope, - final WatcherProperties watcherProperties, - final AssaultProperties assaultProperties) { - return new ChaosMonkeyWebClientWatcher( - chaosMonkeyRequestScope, watcherProperties, assaultProperties); - } + @Bean + @DependsOn("chaosMonkeyRequestScope") + public ChaosMonkeyWebClientWatcher chaosMonkeyWebClientWatcher(final ChaosMonkeyRequestScope chaosMonkeyRequestScope, + final WatcherProperties watcherProperties, final AssaultProperties assaultProperties) { + return new ChaosMonkeyWebClientWatcher(chaosMonkeyRequestScope, watcherProperties, assaultProperties); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/UnleashChaosConfiguration.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/UnleashChaosConfiguration.java index 1db0e026..aa9ccec8 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/UnleashChaosConfiguration.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/UnleashChaosConfiguration.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.configuration; import de.codecentric.spring.boot.chaos.monkey.configuration.toggles.ChaosToggles; @@ -15,10 +30,10 @@ @ConditionalOnProperty(value = "chaos.monkey.toggle.unleash.enabled") public class UnleashChaosConfiguration { - @Bean - @ConditionalOnMissingBean - @ConditionalOnBean(Unleash.class) - public ChaosToggles unleashChaosToggles(Unleash unleash) { - return new UnleashChaosToggles(unleash); - } + @Bean + @ConditionalOnMissingBean + @ConditionalOnBean(Unleash.class) + public ChaosToggles unleashChaosToggles(Unleash unleash) { + return new UnleashChaosToggles(unleash); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/WatcherProperties.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/WatcherProperties.java index 86f7eef4..1a8e76e4 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/WatcherProperties.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/WatcherProperties.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.configuration; import java.util.Collections; @@ -28,21 +27,21 @@ @ConfigurationProperties(prefix = "chaos.monkey.watcher") public class WatcherProperties { - private boolean controller = false; + private boolean controller = false; - private boolean restController = false; + private boolean restController = false; - private boolean service = false; + private boolean service = false; - private boolean repository = false; + private boolean repository = false; - private boolean component = false; + private boolean component = false; - private boolean restTemplate = false; + private boolean restTemplate = false; - private boolean webClient = false; + private boolean webClient = false; - private boolean actuatorHealth = false; + private boolean actuatorHealth = false; - private List beans = Collections.emptyList(); + private List beans = Collections.emptyList(); } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/ChaosToggleNameMapper.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/ChaosToggleNameMapper.java index 92703b7f..cab9cab8 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/ChaosToggleNameMapper.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/ChaosToggleNameMapper.java @@ -1,19 +1,38 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.configuration.toggles; import de.codecentric.spring.boot.chaos.monkey.component.ChaosTarget; /** - * A way to map individual ChaosTargets (controllers, repositories, etc) and the corresponding - * method. Implementations can make the name to toggle mapping as coarse or as detailed as desired. + * A way to map individual ChaosTargets (controllers, repositories, etc) and the + * corresponding method. Implementations can make the name to toggle mapping as + * coarse or as detailed as desired. * * @author Clint Checketts */ public interface ChaosToggleNameMapper { - /** - * @param type ChaosType (controller, repository, etc) - * @param name Name of item being assaulted (a method class and method name for example) - * @return the toggle name to be switched - */ - String mapName(ChaosTarget type, String name); + /** + * @param type + * ChaosType (controller, repository, etc) + * @param name + * Name of item being assaulted (a method class and method name for + * example) + * @return the toggle name to be switched + */ + String mapName(ChaosTarget type, String name); } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/ChaosToggles.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/ChaosToggles.java index 2f03f1e4..caf53518 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/ChaosToggles.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/ChaosToggles.java @@ -1,5 +1,20 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.configuration.toggles; public interface ChaosToggles { - boolean isEnabled(String toggleName); + boolean isEnabled(String toggleName); } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/DefaultChaosToggleNameMapper.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/DefaultChaosToggleNameMapper.java index 485eefc3..ee5ae305 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/DefaultChaosToggleNameMapper.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/DefaultChaosToggleNameMapper.java @@ -1,20 +1,35 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.configuration.toggles; import de.codecentric.spring.boot.chaos.monkey.component.ChaosTarget; public class DefaultChaosToggleNameMapper implements ChaosToggleNameMapper { - protected final String togglePrefix; + protected final String togglePrefix; - public DefaultChaosToggleNameMapper(String togglePrefix) { - this.togglePrefix = togglePrefix; - } - - @Override - public String mapName(ChaosTarget type, String name) { - if (type == null) { - return togglePrefix + ".unknown"; + public DefaultChaosToggleNameMapper(String togglePrefix) { + this.togglePrefix = togglePrefix; } - return togglePrefix + "." + type.getName(); - } + @Override + public String mapName(ChaosTarget type, String name) { + if (type == null) { + return togglePrefix + ".unknown"; + } + + return togglePrefix + "." + type.getName(); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/DefaultChaosToggles.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/DefaultChaosToggles.java index d07b848a..7c036a0a 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/DefaultChaosToggles.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/DefaultChaosToggles.java @@ -1,8 +1,23 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.configuration.toggles; public class DefaultChaosToggles implements ChaosToggles { - @Override - public boolean isEnabled(String toggleName) { - return true; - } + @Override + public boolean isEnabled(String toggleName) { + return true; + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/UnleashChaosToggles.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/UnleashChaosToggles.java index 4c0142df..e6e340c2 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/UnleashChaosToggles.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/UnleashChaosToggles.java @@ -1,16 +1,31 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.configuration.toggles; import io.getunleash.Unleash; public class UnleashChaosToggles implements ChaosToggles { - private final Unleash unleash; + private final Unleash unleash; - public UnleashChaosToggles(Unleash unleash) { - this.unleash = unleash; - } + public UnleashChaosToggles(Unleash unleash) { + this.unleash = unleash; + } - @Override - public boolean isEnabled(String toggleName) { - return unleash.isEnabled(toggleName); - } + @Override + public boolean isEnabled(String toggleName) { + return unleash.isEnabled(toggleName); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/BaseChaosMonkeyEndpoint.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/BaseChaosMonkeyEndpoint.java index 36141ac0..981d61a9 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/BaseChaosMonkeyEndpoint.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/BaseChaosMonkeyEndpoint.java @@ -1,3 +1,18 @@ +/* + * Copyright 2022 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 + * + * https://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.spring.boot.chaos.monkey.endpoints; import de.codecentric.spring.boot.chaos.monkey.configuration.ChaosMonkeyProperties; @@ -9,54 +24,46 @@ public class BaseChaosMonkeyEndpoint { - protected final ChaosMonkeySettings chaosMonkeySettings; - - public BaseChaosMonkeyEndpoint(ChaosMonkeySettings chaosMonkeySettings) { - this.chaosMonkeySettings = chaosMonkeySettings; - } - - public AssaultPropertiesUpdate getAssaultProperties() { - return this.chaosMonkeySettings.getAssaultProperties().toDto(); - } - - public ChaosMonkeyStatusResponseDto enableChaosMonkey() { - return setChaosMonkeyEnabled(true); - } - - public ChaosMonkeyStatusResponseDto disableChaosMonkey() { - return setChaosMonkeyEnabled(false); - } - - private ChaosMonkeyStatusResponseDto setChaosMonkeyEnabled(boolean enabled) { - ChaosMonkeyProperties chaosMonkeyProperties = - this.chaosMonkeySettings.getChaosMonkeyProperties(); - Long lastTimestamp = chaosMonkeyProperties.getLastEnabledToggleTimestamp(); - boolean wasEnabled = chaosMonkeyProperties.isEnabled(); - - chaosMonkeyProperties.setEnabled(enabled); - - Duration enabledFor = - wasEnabled && lastTimestamp != null - ? Duration.ofMillis(System.currentTimeMillis() - lastTimestamp) - : null; - Long timestamp = chaosMonkeyProperties.getLastEnabledToggleTimestamp(); - - return new ChaosMonkeyStatusResponseDto(enabled, timestamp, enabledFor); - } - - public ChaosMonkeyStatusResponseDto getStatus() { - ChaosMonkeyProperties chaosMonkeyProperties = - this.chaosMonkeySettings.getChaosMonkeyProperties(); - Long lastEnabledToggleTime = chaosMonkeyProperties.getLastEnabledToggleTimestamp(); - boolean enabled = chaosMonkeyProperties.isEnabled(); - Duration enabledFor = - enabled && lastEnabledToggleTime != null - ? Duration.ofMillis(System.currentTimeMillis() - lastEnabledToggleTime) - : null; - return new ChaosMonkeyStatusResponseDto(enabled, lastEnabledToggleTime, enabledFor); - } - - public WatcherProperties getWatcherProperties() { - return this.chaosMonkeySettings.getWatcherProperties(); - } + protected final ChaosMonkeySettings chaosMonkeySettings; + + public BaseChaosMonkeyEndpoint(ChaosMonkeySettings chaosMonkeySettings) { + this.chaosMonkeySettings = chaosMonkeySettings; + } + + public AssaultPropertiesUpdate getAssaultProperties() { + return this.chaosMonkeySettings.getAssaultProperties().toDto(); + } + + public ChaosMonkeyStatusResponseDto enableChaosMonkey() { + return setChaosMonkeyEnabled(true); + } + + public ChaosMonkeyStatusResponseDto disableChaosMonkey() { + return setChaosMonkeyEnabled(false); + } + + private ChaosMonkeyStatusResponseDto setChaosMonkeyEnabled(boolean enabled) { + ChaosMonkeyProperties chaosMonkeyProperties = this.chaosMonkeySettings.getChaosMonkeyProperties(); + Long lastTimestamp = chaosMonkeyProperties.getLastEnabledToggleTimestamp(); + boolean wasEnabled = chaosMonkeyProperties.isEnabled(); + + chaosMonkeyProperties.setEnabled(enabled); + + Duration enabledFor = wasEnabled && lastTimestamp != null ? Duration.ofMillis(System.currentTimeMillis() - lastTimestamp) : null; + Long timestamp = chaosMonkeyProperties.getLastEnabledToggleTimestamp(); + + return new ChaosMonkeyStatusResponseDto(enabled, timestamp, enabledFor); + } + + public ChaosMonkeyStatusResponseDto getStatus() { + ChaosMonkeyProperties chaosMonkeyProperties = this.chaosMonkeySettings.getChaosMonkeyProperties(); + Long lastEnabledToggleTime = chaosMonkeyProperties.getLastEnabledToggleTimestamp(); + boolean enabled = chaosMonkeyProperties.isEnabled(); + Duration enabledFor = enabled && lastEnabledToggleTime != null ? Duration.ofMillis(System.currentTimeMillis() - lastEnabledToggleTime) : null; + return new ChaosMonkeyStatusResponseDto(enabled, lastEnabledToggleTime, enabledFor); + } + + public WatcherProperties getWatcherProperties() { + return this.chaosMonkeySettings.getWatcherProperties(); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyJmxEndpoint.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyJmxEndpoint.java index 87c77251..b25b0d23 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyJmxEndpoint.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyJmxEndpoint.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.endpoints; import de.codecentric.spring.boot.chaos.monkey.configuration.ChaosMonkeySettings; @@ -28,74 +27,66 @@ @JmxEndpoint(enableByDefault = false, id = "chaosmonkeyjmx") public class ChaosMonkeyJmxEndpoint extends BaseChaosMonkeyEndpoint { - public ChaosMonkeyJmxEndpoint(ChaosMonkeySettings chaosMonkeySettings) { - super(chaosMonkeySettings); - } + public ChaosMonkeyJmxEndpoint(ChaosMonkeySettings chaosMonkeySettings) { + super(chaosMonkeySettings); + } - @ReadOperation - @Override - public AssaultPropertiesUpdate getAssaultProperties() { - return super.getAssaultProperties(); - } + @ReadOperation + @Override + public AssaultPropertiesUpdate getAssaultProperties() { + return super.getAssaultProperties(); + } - @WriteOperation - public String toggleLatencyAssault() { - this.chaosMonkeySettings - .getAssaultProperties() - .setLatencyActive(!this.getAssaultProperties().getLatencyActive()); - return String.valueOf(this.getAssaultProperties().getLatencyActive()); - } + @WriteOperation + public String toggleLatencyAssault() { + this.chaosMonkeySettings.getAssaultProperties().setLatencyActive(!this.getAssaultProperties().getLatencyActive()); + return String.valueOf(this.getAssaultProperties().getLatencyActive()); + } - @WriteOperation - public String toggleExceptionAssault() { - this.chaosMonkeySettings - .getAssaultProperties() - .setExceptionsActive(!this.getAssaultProperties().getExceptionsActive()); - return String.valueOf(this.getAssaultProperties().getExceptionsActive()); - } + @WriteOperation + public String toggleExceptionAssault() { + this.chaosMonkeySettings.getAssaultProperties().setExceptionsActive(!this.getAssaultProperties().getExceptionsActive()); + return String.valueOf(this.getAssaultProperties().getExceptionsActive()); + } - @WriteOperation - public String toggleKillApplicationAssault() { - this.chaosMonkeySettings - .getAssaultProperties() - .setKillApplicationActive(!this.getAssaultProperties().getKillApplicationActive()); - return String.valueOf(this.getAssaultProperties().getKillApplicationActive()); - } + @WriteOperation + public String toggleKillApplicationAssault() { + this.chaosMonkeySettings.getAssaultProperties().setKillApplicationActive(!this.getAssaultProperties().getKillApplicationActive()); + return String.valueOf(this.getAssaultProperties().getKillApplicationActive()); + } - @WriteOperation - public String toggleCpuAssault() { - this.chaosMonkeySettings - .getAssaultProperties() - .setCpuActive(!this.getAssaultProperties().getCpuActive()); - return String.valueOf(this.getAssaultProperties().getCpuActive()); - } + @WriteOperation + public String toggleCpuAssault() { + this.chaosMonkeySettings.getAssaultProperties().setCpuActive(!this.getAssaultProperties().getCpuActive()); + return String.valueOf(this.getAssaultProperties().getCpuActive()); + } - @ReadOperation() - public String isChaosMonkeyActive() { - return String.valueOf(this.chaosMonkeySettings.getChaosMonkeyProperties().isEnabled()); - } + @ReadOperation() + public String isChaosMonkeyActive() { + return String.valueOf(this.chaosMonkeySettings.getChaosMonkeyProperties().isEnabled()); + } - @WriteOperation - @Override - public ChaosMonkeyStatusResponseDto enableChaosMonkey() { - return super.enableChaosMonkey(); - } + @WriteOperation + @Override + public ChaosMonkeyStatusResponseDto enableChaosMonkey() { + return super.enableChaosMonkey(); + } - @WriteOperation - @Override - public ChaosMonkeyStatusResponseDto disableChaosMonkey() { - return super.disableChaosMonkey(); - } + @WriteOperation + @Override + public ChaosMonkeyStatusResponseDto disableChaosMonkey() { + return super.disableChaosMonkey(); + } - @ReadOperation - @Override - public ChaosMonkeyStatusResponseDto getStatus() { - return super.getStatus(); - } + @ReadOperation + @Override + public ChaosMonkeyStatusResponseDto getStatus() { + return super.getStatus(); + } - @ReadOperation - @Override - public WatcherProperties getWatcherProperties() { - return super.getWatcherProperties(); - } + @ReadOperation + @Override + public WatcherProperties getWatcherProperties() { + return super.getWatcherProperties(); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRestEndpoint.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRestEndpoint.java index d5e0deb4..4ce00135 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRestEndpoint.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRestEndpoint.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.endpoints; import de.codecentric.spring.boot.chaos.monkey.component.ChaosMonkeyRuntimeScope; @@ -34,77 +33,72 @@ @RestControllerEndpoint(enableByDefault = false, id = "chaosmonkey") public class ChaosMonkeyRestEndpoint extends BaseChaosMonkeyEndpoint { - private final ChaosMonkeyRuntimeScope runtimeScope; - - private final ChaosMonkeyScheduler scheduler; - - public ChaosMonkeyRestEndpoint( - ChaosMonkeySettings chaosMonkeySettings, - ChaosMonkeyRuntimeScope runtimeScope, - ChaosMonkeyScheduler scheduler) { - super(chaosMonkeySettings); - this.runtimeScope = runtimeScope; - this.scheduler = scheduler; - } - - @PostMapping("/assaults") - @ResponseBody - public String updateAssaultProperties( - @RequestBody @Validated AssaultPropertiesUpdate assaultProperties) { - assaultProperties.applyTo(chaosMonkeySettings.getAssaultProperties()); - scheduler.reloadConfig(); - return "Assault config has changed"; - } - - @PostMapping("/assaults/runtime/attack") - @ResponseBody - public String attack() { - runtimeScope.callChaosMonkey(); - return "Started runtime assaults"; - } - - @GetMapping("/assaults") - @Override - public AssaultPropertiesUpdate getAssaultProperties() { - return super.getAssaultProperties(); - } - - @PostMapping("/enable") - @Override - public ChaosMonkeyStatusResponseDto enableChaosMonkey() { - return super.enableChaosMonkey(); - } - - @PostMapping("/disable") - @Override - public ChaosMonkeyStatusResponseDto disableChaosMonkey() { - return super.disableChaosMonkey(); - } - - @GetMapping - public ChaosMonkeySettingsDto status() { - return this.chaosMonkeySettings.toDto(); - } - - @GetMapping("/status") - @Override - public ChaosMonkeyStatusResponseDto getStatus() { - return super.getStatus(); - } - - @PostMapping("/watchers") - @ResponseBody - public String updateWatcherProperties( - @RequestBody @Validated WatcherPropertiesUpdate watcherProperties) { - watcherProperties.applyTo(chaosMonkeySettings.getWatcherProperties()); - scheduler.reloadConfig(); - - return "Watcher config has changed"; - } - - @GetMapping("/watchers") - @Override - public WatcherProperties getWatcherProperties() { - return super.getWatcherProperties(); - } + private final ChaosMonkeyRuntimeScope runtimeScope; + + private final ChaosMonkeyScheduler scheduler; + + public ChaosMonkeyRestEndpoint(ChaosMonkeySettings chaosMonkeySettings, ChaosMonkeyRuntimeScope runtimeScope, ChaosMonkeyScheduler scheduler) { + super(chaosMonkeySettings); + this.runtimeScope = runtimeScope; + this.scheduler = scheduler; + } + + @PostMapping("/assaults") + @ResponseBody + public String updateAssaultProperties(@RequestBody @Validated AssaultPropertiesUpdate assaultProperties) { + assaultProperties.applyTo(chaosMonkeySettings.getAssaultProperties()); + scheduler.reloadConfig(); + return "Assault config has changed"; + } + + @PostMapping("/assaults/runtime/attack") + @ResponseBody + public String attack() { + runtimeScope.callChaosMonkey(); + return "Started runtime assaults"; + } + + @GetMapping("/assaults") + @Override + public AssaultPropertiesUpdate getAssaultProperties() { + return super.getAssaultProperties(); + } + + @PostMapping("/enable") + @Override + public ChaosMonkeyStatusResponseDto enableChaosMonkey() { + return super.enableChaosMonkey(); + } + + @PostMapping("/disable") + @Override + public ChaosMonkeyStatusResponseDto disableChaosMonkey() { + return super.disableChaosMonkey(); + } + + @GetMapping + public ChaosMonkeySettingsDto status() { + return this.chaosMonkeySettings.toDto(); + } + + @GetMapping("/status") + @Override + public ChaosMonkeyStatusResponseDto getStatus() { + return super.getStatus(); + } + + @PostMapping("/watchers") + @ResponseBody + public String updateWatcherProperties(@RequestBody @Validated WatcherPropertiesUpdate watcherProperties) { + watcherProperties.applyTo(chaosMonkeySettings.getWatcherProperties()); + scheduler.reloadConfig(); + + return "Watcher config has changed"; + } + + @GetMapping("/watchers") + @Override + public WatcherProperties getWatcherProperties() { + return super.getWatcherProperties(); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/AssaultPropertiesUpdate.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/AssaultPropertiesUpdate.java index 76326b9b..d4fd3dfd 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/AssaultPropertiesUpdate.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/AssaultPropertiesUpdate.java @@ -1,3 +1,18 @@ +/* + * Copyright 2019-2022 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 + * + * https://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.spring.boot.chaos.monkey.endpoints.dto; import com.fasterxml.jackson.annotation.JsonInclude; @@ -17,8 +32,9 @@ import org.springframework.validation.annotation.Validated; /** - * Is used to update properties. Partial updates are allowed: i. e. {@code {"level": 2}} is fine. - * This is also why we're using ObjectTypes (and not the corresponding primitives). + * Is used to update properties. Partial updates are allowed: i. e. + * {@code {"level": 2}} is fine. This is also why we're using ObjectTypes (and + * not the corresponding primitives). */ @Data @NoArgsConstructor @@ -26,111 +42,125 @@ @JsonInclude(JsonInclude.Include.NON_NULL) @AssaultPropertiesUpdateLatencyRangeConstraint public class AssaultPropertiesUpdate { - @Nullable - @Min(value = 1) - @Max(value = 10000) - private Integer level; - - @Nullable private Boolean deterministic; - - @Nullable - @Min(value = 1) - @Max(value = Integer.MAX_VALUE) - private Integer latencyRangeStart; - - @Nullable - @Min(value = 1) - @Max(value = Integer.MAX_VALUE) - private Integer latencyRangeEnd; - - @Nullable private Boolean latencyActive; - - @Nullable private Boolean exceptionsActive; - - @AssaultExceptionConstraint private AssaultException exception; - - @Nullable private Boolean killApplicationActive; - - @Nullable private String killApplicationCronExpression; - - @Nullable private volatile Boolean memoryActive; - - @Nullable - @Min(value = 1500) - @Max(value = Integer.MAX_VALUE) - private Integer memoryMillisecondsHoldFilledMemory; - - @Nullable - @Min(value = 100) - @Max(value = 30000) - private Integer memoryMillisecondsWaitNextIncrease; - - @Nullable - @DecimalMax("1.0") - @DecimalMin("0.0") - private Double memoryFillIncrementFraction; - - @Nullable - @DecimalMax("0.95") - @DecimalMin("0.05") - private Double memoryFillTargetFraction; - - @Nullable private String memoryCronExpression; - - @Nullable private Boolean cpuActive; - - @Nullable - @Min(value = 1500) - @Max(value = Integer.MAX_VALUE) - private Integer cpuMillisecondsHoldLoad; - - @Nullable - @DecimalMax("1.0") - @DecimalMin("0.1") - private Double cpuLoadTargetFraction; - - @Nullable private String cpuCronExpression; - - /** - * @deprecated please use {@link #killApplicationCronExpression}, {@link #memoryCronExpression} or - * {@link #cpuCronExpression} instead - */ - @Deprecated @Nullable private String runtimeAssaultCronExpression; - - @Nullable private List watchedCustomServices; + @Nullable + @Min(value = 1) + @Max(value = 10000) + private Integer level; + + @Nullable + private Boolean deterministic; + + @Nullable + @Min(value = 1) + @Max(value = Integer.MAX_VALUE) + private Integer latencyRangeStart; + + @Nullable + @Min(value = 1) + @Max(value = Integer.MAX_VALUE) + private Integer latencyRangeEnd; + + @Nullable + private Boolean latencyActive; + + @Nullable + private Boolean exceptionsActive; + + @AssaultExceptionConstraint + private AssaultException exception; + + @Nullable + private Boolean killApplicationActive; + + @Nullable + private String killApplicationCronExpression; + + @Nullable + private volatile Boolean memoryActive; + + @Nullable + @Min(value = 1500) + @Max(value = Integer.MAX_VALUE) + private Integer memoryMillisecondsHoldFilledMemory; + + @Nullable + @Min(value = 100) + @Max(value = 30000) + private Integer memoryMillisecondsWaitNextIncrease; + + @Nullable + @DecimalMax("1.0") + @DecimalMin("0.0") + private Double memoryFillIncrementFraction; + + @Nullable + @DecimalMax("0.95") + @DecimalMin("0.05") + private Double memoryFillTargetFraction; + + @Nullable + private String memoryCronExpression; + + @Nullable + private Boolean cpuActive; + + @Nullable + @Min(value = 1500) + @Max(value = Integer.MAX_VALUE) + private Integer cpuMillisecondsHoldLoad; + + @Nullable + @DecimalMax("1.0") + @DecimalMin("0.1") + private Double cpuLoadTargetFraction; + + @Nullable + private String cpuCronExpression; + + /** + * @deprecated please use {@link #killApplicationCronExpression}, + * {@link #memoryCronExpression} or {@link #cpuCronExpression} + * instead + */ + @Deprecated + @Nullable + private String runtimeAssaultCronExpression; + + @Nullable + private List watchedCustomServices; + + private void applyTo(T value, Consumer setter) { + if (value != null) { + setter.accept(value); + } + } - private void applyTo(T value, Consumer setter) { - if (value != null) { - setter.accept(value); + public void applyTo(AssaultProperties t) { + applyTo(level, t::setLevel); + applyTo(deterministic, t::setDeterministic); + applyTo(latencyActive, t::setLatencyActive); + applyTo(latencyRangeStart, t::setLatencyRangeStart); + applyTo(latencyRangeEnd, t::setLatencyRangeEnd); + + applyTo(exceptionsActive, t::setExceptionsActive); + applyTo(exception, t::setException); + + applyTo(killApplicationActive, t::setKillApplicationActive); + applyTo(killApplicationCronExpression, t::setKillApplicationCronExpression); + + applyTo(memoryActive, t::setMemoryActive); + applyTo(memoryMillisecondsHoldFilledMemory, t::setMemoryMillisecondsHoldFilledMemory); + applyTo(memoryMillisecondsWaitNextIncrease, t::setMemoryMillisecondsWaitNextIncrease); + applyTo(memoryFillIncrementFraction, t::setMemoryFillIncrementFraction); + applyTo(memoryFillTargetFraction, t::setMemoryFillTargetFraction); + applyTo(memoryCronExpression, t::setMemoryCronExpression); + + applyTo(cpuActive, t::setCpuActive); + applyTo(cpuMillisecondsHoldLoad, t::setCpuMillisecondsHoldLoad); + applyTo(cpuLoadTargetFraction, t::setCpuLoadTargetFraction); + applyTo(cpuCronExpression, t::setCpuCronExpression); + + applyTo(runtimeAssaultCronExpression, t::setRuntimeAssaultCronExpression); + applyTo(watchedCustomServices, t::setWatchedCustomServices); } - } - - public void applyTo(AssaultProperties t) { - applyTo(level, t::setLevel); - applyTo(deterministic, t::setDeterministic); - applyTo(latencyActive, t::setLatencyActive); - applyTo(latencyRangeStart, t::setLatencyRangeStart); - applyTo(latencyRangeEnd, t::setLatencyRangeEnd); - - applyTo(exceptionsActive, t::setExceptionsActive); - applyTo(exception, t::setException); - - applyTo(killApplicationActive, t::setKillApplicationActive); - applyTo(killApplicationCronExpression, t::setKillApplicationCronExpression); - - applyTo(memoryActive, t::setMemoryActive); - applyTo(memoryMillisecondsHoldFilledMemory, t::setMemoryMillisecondsHoldFilledMemory); - applyTo(memoryMillisecondsWaitNextIncrease, t::setMemoryMillisecondsWaitNextIncrease); - applyTo(memoryFillIncrementFraction, t::setMemoryFillIncrementFraction); - applyTo(memoryFillTargetFraction, t::setMemoryFillTargetFraction); - applyTo(memoryCronExpression, t::setMemoryCronExpression); - - applyTo(cpuActive, t::setCpuActive); - applyTo(cpuMillisecondsHoldLoad, t::setCpuMillisecondsHoldLoad); - applyTo(cpuLoadTargetFraction, t::setCpuLoadTargetFraction); - applyTo(cpuCronExpression, t::setCpuCronExpression); - - applyTo(runtimeAssaultCronExpression, t::setRuntimeAssaultCronExpression); - applyTo(watchedCustomServices, t::setWatchedCustomServices); - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/ChaosMonkeySettingsDto.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/ChaosMonkeySettingsDto.java index f1a6339a..790927df 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/ChaosMonkeySettingsDto.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/ChaosMonkeySettingsDto.java @@ -1,20 +1,18 @@ /* - * Copyright 2020 the original author or authors. + * Copyright 2018-2022 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 + * https://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.spring.boot.chaos.monkey.endpoints.dto; import de.codecentric.spring.boot.chaos.monkey.configuration.AssaultProperties; @@ -26,16 +24,14 @@ @Getter public class ChaosMonkeySettingsDto { - ChaosMonkeyProperties chaosMonkeyProperties; - AssaultPropertiesUpdate assaultProperties; - WatcherProperties watcherProperties; + ChaosMonkeyProperties chaosMonkeyProperties; + AssaultPropertiesUpdate assaultProperties; + WatcherProperties watcherProperties; - public ChaosMonkeySettingsDto( - @NotNull ChaosMonkeyProperties chaosMonkeyProperties, - @NotNull AssaultProperties assaultProperties, - @NotNull WatcherProperties watcherProperties) { - this.chaosMonkeyProperties = chaosMonkeyProperties; - this.assaultProperties = assaultProperties.toDto(); - this.watcherProperties = watcherProperties; - } + public ChaosMonkeySettingsDto(@NotNull ChaosMonkeyProperties chaosMonkeyProperties, @NotNull AssaultProperties assaultProperties, + @NotNull WatcherProperties watcherProperties) { + this.chaosMonkeyProperties = chaosMonkeyProperties; + this.assaultProperties = assaultProperties.toDto(); + this.watcherProperties = watcherProperties; + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/ChaosMonkeyStatusResponseDto.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/ChaosMonkeyStatusResponseDto.java index e05a79a0..6ebfb79d 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/ChaosMonkeyStatusResponseDto.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/ChaosMonkeyStatusResponseDto.java @@ -1,3 +1,18 @@ +/* + * Copyright 2022 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 + * + * https://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.spring.boot.chaos.monkey.endpoints.dto; import com.fasterxml.jackson.annotation.JsonInclude; @@ -16,46 +31,41 @@ @JsonInclude(Include.NON_NULL) public class ChaosMonkeyStatusResponseDto { - private boolean isEnabled; - private OffsetDateTime enabledAt; - private OffsetDateTime disabledAt; - private Value enabledFor; - - public ChaosMonkeyStatusResponseDto( - boolean isEnabled, @Nullable Long lastStatusToggleTimestamp, @Nullable Duration enabledFor) { - this.isEnabled = isEnabled; - OffsetDateTime lastStatusToggleTime = - lastStatusToggleTimestamp != null - ? OffsetDateTime.ofInstant( - Instant.ofEpochMilli(lastStatusToggleTimestamp), ZoneId.systemDefault()) - : null; - this.enabledAt = isEnabled ? lastStatusToggleTime : null; - this.disabledAt = !isEnabled ? lastStatusToggleTime : null; - this.enabledFor = - enabledFor != null ? new Value<>(enabledFor, formatDuration(enabledFor)) : null; - } - - private String formatDuration(Duration duration) { - long inSeconds = duration.getSeconds(); - long secondsPart = inSeconds % 60; - long minutesPart = (inSeconds % 3600) / 60; - - if (duration.toHours() > 0) { - return String.format( - "%d hours %02d minutes %02d seconds", duration.toHours(), minutesPart, secondsPart); - } else if (duration.toMinutes() > 0) { - return String.format("%d minutes %02d seconds", duration.toMinutes(), secondsPart); - } else { - return String.format("%d seconds", inSeconds); + private boolean isEnabled; + private OffsetDateTime enabledAt; + private OffsetDateTime disabledAt; + private Value enabledFor; + + public ChaosMonkeyStatusResponseDto(boolean isEnabled, @Nullable Long lastStatusToggleTimestamp, @Nullable Duration enabledFor) { + this.isEnabled = isEnabled; + OffsetDateTime lastStatusToggleTime = lastStatusToggleTimestamp != null + ? OffsetDateTime.ofInstant(Instant.ofEpochMilli(lastStatusToggleTimestamp), ZoneId.systemDefault()) + : null; + this.enabledAt = isEnabled ? lastStatusToggleTime : null; + this.disabledAt = !isEnabled ? lastStatusToggleTime : null; + this.enabledFor = enabledFor != null ? new Value<>(enabledFor, formatDuration(enabledFor)) : null; } - } - @Data - @NoArgsConstructor - @AllArgsConstructor - public static class Value { + private String formatDuration(Duration duration) { + long inSeconds = duration.getSeconds(); + long secondsPart = inSeconds % 60; + long minutesPart = (inSeconds % 3600) / 60; + + if (duration.toHours() > 0) { + return String.format("%d hours %02d minutes %02d seconds", duration.toHours(), minutesPart, secondsPart); + } else if (duration.toMinutes() > 0) { + return String.format("%d minutes %02d seconds", duration.toMinutes(), secondsPart); + } else { + return String.format("%d seconds", inSeconds); + } + } - private T raw; - private String formatted; - } + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class Value { + + private T raw; + private String formatted; + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/WatcherPropertiesUpdate.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/WatcherPropertiesUpdate.java index 73b57e28..f5d13ce4 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/WatcherPropertiesUpdate.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/WatcherPropertiesUpdate.java @@ -1,3 +1,18 @@ +/* + * Copyright 2019-2022 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 + * + * https://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.spring.boot.chaos.monkey.endpoints.dto; import com.fasterxml.jackson.annotation.JsonInclude; @@ -13,39 +28,48 @@ @JsonInclude(JsonInclude.Include.NON_NULL) public class WatcherPropertiesUpdate { - @Nullable private Boolean controller; + @Nullable + private Boolean controller; - @Nullable private Boolean restController; + @Nullable + private Boolean restController; - @Nullable private Boolean service; + @Nullable + private Boolean service; - @Nullable private Boolean repository; + @Nullable + private Boolean repository; - @Nullable private Boolean component; + @Nullable + private Boolean component; - @Nullable private Boolean restTemplate; + @Nullable + private Boolean restTemplate; - @Nullable private Boolean webClient; + @Nullable + private Boolean webClient; - @Nullable private Boolean actuatorHealth; + @Nullable + private Boolean actuatorHealth; - @Nullable private List beans; + @Nullable + private List beans; - private void applyTo(T value, Consumer setter) { - if (value != null) { - setter.accept(value); + private void applyTo(T value, Consumer setter) { + if (value != null) { + setter.accept(value); + } + } + + public void applyTo(WatcherProperties t) { + applyTo(controller, t::setController); + applyTo(restController, t::setRestController); + applyTo(service, t::setService); + applyTo(repository, t::setRepository); + applyTo(component, t::setComponent); + applyTo(restTemplate, t::setRestTemplate); + applyTo(webClient, t::setWebClient); + applyTo(actuatorHealth, t::setActuatorHealth); + applyTo(beans, t::setBeans); } - } - - public void applyTo(WatcherProperties t) { - applyTo(controller, t::setController); - applyTo(restController, t::setRestController); - applyTo(service, t::setService); - applyTo(repository, t::setRepository); - applyTo(component, t::setComponent); - applyTo(restTemplate, t::setRestTemplate); - applyTo(webClient, t::setWebClient); - applyTo(actuatorHealth, t::setActuatorHealth); - applyTo(beans, t::setBeans); - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultExceptionConstraint.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultExceptionConstraint.java index bf4e497e..cf7a3de9 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultExceptionConstraint.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultExceptionConstraint.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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.spring.boot.chaos.monkey.endpoints.dto.validation; import java.lang.annotation.ElementType; @@ -12,9 +27,9 @@ @Retention(RetentionPolicy.RUNTIME) public @interface AssaultExceptionConstraint { - String message() default "Invalid Exception type and arguments"; + String message() default "Invalid Exception type and arguments"; - Class[] groups() default {}; + Class[] groups() default {}; - Class[] payload() default {}; + Class[] payload() default {}; } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultExceptionValidator.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultExceptionValidator.java index 6a224b4c..e0fe7466 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultExceptionValidator.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultExceptionValidator.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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.spring.boot.chaos.monkey.endpoints.dto.validation; import de.codecentric.spring.boot.chaos.monkey.configuration.AssaultException; @@ -6,25 +21,22 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class AssaultExceptionValidator - implements ConstraintValidator { +public class AssaultExceptionValidator implements ConstraintValidator { - private static final Logger Logger = LoggerFactory.getLogger(AssaultExceptionValidator.class); + private static final Logger Logger = LoggerFactory.getLogger(AssaultExceptionValidator.class); - @Override - public boolean isValid( - AssaultException exception, ConstraintValidatorContext constraintValidatorContext) { - if (exception == null) { - return true; - } + @Override + public boolean isValid(AssaultException exception, ConstraintValidatorContext constraintValidatorContext) { + if (exception == null) { + return true; + } - try { - exception.getCreator(); - return true; - } catch (ReflectiveOperationException e) { - Logger.warn( - "Invalid combination of type ({}), method and arguments provided", exception.getType()); + try { + exception.getCreator(); + return true; + } catch (ReflectiveOperationException e) { + Logger.warn("Invalid combination of type ({}), method and arguments provided", exception.getType()); + } + return false; } - return false; - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultPropertiesUpdateLatencyRangeConstraint.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultPropertiesUpdateLatencyRangeConstraint.java index 6cae3ad0..ca9dc2be 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultPropertiesUpdateLatencyRangeConstraint.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultPropertiesUpdateLatencyRangeConstraint.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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.spring.boot.chaos.monkey.endpoints.dto.validation; import java.lang.annotation.ElementType; @@ -12,10 +27,9 @@ @Retention(RetentionPolicy.RUNTIME) public @interface AssaultPropertiesUpdateLatencyRangeConstraint { - String message() default - "Invalid range parameters. Value of latencyRangeStart must not be greater than value of latencyRangeEnd!"; + String message() default "Invalid range parameters. Value of latencyRangeStart must not be greater than value of latencyRangeEnd!"; - Class[] groups() default {}; + Class[] groups() default {}; - Class[] payload() default {}; + Class[] payload() default {}; } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultPropertiesUpdateLatencyRangeValidator.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultPropertiesUpdateLatencyRangeValidator.java index 2045241f..acc2e4f9 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultPropertiesUpdateLatencyRangeValidator.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultPropertiesUpdateLatencyRangeValidator.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.endpoints.dto.validation; import de.codecentric.spring.boot.chaos.monkey.endpoints.dto.AssaultPropertiesUpdate; @@ -5,17 +20,15 @@ import javax.validation.ConstraintValidatorContext; public class AssaultPropertiesUpdateLatencyRangeValidator - implements ConstraintValidator< - AssaultPropertiesUpdateLatencyRangeConstraint, AssaultPropertiesUpdate> { + implements + ConstraintValidator { - @Override - public boolean isValid( - final AssaultPropertiesUpdate properties, - final ConstraintValidatorContext constraintValidatorContext) { - Integer start = properties.getLatencyRangeStart(); - Integer end = properties.getLatencyRangeEnd(); - boolean isEmptyRange = start == null && end == null; - boolean isCompleteRange = start != null && end != null; - return isEmptyRange || (isCompleteRange && start <= end); - } + @Override + public boolean isValid(final AssaultPropertiesUpdate properties, final ConstraintValidatorContext constraintValidatorContext) { + Integer start = properties.getLatencyRangeStart(); + Integer end = properties.getLatencyRangeEnd(); + boolean isEmptyRange = start == null && end == null; + boolean isCompleteRange = start != null && end != null; + return isEmptyRange || (isCompleteRange && start <= end); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/events/MetricEvent.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/events/MetricEvent.java index 10a7daf4..d8b3ace3 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/events/MetricEvent.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/events/MetricEvent.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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.spring.boot.chaos.monkey.events; import de.codecentric.spring.boot.chaos.monkey.component.MetricType; @@ -7,60 +22,60 @@ /** @author Benjamin Wilms */ public class MetricEvent extends ApplicationEvent { - private final MetricType metricType; + private final MetricType metricType; - private final double metricValue; + private final double metricValue; - private final String methodSignature; + private final String methodSignature; - private final String[] tags; + private final String[] tags; - /** - * Create a new Chaos Monkey for Spring Boot Metric ApplicationEvent. - * - * @param source the object on which the event initially occurred (never {@code null}) - * @param metricType MetricType - * @param methodSignature String - * @param tags String[] - */ - public MetricEvent(Object source, MetricType metricType, String methodSignature, String... tags) { - this(source, metricType, -1, methodSignature, tags); - } + /** + * Create a new Chaos Monkey for Spring Boot Metric ApplicationEvent. + * + * @param source + * the object on which the event initially occurred (never + * {@code null}) + * @param metricType + * MetricType + * @param methodSignature + * String + * @param tags + * String[] + */ + public MetricEvent(Object source, MetricType metricType, String methodSignature, String... tags) { + this(source, metricType, -1, methodSignature, tags); + } - public MetricEvent(Object source, MetricType metricType, String... tags) { - this(source, metricType, -1, null); - } + public MetricEvent(Object source, MetricType metricType, String... tags) { + this(source, metricType, -1, null); + } - public MetricEvent( - Object source, - MetricType metricType, - long metricValue, - String methodSignature, - String... tags) { - super(source); - this.metricType = metricType; - this.tags = tags; - this.methodSignature = methodSignature; - this.metricValue = metricValue; - } + public MetricEvent(Object source, MetricType metricType, long metricValue, String methodSignature, String... tags) { + super(source); + this.metricType = metricType; + this.tags = tags; + this.methodSignature = methodSignature; + this.metricValue = metricValue; + } - public MetricType getMetricType() { - return metricType; - } + public MetricType getMetricType() { + return metricType; + } - public String getMethodSignature() { - return methodSignature; - } + public String getMethodSignature() { + return methodSignature; + } - public String[] getTags() { - return tags; - } + public String[] getTags() { + return tags; + } - public double getMetricValue() { - return metricValue; - } + public double getMetricValue() { + return metricValue; + } - public AtomicInteger getGaugeValue() { - return new AtomicInteger((int) metricValue); - } + public AtomicInteger getGaugeValue() { + return new AtomicInteger((int) metricValue); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/ChaosMonkeyBaseAspect.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/ChaosMonkeyBaseAspect.java index 161e67c7..33a4c8ee 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/ChaosMonkeyBaseAspect.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/ChaosMonkeyBaseAspect.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.watcher.aspect; import org.aspectj.lang.annotation.Pointcut; @@ -22,24 +21,27 @@ /** @author Benjamin Wilms */ abstract class ChaosMonkeyBaseAspect { - @Pointcut("within(de.codecentric.spring.boot.chaos.monkey..*)") - public void classInChaosMonkeyPackage() {} + @Pointcut("within(de.codecentric.spring.boot.chaos.monkey..*)") + public void classInChaosMonkeyPackage() { + } - @Pointcut("!within(is(FinalType)) || within(com.sun.proxy.*)") - public void nonFinalOrJdkProxiedClassPointcut() {} + @Pointcut("!within(is(FinalType)) || within(com.sun.proxy.*)") + public void nonFinalOrJdkProxiedClassPointcut() { + } - @Pointcut("nonFinalOrJdkProxiedClassPointcut() && execution(* *.*(..))") - public void allPublicMethodPointcut() {} + @Pointcut("nonFinalOrJdkProxiedClassPointcut() && execution(* *.*(..))") + public void allPublicMethodPointcut() { + } - @Pointcut( - "execution(* postProcess*Initialization(..)) || (execution(* onApplicationEvent(..)) && !execution(* onApplicationEvent(org.springframework.web.context.support.RequestHandledEvent))) || execution(* org.springframework.beans.factory.FactoryBean+.*(..))") - public void springHooksPointcut() {} + @Pointcut("execution(* postProcess*Initialization(..)) || (execution(* onApplicationEvent(..)) && !execution(* onApplicationEvent(org.springframework.web.context.support.RequestHandledEvent))) || execution(* org.springframework.beans.factory.FactoryBean+.*(..))") + public void springHooksPointcut() { + } - String calculatePointcut(String target) { - return target.replaceAll("\\(\\)", "").replaceAll("\\)", "").replaceAll("\\(", "."); - } + String calculatePointcut(String target) { + return target.replaceAll("\\(\\)", "").replaceAll("\\)", "").replaceAll("\\(", "."); + } - String createSignature(MethodSignature signature) { - return signature.getDeclaringTypeName() + "." + signature.getMethod().getName(); - } + String createSignature(MethodSignature signature) { + return signature.getDeclaringTypeName() + "." + signature.getMethod().getName(); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/ChaosMonkeyBeanPostProcessor.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/ChaosMonkeyBeanPostProcessor.java index a66c6d09..813247e0 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/ChaosMonkeyBeanPostProcessor.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/ChaosMonkeyBeanPostProcessor.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.watcher.aspect; import de.codecentric.spring.boot.chaos.monkey.component.ChaosMonkeyRequestScope; @@ -24,69 +39,62 @@ @Slf4j public class ChaosMonkeyBeanPostProcessor extends AbstractAdvisingBeanPostProcessor { - private final WatcherProperties watcherProperties; - private final Map activeBeanNameCache = new WeakHashMap<>(); + private final WatcherProperties watcherProperties; + private final Map activeBeanNameCache = new WeakHashMap<>(); - public ChaosMonkeyBeanPostProcessor( - WatcherProperties watcherProperties, - ChaosMonkeyRequestScope requestScope, - MetricEventPublisher eventPublisher) { - this(watcherProperties, requestScope, eventPublisher, new ReflectiveAspectJAdvisorFactory()); - } + public ChaosMonkeyBeanPostProcessor(WatcherProperties watcherProperties, ChaosMonkeyRequestScope requestScope, + MetricEventPublisher eventPublisher) { + this(watcherProperties, requestScope, eventPublisher, new ReflectiveAspectJAdvisorFactory()); + } - public ChaosMonkeyBeanPostProcessor( - WatcherProperties watcherProperties, - ChaosMonkeyRequestScope requestScope, - MetricEventPublisher eventPublisher, - AspectJAdvisorFactory advisorFactory) { - this.watcherProperties = watcherProperties; - SpringBeanAspect aspect = new SpringBeanAspect(requestScope, eventPublisher); - this.advisor = convertAspectToAdvisor(advisorFactory, aspect, "springBeanAspect"); - } + public ChaosMonkeyBeanPostProcessor(WatcherProperties watcherProperties, ChaosMonkeyRequestScope requestScope, + MetricEventPublisher eventPublisher, AspectJAdvisorFactory advisorFactory) { + this.watcherProperties = watcherProperties; + SpringBeanAspect aspect = new SpringBeanAspect(requestScope, eventPublisher); + this.advisor = convertAspectToAdvisor(advisorFactory, aspect, "springBeanAspect"); + } - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) { - if (watcherProperties.getBeans().contains(beanName)) { - Object proxy = super.postProcessAfterInitialization(bean, beanName); - activeBeanNameCache.put(proxy, beanName); - return proxy; + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) { + if (watcherProperties.getBeans().contains(beanName)) { + Object proxy = super.postProcessAfterInitialization(bean, beanName); + activeBeanNameCache.put(proxy, beanName); + return proxy; + } + return bean; } - return bean; - } - private Advisor convertAspectToAdvisor( - AspectJAdvisorFactory advisorFactory, Object aspect, String name) { - val factory = new SingletonMetadataAwareAspectInstanceFactory(aspect, name); - List classAdvisors = advisorFactory.getAdvisors(factory); - if (classAdvisors.size() != 1) { - throw new IllegalArgumentException(name + " must contain exactly one advisor"); + private Advisor convertAspectToAdvisor(AspectJAdvisorFactory advisorFactory, Object aspect, String name) { + val factory = new SingletonMetadataAwareAspectInstanceFactory(aspect, name); + List classAdvisors = advisorFactory.getAdvisors(factory); + if (classAdvisors.size() != 1) { + throw new IllegalArgumentException(name + " must contain exactly one advisor"); + } + return classAdvisors.get(0); } - return classAdvisors.get(0); - } - @Aspect - @AllArgsConstructor - public class SpringBeanAspect extends ChaosMonkeyBaseAspect { + @Aspect + @AllArgsConstructor + public class SpringBeanAspect extends ChaosMonkeyBaseAspect { - private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; + private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; - private MetricEventPublisher metricEventPublisher; + private MetricEventPublisher metricEventPublisher; - @Around("allPublicMethodPointcut()") - public Object intercept(ProceedingJoinPoint pjp) throws Throwable { - if (watcherProperties.getBeans().contains(activeBeanNameCache.get(pjp.getThis()))) { - log.debug("Watching public method on bean class: {}", pjp.getSignature()); + @Around("allPublicMethodPointcut()") + public Object intercept(ProceedingJoinPoint pjp) throws Throwable { + if (watcherProperties.getBeans().contains(activeBeanNameCache.get(pjp.getThis()))) { + log.debug("Watching public method on bean class: {}", pjp.getSignature()); - if (metricEventPublisher != null) { - metricEventPublisher.publishMetricEvent( - calculatePointcut(pjp.toShortString()), MetricType.BEAN); - } + if (metricEventPublisher != null) { + metricEventPublisher.publishMetricEvent(calculatePointcut(pjp.toShortString()), MetricType.BEAN); + } - MethodSignature signature = (MethodSignature) pjp.getSignature(); + MethodSignature signature = (MethodSignature) pjp.getSignature(); - chaosMonkeyRequestScope.callChaosMonkey(ChaosTarget.BEAN, createSignature(signature)); - } - return pjp.proceed(); + chaosMonkeyRequestScope.callChaosMonkey(ChaosTarget.BEAN, createSignature(signature)); + } + return pjp.proceed(); + } } - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringBootHealthIndicatorAspect.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringBootHealthIndicatorAspect.java index 2b134bef..6116bd45 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringBootHealthIndicatorAspect.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringBootHealthIndicatorAspect.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.watcher.aspect; import de.codecentric.spring.boot.chaos.monkey.component.ChaosMonkeyRequestScope; @@ -17,26 +32,26 @@ @Slf4j public class SpringBootHealthIndicatorAspect extends ChaosMonkeyBaseAspect { - private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; + private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; - private final WatcherProperties watcherProperties; + private final WatcherProperties watcherProperties; - @Pointcut("execution(* org.springframework.boot.actuate.health.HealthIndicator.getHealth(..))") - public void getHealthPointCut() {} + @Pointcut("execution(* org.springframework.boot.actuate.health.HealthIndicator.getHealth(..))") + public void getHealthPointCut() { + } - @Around("getHealthPointCut() && !classInChaosMonkeyPackage()") - public Object intercept(ProceedingJoinPoint pjp) throws Throwable { - Health health = (Health) pjp.proceed(); - if (watcherProperties.isActuatorHealth()) { - MethodSignature signature = (MethodSignature) pjp.getSignature(); - try { - this.chaosMonkeyRequestScope.callChaosMonkey( - ChaosTarget.ACTUATOR_HEALTH, createSignature(signature)); - } catch (final Exception e) { - log.error("Exception occurred", e); - health = Health.down(e).build(); - } + @Around("getHealthPointCut() && !classInChaosMonkeyPackage()") + public Object intercept(ProceedingJoinPoint pjp) throws Throwable { + Health health = (Health) pjp.proceed(); + if (watcherProperties.isActuatorHealth()) { + MethodSignature signature = (MethodSignature) pjp.getSignature(); + try { + this.chaosMonkeyRequestScope.callChaosMonkey(ChaosTarget.ACTUATOR_HEALTH, createSignature(signature)); + } catch (final Exception e) { + log.error("Exception occurred", e); + health = Health.down(e).build(); + } + } + return health; } - return health; - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringComponentAspect.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringComponentAspect.java index 77462662..6eec2369 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringComponentAspect.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringComponentAspect.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.watcher.aspect; import de.codecentric.spring.boot.chaos.monkey.component.ChaosMonkeyRequestScope; @@ -35,34 +34,34 @@ @Slf4j public class SpringComponentAspect extends ChaosMonkeyBaseAspect { - private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; + private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; - private MetricEventPublisher metricEventPublisher; + private MetricEventPublisher metricEventPublisher; - private WatcherProperties watcherProperties; + private WatcherProperties watcherProperties; - @Pointcut("within(@org.springframework.stereotype.Component *)") - public void classAnnotatedWithComponentPointcut() {} + @Pointcut("within(@org.springframework.stereotype.Component *)") + public void classAnnotatedWithComponentPointcut() { + } - @Pointcut("within(org.springframework.cloud.context..*)") - public void classInSpringCloudContextPackage() {} + @Pointcut("within(org.springframework.cloud.context..*)") + public void classInSpringCloudContextPackage() { + } - @Around( - "classAnnotatedWithComponentPointcut() && !classInSpringCloudContextPackage() " - + "&& allPublicMethodPointcut() && !classInChaosMonkeyPackage() && !springHooksPointcut()") - public Object intercept(ProceedingJoinPoint pjp) throws Throwable { - if (watcherProperties.isComponent()) { - log.debug("Watching public method on component class: {}", pjp.getSignature()); + @Around("classAnnotatedWithComponentPointcut() && !classInSpringCloudContextPackage() " + + "&& allPublicMethodPointcut() && !classInChaosMonkeyPackage() && !springHooksPointcut()") + public Object intercept(ProceedingJoinPoint pjp) throws Throwable { + if (watcherProperties.isComponent()) { + log.debug("Watching public method on component class: {}", pjp.getSignature()); - if (metricEventPublisher != null) { - metricEventPublisher.publishMetricEvent( - calculatePointcut(pjp.toShortString()), MetricType.COMPONENT); - } + if (metricEventPublisher != null) { + metricEventPublisher.publishMetricEvent(calculatePointcut(pjp.toShortString()), MetricType.COMPONENT); + } - MethodSignature signature = (MethodSignature) pjp.getSignature(); + MethodSignature signature = (MethodSignature) pjp.getSignature(); - chaosMonkeyRequestScope.callChaosMonkey(ChaosTarget.COMPONENT, createSignature(signature)); + chaosMonkeyRequestScope.callChaosMonkey(ChaosTarget.COMPONENT, createSignature(signature)); + } + return pjp.proceed(); } - return pjp.proceed(); - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringControllerAspect.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringControllerAspect.java index 69f61683..474f9014 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringControllerAspect.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringControllerAspect.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.watcher.aspect; import de.codecentric.spring.boot.chaos.monkey.component.ChaosMonkeyRequestScope; @@ -35,31 +34,30 @@ @Slf4j public class SpringControllerAspect extends ChaosMonkeyBaseAspect { - private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; + private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; - private MetricEventPublisher metricEventPublisher; + private MetricEventPublisher metricEventPublisher; - private WatcherProperties watcherProperties; + private WatcherProperties watcherProperties; - @Pointcut("within(@org.springframework.stereotype.Controller *)") - public void classAnnotatedWithControllerPointcut() {} + @Pointcut("within(@org.springframework.stereotype.Controller *)") + public void classAnnotatedWithControllerPointcut() { + } - @Around( - "classAnnotatedWithControllerPointcut() && allPublicMethodPointcut() && !classInChaosMonkeyPackage()") - public Object intercept(ProceedingJoinPoint pjp) throws Throwable { + @Around("classAnnotatedWithControllerPointcut() && allPublicMethodPointcut() && !classInChaosMonkeyPackage()") + public Object intercept(ProceedingJoinPoint pjp) throws Throwable { - if (watcherProperties.isController()) { - log.debug("Watching public method on controller class: {}", pjp.getSignature()); + if (watcherProperties.isController()) { + log.debug("Watching public method on controller class: {}", pjp.getSignature()); - if (metricEventPublisher != null) { - metricEventPublisher.publishMetricEvent( - calculatePointcut(pjp.toShortString()), MetricType.CONTROLLER); - } + if (metricEventPublisher != null) { + metricEventPublisher.publishMetricEvent(calculatePointcut(pjp.toShortString()), MetricType.CONTROLLER); + } - MethodSignature signature = (MethodSignature) pjp.getSignature(); + MethodSignature signature = (MethodSignature) pjp.getSignature(); - chaosMonkeyRequestScope.callChaosMonkey(ChaosTarget.CONTROLLER, createSignature(signature)); + chaosMonkeyRequestScope.callChaosMonkey(ChaosTarget.CONTROLLER, createSignature(signature)); + } + return pjp.proceed(); } - return pjp.proceed(); - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectJDBC.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectJDBC.java index 33d0af34..ea555503 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectJDBC.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectJDBC.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.watcher.aspect; import de.codecentric.spring.boot.chaos.monkey.component.ChaosMonkeyRequestScope; @@ -35,31 +34,30 @@ @Slf4j public class SpringRepositoryAspectJDBC extends ChaosMonkeyBaseAspect { - private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; + private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; - private MetricEventPublisher metricEventPublisher; + private MetricEventPublisher metricEventPublisher; - private WatcherProperties watcherProperties; + private WatcherProperties watcherProperties; - @Pointcut("within(@org.springframework.stereotype.Repository *)") - public void classAnnotatedWithRepositoryPointcut() {} + @Pointcut("within(@org.springframework.stereotype.Repository *)") + public void classAnnotatedWithRepositoryPointcut() { + } - @Around( - "classAnnotatedWithRepositoryPointcut() && allPublicMethodPointcut() && !classInChaosMonkeyPackage()") - public Object intercept(ProceedingJoinPoint pjp) throws Throwable { + @Around("classAnnotatedWithRepositoryPointcut() && allPublicMethodPointcut() && !classInChaosMonkeyPackage()") + public Object intercept(ProceedingJoinPoint pjp) throws Throwable { - if (watcherProperties.isRepository()) { - log.debug("Watching public method on repository stereotype class: {}", pjp.getSignature()); + if (watcherProperties.isRepository()) { + log.debug("Watching public method on repository stereotype class: {}", pjp.getSignature()); - if (metricEventPublisher != null) { - metricEventPublisher.publishMetricEvent( - calculatePointcut(pjp.toShortString()), MetricType.REPOSITORY); - } + if (metricEventPublisher != null) { + metricEventPublisher.publishMetricEvent(calculatePointcut(pjp.toShortString()), MetricType.REPOSITORY); + } - MethodSignature signature = (MethodSignature) pjp.getSignature(); + MethodSignature signature = (MethodSignature) pjp.getSignature(); - chaosMonkeyRequestScope.callChaosMonkey(ChaosTarget.REPOSITORY, createSignature(signature)); + chaosMonkeyRequestScope.callChaosMonkey(ChaosTarget.REPOSITORY, createSignature(signature)); + } + return pjp.proceed(); } - return pjp.proceed(); - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectJPA.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectJPA.java index df2613ca..578bd387 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectJPA.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectJPA.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.watcher.aspect; import de.codecentric.spring.boot.chaos.monkey.component.ChaosMonkeyRequestScope; @@ -35,31 +34,30 @@ @Slf4j public class SpringRepositoryAspectJPA extends ChaosMonkeyBaseAspect { - private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; + private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; - private MetricEventPublisher metricEventPublisher; + private MetricEventPublisher metricEventPublisher; - private WatcherProperties watcherProperties; + private WatcherProperties watcherProperties; - @Pointcut( - "this(org.springframework.data.repository.Repository) || within(@org.springframework.data.repository.RepositoryDefinition *)") - public void implementsCrudRepository() {} + @Pointcut("this(org.springframework.data.repository.Repository) || within(@org.springframework.data.repository.RepositoryDefinition *)") + public void implementsCrudRepository() { + } - @Around("implementsCrudRepository() && allPublicMethodPointcut() && !classInChaosMonkeyPackage()") - public Object intercept(ProceedingJoinPoint pjp) throws Throwable { + @Around("implementsCrudRepository() && allPublicMethodPointcut() && !classInChaosMonkeyPackage()") + public Object intercept(ProceedingJoinPoint pjp) throws Throwable { - if (watcherProperties.isRepository()) { - log.debug("Watching public method on repository class: {}", pjp.getSignature()); + if (watcherProperties.isRepository()) { + log.debug("Watching public method on repository class: {}", pjp.getSignature()); - if (metricEventPublisher != null) { - metricEventPublisher.publishMetricEvent( - calculatePointcut(pjp.toShortString()), MetricType.REPOSITORY); - } + if (metricEventPublisher != null) { + metricEventPublisher.publishMetricEvent(calculatePointcut(pjp.toShortString()), MetricType.REPOSITORY); + } - MethodSignature signature = (MethodSignature) pjp.getSignature(); + MethodSignature signature = (MethodSignature) pjp.getSignature(); - chaosMonkeyRequestScope.callChaosMonkey(ChaosTarget.REPOSITORY, createSignature(signature)); + chaosMonkeyRequestScope.callChaosMonkey(ChaosTarget.REPOSITORY, createSignature(signature)); + } + return pjp.proceed(); } - return pjp.proceed(); - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRestControllerAspect.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRestControllerAspect.java index 45dcc21f..5c7e3ef4 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRestControllerAspect.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRestControllerAspect.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.watcher.aspect; import de.codecentric.spring.boot.chaos.monkey.component.ChaosMonkeyRequestScope; @@ -35,32 +34,30 @@ @Slf4j public class SpringRestControllerAspect extends ChaosMonkeyBaseAspect { - private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; + private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; - private MetricEventPublisher metricEventPublisher; + private MetricEventPublisher metricEventPublisher; - private WatcherProperties watcherProperties; + private WatcherProperties watcherProperties; - @Pointcut("within(@org.springframework.web.bind.annotation.RestController *)") - public void classAnnotatedWithControllerPointcut() {} + @Pointcut("within(@org.springframework.web.bind.annotation.RestController *)") + public void classAnnotatedWithControllerPointcut() { + } - @Around( - "classAnnotatedWithControllerPointcut() && allPublicMethodPointcut() && !classInChaosMonkeyPackage()") - public Object intercept(ProceedingJoinPoint pjp) throws Throwable { + @Around("classAnnotatedWithControllerPointcut() && allPublicMethodPointcut() && !classInChaosMonkeyPackage()") + public Object intercept(ProceedingJoinPoint pjp) throws Throwable { - if (watcherProperties.isRestController()) { - log.debug("Watching public method on rest controller class: {}", pjp.getSignature()); + if (watcherProperties.isRestController()) { + log.debug("Watching public method on rest controller class: {}", pjp.getSignature()); - if (metricEventPublisher != null) { - metricEventPublisher.publishMetricEvent( - calculatePointcut(pjp.toShortString()), MetricType.RESTCONTROLLER); - } + if (metricEventPublisher != null) { + metricEventPublisher.publishMetricEvent(calculatePointcut(pjp.toShortString()), MetricType.RESTCONTROLLER); + } - MethodSignature signature = (MethodSignature) pjp.getSignature(); + MethodSignature signature = (MethodSignature) pjp.getSignature(); - chaosMonkeyRequestScope.callChaosMonkey( - ChaosTarget.REST_CONTROLLER, createSignature(signature)); + chaosMonkeyRequestScope.callChaosMonkey(ChaosTarget.REST_CONTROLLER, createSignature(signature)); + } + return pjp.proceed(); } - return pjp.proceed(); - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringServiceAspect.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringServiceAspect.java index 673be14b..6bb24ec8 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringServiceAspect.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringServiceAspect.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.watcher.aspect; import de.codecentric.spring.boot.chaos.monkey.component.ChaosMonkeyRequestScope; @@ -35,32 +34,30 @@ @Slf4j public class SpringServiceAspect extends ChaosMonkeyBaseAspect { - private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; + private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; - private MetricEventPublisher metricEventPublisher; + private MetricEventPublisher metricEventPublisher; - private WatcherProperties watcherProperties; + private WatcherProperties watcherProperties; - @Pointcut("within(@org.springframework.stereotype.Service *)") - public void classAnnotatedWithServicePointcut() {} + @Pointcut("within(@org.springframework.stereotype.Service *)") + public void classAnnotatedWithServicePointcut() { + } - @Around( - "classAnnotatedWithServicePointcut() && allPublicMethodPointcut() && !classInChaosMonkeyPackage()" - + "&& !springHooksPointcut()") - public Object intercept(ProceedingJoinPoint pjp) throws Throwable { + @Around("classAnnotatedWithServicePointcut() && allPublicMethodPointcut() && !classInChaosMonkeyPackage()" + "&& !springHooksPointcut()") + public Object intercept(ProceedingJoinPoint pjp) throws Throwable { - if (watcherProperties.isService()) { - log.debug("Watching public method on service class: {}", pjp.getSignature()); + if (watcherProperties.isService()) { + log.debug("Watching public method on service class: {}", pjp.getSignature()); - if (metricEventPublisher != null) { - metricEventPublisher.publishMetricEvent( - calculatePointcut(pjp.toShortString()), MetricType.SERVICE); - } + if (metricEventPublisher != null) { + metricEventPublisher.publishMetricEvent(calculatePointcut(pjp.toShortString()), MetricType.SERVICE); + } - MethodSignature signature = (MethodSignature) pjp.getSignature(); + MethodSignature signature = (MethodSignature) pjp.getSignature(); - chaosMonkeyRequestScope.callChaosMonkey(ChaosTarget.SERVICE, createSignature(signature)); + chaosMonkeyRequestScope.callChaosMonkey(ChaosTarget.SERVICE, createSignature(signature)); + } + return pjp.proceed(); } - return pjp.proceed(); - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyRestTemplateCustomizer.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyRestTemplateCustomizer.java index dc980a5d..afa6cfc3 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyRestTemplateCustomizer.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyRestTemplateCustomizer.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.watcher.outgoing; import java.util.List; @@ -8,17 +23,17 @@ /** @author Marcel Becker */ public class ChaosMonkeyRestTemplateCustomizer implements RestTemplateCustomizer { - private final ChaosMonkeyRestTemplateWatcher interceptor; + private final ChaosMonkeyRestTemplateWatcher interceptor; - public ChaosMonkeyRestTemplateCustomizer(ChaosMonkeyRestTemplateWatcher interceptor) { - this.interceptor = interceptor; - } + public ChaosMonkeyRestTemplateCustomizer(ChaosMonkeyRestTemplateWatcher interceptor) { + this.interceptor = interceptor; + } - @Override - public void customize(RestTemplate restTemplate) { - final List existingInterceptors = restTemplate.getInterceptors(); - if (!existingInterceptors.contains(interceptor)) { - restTemplate.getInterceptors().add(interceptor); + @Override + public void customize(RestTemplate restTemplate) { + final List existingInterceptors = restTemplate.getInterceptors(); + if (!existingInterceptors.contains(interceptor)) { + restTemplate.getInterceptors().add(interceptor); + } } - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyRestTemplatePostProcessor.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyRestTemplatePostProcessor.java index e065c89a..1e5bcb47 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyRestTemplatePostProcessor.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyRestTemplatePostProcessor.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.watcher.outgoing; import org.springframework.beans.BeansException; @@ -7,19 +22,17 @@ /** @author Marcel Becker */ public class ChaosMonkeyRestTemplatePostProcessor implements BeanPostProcessor { - private final ChaosMonkeyRestTemplateCustomizer restTemplateCustomizer; + private final ChaosMonkeyRestTemplateCustomizer restTemplateCustomizer; - public ChaosMonkeyRestTemplatePostProcessor( - ChaosMonkeyRestTemplateCustomizer restTemplateCustomizer) { - this.restTemplateCustomizer = restTemplateCustomizer; - } + public ChaosMonkeyRestTemplatePostProcessor(ChaosMonkeyRestTemplateCustomizer restTemplateCustomizer) { + this.restTemplateCustomizer = restTemplateCustomizer; + } - @Override - public Object postProcessBeforeInitialization(final Object bean, final String beanName) - throws BeansException { - if (bean instanceof RestTemplate) { - this.restTemplateCustomizer.customize((RestTemplate) bean); + @Override + public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException { + if (bean instanceof RestTemplate) { + this.restTemplateCustomizer.customize((RestTemplate) bean); + } + return bean; } - return bean; - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyRestTemplateWatcher.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyRestTemplateWatcher.java index b40aee82..5f3501f7 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyRestTemplateWatcher.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyRestTemplateWatcher.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.watcher.outgoing; import de.codecentric.spring.boot.chaos.monkey.component.ChaosMonkeyRequestScope; @@ -23,88 +38,83 @@ /** @author Marcel Becker */ public class ChaosMonkeyRestTemplateWatcher implements ClientHttpRequestInterceptor { - private final WatcherProperties watcherProperties; - private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; - private final AssaultProperties assaultProperties; + private final WatcherProperties watcherProperties; + private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; + private final AssaultProperties assaultProperties; - public ChaosMonkeyRestTemplateWatcher( - final ChaosMonkeyRequestScope chaosMonkeyRequestScope, - final WatcherProperties watcherProperties, - AssaultProperties assaultProperties) { - this.chaosMonkeyRequestScope = chaosMonkeyRequestScope; - this.watcherProperties = watcherProperties; - this.assaultProperties = assaultProperties; - } + public ChaosMonkeyRestTemplateWatcher(final ChaosMonkeyRequestScope chaosMonkeyRequestScope, final WatcherProperties watcherProperties, + AssaultProperties assaultProperties) { + this.chaosMonkeyRequestScope = chaosMonkeyRequestScope; + this.watcherProperties = watcherProperties; + this.assaultProperties = assaultProperties; + } - @Override - public ClientHttpResponse intercept( - final HttpRequest httpRequest, - byte[] bytes, - ClientHttpRequestExecution clientHttpRequestExecution) - throws IOException { - ClientHttpResponse response = clientHttpRequestExecution.execute(httpRequest, bytes); - if (watcherProperties.isRestTemplate()) { - try { - chaosMonkeyRequestScope.callChaosMonkey( - ChaosTarget.REST_TEMPLATE, httpRequest.getURI().toString()); - } catch (final Exception exception) { - try { - if (exception.getClass().equals(assaultProperties.getException().getExceptionClass())) { - response = new ErrorResponse(); - } else { - throw exception; - } - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); + @Override + public ClientHttpResponse intercept(final HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) + throws IOException { + ClientHttpResponse response = clientHttpRequestExecution.execute(httpRequest, bytes); + if (watcherProperties.isRestTemplate()) { + try { + chaosMonkeyRequestScope.callChaosMonkey(ChaosTarget.REST_TEMPLATE, httpRequest.getURI().toString()); + } catch (final Exception exception) { + try { + if (exception.getClass().equals(assaultProperties.getException().getExceptionClass())) { + response = new ErrorResponse(); + } else { + throw exception; + } + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } } - } + return response; } - return response; - } - static class ErrorResponse extends AbstractClientHttpResponse { + static class ErrorResponse extends AbstractClientHttpResponse { - static final String ERROR_TEXT = "This error is generated by Chaos Monkey for Spring Boot"; - static final String ERROR_BODY = - "{\"error\": \"This is a Chaos Monkey for Spring Boot generated failure\"}"; + static final String ERROR_TEXT = "This error is generated by Chaos Monkey for Spring Boot"; + static final String ERROR_BODY = "{\"error\": \"This is a Chaos Monkey for Spring Boot generated failure\"}"; - private static final Logger Logger = LoggerFactory.getLogger(ErrorResponse.class); + private static final Logger Logger = LoggerFactory.getLogger(ErrorResponse.class); - @Nullable private InputStream responseStream; + @Nullable + private InputStream responseStream; - @Override - public int getRawStatusCode() { - return HttpStatus.INTERNAL_SERVER_ERROR.value(); - } + @Override + public int getRawStatusCode() { + return HttpStatus.INTERNAL_SERVER_ERROR.value(); + } - @Override - public String getStatusText() { - return ERROR_TEXT; - } + @Override + public String getStatusText() { + return ERROR_TEXT; + } - @Override - public void close() { - try { - if (this.responseStream == null) { - getBody(); + @Override + public void close() { + try { + if (this.responseStream == null) { + getBody(); + } + StreamUtils.drain(this.responseStream); + this.responseStream.close(); + } catch (Exception ex) { + Logger.debug("Exception while closing the error response", ex); + // ignore {@see + // #org.springframework.http.client.SimpleClientHttpResponse.close()} + } } - StreamUtils.drain(this.responseStream); - this.responseStream.close(); - } catch (Exception ex) { - Logger.debug("Exception while closing the error response", ex); - // ignore {@see #org.springframework.http.client.SimpleClientHttpResponse.close()} - } - } - @Override - public InputStream getBody() { - responseStream = new ByteArrayInputStream(ERROR_BODY.getBytes(StandardCharsets.UTF_8)); - return responseStream; - } + @Override + public InputStream getBody() { + responseStream = new ByteArrayInputStream(ERROR_BODY.getBytes(StandardCharsets.UTF_8)); + return responseStream; + } - @Override - public HttpHeaders getHeaders() { - return new HttpHeaders(); + @Override + public HttpHeaders getHeaders() { + return new HttpHeaders(); + } } - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyWebClientCustomizer.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyWebClientCustomizer.java index 73c0336c..bbd43d6e 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyWebClientCustomizer.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyWebClientCustomizer.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.watcher.outgoing; import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; @@ -5,14 +20,14 @@ public class ChaosMonkeyWebClientCustomizer implements WebClientCustomizer { - private final ChaosMonkeyWebClientWatcher chaosMonkeyWebClientWatcher; + private final ChaosMonkeyWebClientWatcher chaosMonkeyWebClientWatcher; - public ChaosMonkeyWebClientCustomizer(ChaosMonkeyWebClientWatcher chaosMonkeyWebClientWatcher) { - this.chaosMonkeyWebClientWatcher = chaosMonkeyWebClientWatcher; - } + public ChaosMonkeyWebClientCustomizer(ChaosMonkeyWebClientWatcher chaosMonkeyWebClientWatcher) { + this.chaosMonkeyWebClientWatcher = chaosMonkeyWebClientWatcher; + } - @Override - public void customize(Builder webClientBuilder) { - webClientBuilder.filter(chaosMonkeyWebClientWatcher); - } + @Override + public void customize(Builder webClientBuilder) { + webClientBuilder.filter(chaosMonkeyWebClientWatcher); + } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyWebClientPostProcessor.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyWebClientPostProcessor.java index 850d8e9a..d7bf7e15 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyWebClientPostProcessor.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyWebClientPostProcessor.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.watcher.outgoing; import org.springframework.beans.BeansException; @@ -7,22 +22,22 @@ /** @author Marcel Becker */ public class ChaosMonkeyWebClientPostProcessor implements BeanPostProcessor { - private final ChaosMonkeyWebClientWatcher filter; + private final ChaosMonkeyWebClientWatcher filter; - public ChaosMonkeyWebClientPostProcessor(final ChaosMonkeyWebClientWatcher filter) { - this.filter = filter; - } + public ChaosMonkeyWebClientPostProcessor(final ChaosMonkeyWebClientWatcher filter) { + this.filter = filter; + } - @Override - public Object postProcessBeforeInitialization(final Object bean, final String beanName) - throws BeansException { - final Object target; - if (bean instanceof WebClient) { - // create a copy of WebClient whose settings are replicated from the current WebClient. - target = ((WebClient) bean).mutate().filter(filter).build(); - } else { - target = bean; + @Override + public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException { + final Object target; + if (bean instanceof WebClient) { + // create a copy of WebClient whose settings are replicated from the current + // WebClient. + target = ((WebClient) bean).mutate().filter(filter).build(); + } else { + target = bean; + } + return target; } - return target; - } } diff --git a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyWebClientWatcher.java b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyWebClientWatcher.java index 56382430..2e786bba 100644 --- a/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyWebClientWatcher.java +++ b/chaos-monkey-spring-boot/src/main/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyWebClientWatcher.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.watcher.outgoing; import de.codecentric.spring.boot.chaos.monkey.component.ChaosMonkeyRequestScope; @@ -16,76 +31,71 @@ /** @author Marcel Becker */ public class ChaosMonkeyWebClientWatcher implements ExchangeFilterFunction { - private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; - private final WatcherProperties watcherProperties; - private final AssaultProperties assaultProperties; + private final ChaosMonkeyRequestScope chaosMonkeyRequestScope; + private final WatcherProperties watcherProperties; + private final AssaultProperties assaultProperties; - private static final String ALREADY_FILTERED_SUFFIX = ".FILTERED"; + private static final String ALREADY_FILTERED_SUFFIX = ".FILTERED"; - public ChaosMonkeyWebClientWatcher( - final ChaosMonkeyRequestScope chaosMonkeyRequestScope, - final WatcherProperties watcherProperties, - AssaultProperties assaultProperties) { - this.chaosMonkeyRequestScope = chaosMonkeyRequestScope; - this.watcherProperties = watcherProperties; - this.assaultProperties = assaultProperties; - } + public ChaosMonkeyWebClientWatcher(final ChaosMonkeyRequestScope chaosMonkeyRequestScope, final WatcherProperties watcherProperties, + AssaultProperties assaultProperties) { + this.chaosMonkeyRequestScope = chaosMonkeyRequestScope; + this.watcherProperties = watcherProperties; + this.assaultProperties = assaultProperties; + } - @Override - public Mono filter( - ClientRequest clientRequest, ExchangeFunction exchangeFunction) { - final RequestFilterWrapper requestFilterWrapper = handleOncePerRequest(clientRequest); - Mono response = exchangeFunction.exchange(requestFilterWrapper.clientRequest); - if (requestFilterWrapper.filter) { - if (watcherProperties.isWebClient()) { - try { - chaosMonkeyRequestScope.callChaosMonkey( - ChaosTarget.WEB_CLIENT, clientRequest.url().toString()); - } catch (final Exception exception) { - try { - if (exception.getClass().equals(assaultProperties.getException().getExceptionClass())) { - response = Mono.just(ErrorClientResponse.getResponse()); - } else { - throw exception; + @Override + public Mono filter(ClientRequest clientRequest, ExchangeFunction exchangeFunction) { + final RequestFilterWrapper requestFilterWrapper = handleOncePerRequest(clientRequest); + Mono response = exchangeFunction.exchange(requestFilterWrapper.clientRequest); + if (requestFilterWrapper.filter) { + if (watcherProperties.isWebClient()) { + try { + chaosMonkeyRequestScope.callChaosMonkey(ChaosTarget.WEB_CLIENT, clientRequest.url().toString()); + } catch (final Exception exception) { + try { + if (exception.getClass().equals(assaultProperties.getException().getExceptionClass())) { + response = Mono.just(ErrorClientResponse.getResponse()); + } else { + throw exception; + } + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } } - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } } - } + return response; } - return response; - } - private RequestFilterWrapper handleOncePerRequest(final ClientRequest clientRequest) { - final String filterName = this.getClass().getName() + ALREADY_FILTERED_SUFFIX; - final Boolean filter; - final ClientRequest request; - if (clientRequest.attribute(filterName).isPresent()) { - filter = Boolean.FALSE; - request = clientRequest; - } else { - filter = Boolean.TRUE; - request = ClientRequest.from(clientRequest).attribute(filterName, Boolean.TRUE).build(); + private RequestFilterWrapper handleOncePerRequest(final ClientRequest clientRequest) { + final String filterName = this.getClass().getName() + ALREADY_FILTERED_SUFFIX; + final Boolean filter; + final ClientRequest request; + if (clientRequest.attribute(filterName).isPresent()) { + filter = Boolean.FALSE; + request = clientRequest; + } else { + filter = Boolean.TRUE; + request = ClientRequest.from(clientRequest).attribute(filterName, Boolean.TRUE).build(); + } + return new RequestFilterWrapper(request, filter); } - return new RequestFilterWrapper(request, filter); - } - @Data - @AllArgsConstructor - private static class RequestFilterWrapper { + @Data + @AllArgsConstructor + private static class RequestFilterWrapper { - private final ClientRequest clientRequest; - private final Boolean filter; - } + private final ClientRequest clientRequest; + private final Boolean filter; + } - static class ErrorClientResponse { + static class ErrorClientResponse { - static final String ERROR_BODY = - "{\"error\": \"This is a Chaos Monkey for Spring Boot generated failure\"}"; + static final String ERROR_BODY = "{\"error\": \"This is a Chaos Monkey for Spring Boot generated failure\"}"; - private static ClientResponse getResponse() { - return ClientResponse.create(HttpStatus.INTERNAL_SERVER_ERROR).body(ERROR_BODY).build(); + private static ClientResponse getResponse() { + return ClientResponse.create(HttpStatus.INTERNAL_SERVER_ERROR).body(ERROR_BODY).build(); + } } - } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/ChaosDemoApplicationChaosMonkeyRequestScopeProfileTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/ChaosDemoApplicationChaosMonkeyRequestScopeProfileTest.java index 3db3a1d4..4db63556 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/ChaosDemoApplicationChaosMonkeyRequestScopeProfileTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/ChaosDemoApplicationChaosMonkeyRequestScopeProfileTest.java @@ -1,20 +1,18 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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.spring.boot.chaos.monkey; import static org.assertj.core.api.Assertions.assertThat; @@ -38,67 +36,59 @@ import org.springframework.boot.test.context.SpringBootTest; /** @author Benjamin Wilms */ -@SpringBootTest( - classes = ChaosDemoApplication.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = { - "chaos.monkey.watcher.controller=true", - "chaos.monkey.assaults.level=1", - "chaos.monkey.assaults.latencyRangeStart=10", - "chaos.monkey.assaults.latencyRangeEnd=50", - "chaos.monkey.assaults.killApplicationActive=true", - "spring.profiles.active=chaos-monkey" - }) +@SpringBootTest(classes = ChaosDemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { + "chaos.monkey.watcher.controller=true", "chaos.monkey.assaults.level=1", "chaos.monkey.assaults.latencyRangeStart=10", + "chaos.monkey.assaults.latencyRangeEnd=50", "chaos.monkey.assaults.killApplicationActive=true", "spring.profiles.active=chaos-monkey"}) class ChaosDemoApplicationChaosMonkeyRequestScopeProfileTest { - @Autowired private ChaosMonkeyRequestScope chaosMonkeyRequestScope; + @Autowired + private ChaosMonkeyRequestScope chaosMonkeyRequestScope; - @Autowired private ChaosMonkeySettings monkeySettings; + @Autowired + private ChaosMonkeySettings monkeySettings; - @Autowired private LatencyAssault latencyAssault; + @Autowired + private LatencyAssault latencyAssault; - @Autowired private ExceptionAssault exceptionAssault; + @Autowired + private ExceptionAssault exceptionAssault; - @Autowired private KillAppAssault killAppAssault; + @Autowired + private KillAppAssault killAppAssault; - @Mock private MetricEventPublisher metricsMock; + @Mock + private MetricEventPublisher metricsMock; - @BeforeEach - void setUp() { - chaosMonkeyRequestScope = - new ChaosMonkeyRequestScope( - monkeySettings, - Arrays.asList(latencyAssault, exceptionAssault), - Collections.emptyList(), - metricsMock, - new DefaultChaosToggles(), - new DefaultChaosToggleNameMapper( - monkeySettings.getChaosMonkeyProperties().getTogglePrefix())); - } + @BeforeEach + void setUp() { + chaosMonkeyRequestScope = new ChaosMonkeyRequestScope(monkeySettings, Arrays.asList(latencyAssault, exceptionAssault), + Collections.emptyList(), metricsMock, new DefaultChaosToggles(), + new DefaultChaosToggleNameMapper(monkeySettings.getChaosMonkeyProperties().getTogglePrefix())); + } - @Test - void contextLoads() { - assertNotNull(chaosMonkeyRequestScope); - } + @Test + void contextLoads() { + assertNotNull(chaosMonkeyRequestScope); + } - @Test - void checkChaosSettingsObject() { - assertNotNull(monkeySettings); - } + @Test + void checkChaosSettingsObject() { + assertNotNull(monkeySettings); + } - @Test - void checkChaosSettingsValues() { - assertThat(monkeySettings.getChaosMonkeyProperties().isEnabled()).isFalse(); - assertThat(monkeySettings.getAssaultProperties().getLatencyRangeEnd()).isEqualTo(50); - assertThat(monkeySettings.getAssaultProperties().getLatencyRangeStart()).isEqualTo(10); - assertThat(monkeySettings.getAssaultProperties().getLevel()).isEqualTo(1); - assertThat(monkeySettings.getAssaultProperties().isLatencyActive()).isFalse(); - assertThat(monkeySettings.getAssaultProperties().isExceptionsActive()).isFalse(); - assertThat(monkeySettings.getAssaultProperties().isKillApplicationActive()).isTrue(); - assertThat(monkeySettings.getAssaultProperties().getWatchedCustomServices()).isNull(); - assertThat(monkeySettings.getWatcherProperties().isController()).isTrue(); - assertThat(monkeySettings.getWatcherProperties().isRepository()).isFalse(); - assertThat(monkeySettings.getWatcherProperties().isRestController()).isFalse(); - assertThat(monkeySettings.getWatcherProperties().isService()).isFalse(); - } + @Test + void checkChaosSettingsValues() { + assertThat(monkeySettings.getChaosMonkeyProperties().isEnabled()).isFalse(); + assertThat(monkeySettings.getAssaultProperties().getLatencyRangeEnd()).isEqualTo(50); + assertThat(monkeySettings.getAssaultProperties().getLatencyRangeStart()).isEqualTo(10); + assertThat(monkeySettings.getAssaultProperties().getLevel()).isEqualTo(1); + assertThat(monkeySettings.getAssaultProperties().isLatencyActive()).isFalse(); + assertThat(monkeySettings.getAssaultProperties().isExceptionsActive()).isFalse(); + assertThat(monkeySettings.getAssaultProperties().isKillApplicationActive()).isTrue(); + assertThat(monkeySettings.getAssaultProperties().getWatchedCustomServices()).isNull(); + assertThat(monkeySettings.getWatcherProperties().isController()).isTrue(); + assertThat(monkeySettings.getWatcherProperties().isRepository()).isFalse(); + assertThat(monkeySettings.getWatcherProperties().isRestController()).isFalse(); + assertThat(monkeySettings.getWatcherProperties().isService()).isFalse(); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/ChaosDemoApplicationDefaultProfileTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/ChaosDemoApplicationDefaultProfileTest.java index 0d254b50..2c45f8d2 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/ChaosDemoApplicationDefaultProfileTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/ChaosDemoApplicationDefaultProfileTest.java @@ -1,20 +1,18 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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.spring.boot.chaos.monkey; import static org.assertj.core.api.Assertions.assertThat; @@ -30,45 +28,41 @@ import org.springframework.test.context.TestPropertySource; /** @author Benjamin Wilms */ -@SpringBootTest( - classes = ChaosDemoApplication.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(classes = ChaosDemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestPropertySource("classpath:application-test-default-profile.properties") class ChaosDemoApplicationDefaultProfileTest { - @Autowired(required = false) - private ChaosMonkeyRequestScope chaosMonkeyRequestScope; + @Autowired(required = false) + private ChaosMonkeyRequestScope chaosMonkeyRequestScope; - @Autowired private Environment env; + @Autowired + private Environment env; - @Test - void contextLoads() { - assertNull(chaosMonkeyRequestScope); - } + @Test + void contextLoads() { + assertNull(chaosMonkeyRequestScope); + } - @Test - void checkEnvWatcherController() { - assertThat(env.getProperty("chaos.monkey.watcher.controller")).isEqualTo("true"); - } + @Test + void checkEnvWatcherController() { + assertThat(env.getProperty("chaos.monkey.watcher.controller")).isEqualTo("true"); + } - @Test - void checkEnvAssaultLatencyRangeStart() { - assertThat(env.getProperty("chaos.monkey.assaults.latency-range-start")).isEqualTo("100"); - } + @Test + void checkEnvAssaultLatencyRangeStart() { + assertThat(env.getProperty("chaos.monkey.assaults.latency-range-start")).isEqualTo("100"); + } - @Test - void checkEnvAssaultLatencyRangeEnd() { - assertThat(env.getProperty("chaos.monkey.assaults.latency-range-end")).isEqualTo("200"); - } + @Test + void checkEnvAssaultLatencyRangeEnd() { + assertThat(env.getProperty("chaos.monkey.assaults.latency-range-end")).isEqualTo("200"); + } - @Test - void checkEnvCustomServiceWatcherList() { - List stringList = - env.getProperty("chaos.monkey.assaults.watchedCustomServices", List.class); - assertThat(stringList).hasSize(2); - assertThat(stringList.get(0)) - .isEqualTo("com.example.chaos.monkey.chaosdemo.controller.HelloController.sayHello"); - assertThat(stringList.get(1)) - .isEqualTo("com.example.chaos.monkey.chaosdemo.controller.HelloController.sayGoodbye"); - } + @Test + void checkEnvCustomServiceWatcherList() { + List stringList = env.getProperty("chaos.monkey.assaults.watchedCustomServices", List.class); + assertThat(stringList).hasSize(2); + assertThat(stringList.get(0)).isEqualTo("com.example.chaos.monkey.chaosdemo.controller.HelloController.sayHello"); + assertThat(stringList.get(1)).isEqualTo("com.example.chaos.monkey.chaosdemo.controller.HelloController.sayGoodbye"); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/DefaultSettingsIntegrationTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/DefaultSettingsIntegrationTest.java index 5dd247b1..dbc8747a 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/DefaultSettingsIntegrationTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/DefaultSettingsIntegrationTest.java @@ -1,20 +1,18 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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.spring.boot.chaos.monkey; import static org.assertj.core.api.Assertions.assertThat; @@ -26,43 +24,42 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; -@SpringBootTest( - classes = ChaosDemoApplication.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(classes = ChaosDemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ActiveProfiles("chaos-monkey") class DefaultSettingsIntegrationTest { - @Autowired private ChaosMonkeySettings monkeySettings; + @Autowired + private ChaosMonkeySettings monkeySettings; - @Test - void masterSwitchShouldDefaultToOff() { - assertThat(monkeySettings.getChaosMonkeyProperties().isEnabled()).isFalse(); - } + @Test + void masterSwitchShouldDefaultToOff() { + assertThat(monkeySettings.getChaosMonkeyProperties().isEnabled()).isFalse(); + } - @Test - void watchersShouldBeDisabledByDefault() { - assertThat(monkeySettings.getAssaultProperties().getWatchedCustomServices()).isNull(); - assertThat(monkeySettings.getWatcherProperties().isController()).isFalse(); - assertThat(monkeySettings.getWatcherProperties().isRestController()).isFalse(); - assertThat(monkeySettings.getWatcherProperties().isRepository()).isFalse(); - assertThat(monkeySettings.getWatcherProperties().isService()).isFalse(); - assertThat(monkeySettings.getWatcherProperties().isComponent()).isFalse(); - } + @Test + void watchersShouldBeDisabledByDefault() { + assertThat(monkeySettings.getAssaultProperties().getWatchedCustomServices()).isNull(); + assertThat(monkeySettings.getWatcherProperties().isController()).isFalse(); + assertThat(monkeySettings.getWatcherProperties().isRestController()).isFalse(); + assertThat(monkeySettings.getWatcherProperties().isRepository()).isFalse(); + assertThat(monkeySettings.getWatcherProperties().isService()).isFalse(); + assertThat(monkeySettings.getWatcherProperties().isComponent()).isFalse(); + } - @Test - void assaultsShouldBeDisabledByDefault() { - assertThat(monkeySettings.getAssaultProperties().isLatencyActive()).isFalse(); - assertThat(monkeySettings.getAssaultProperties().isExceptionsActive()).isFalse(); - } + @Test + void assaultsShouldBeDisabledByDefault() { + assertThat(monkeySettings.getAssaultProperties().isLatencyActive()).isFalse(); + assertThat(monkeySettings.getAssaultProperties().isExceptionsActive()).isFalse(); + } - @Test - void levelShouldDefaultToOne() { - assertThat(monkeySettings.getAssaultProperties().getLevel()).isEqualTo(1); - } + @Test + void levelShouldDefaultToOne() { + assertThat(monkeySettings.getAssaultProperties().getLevel()).isEqualTo(1); + } - @Test - void latencyDefaultsShouldBeSensible() { - assertThat(monkeySettings.getAssaultProperties().getLatencyRangeStart()).isEqualTo(1000); - assertThat(monkeySettings.getAssaultProperties().getLatencyRangeEnd()).isEqualTo(3000); - } + @Test + void latencyDefaultsShouldBeSensible() { + assertThat(monkeySettings.getAssaultProperties().getLatencyRangeStart()).isEqualTo(1000); + assertThat(monkeySettings.getAssaultProperties().getLatencyRangeEnd()).isEqualTo(3000); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/CPUAssaultIntegration.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/CPUAssaultIntegration.java index 7e0fcedf..a5233c07 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/CPUAssaultIntegration.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/CPUAssaultIntegration.java @@ -1,20 +1,18 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2022 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 + * https://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.spring.boot.chaos.monkey.assaults; import static org.junit.jupiter.api.Assertions.*; @@ -34,122 +32,109 @@ /** @author Lukas Morawietz */ abstract class CPUAssaultIntegration { - @SpringBootTest( - classes = ChaosDemoApplication.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = { - "management.endpoints.web.exposure.include=chaosmonkey", - "management.endpoints.enabled-by-default=true", - "chaos.monkey.assaults.cpuActive=true", - "chaos.monkey.assaults.cpuLoadTargetFraction=0.3", - "chaos.monkey.assaults.cpuMillisecondsHoldLoad=5000", - "spring.profiles.active=chaos-monkey" - }) - static class LowCPUAssaultIntegration extends CPUAssaultIntegration {} - - @SpringBootTest( - classes = ChaosDemoApplication.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = { - "management.endpoints.web.exposure.include=chaosmonkey", - "management.endpoints.enabled-by-default=true", - "chaos.monkey.assaults.cpuActive=true", - "chaos.monkey.assaults.cpuLoadTargetFraction=0.8", - "chaos.monkey.assaults.cpuMillisecondsHoldLoad=5000", - "spring.profiles.active=chaos-monkey" - }) - static class HighCPUAssaultIntegration extends CPUAssaultIntegration {} - - @SpringBootTest( - classes = ChaosDemoApplication.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = { - "management.endpoints.web.exposure.include=chaosmonkey", - "management.endpoints.enabled-by-default=true", - "chaos.monkey.assaults.cpuActive=true", - "chaos.monkey.assaults.cpuLoadTargetFraction=1.0", - "chaos.monkey.assaults.cpuMillisecondsHoldLoad=5000", - "spring.profiles.active=chaos-monkey" - }) - static class MaxCPUAssaultIntegration extends CPUAssaultIntegration {} - - @Autowired private CpuAssault cpuAssault; - - @Autowired private ChaosMonkeySettings settings; - - @NotNull private boolean isCpuAssaultActiveOriginal; - - @NotNull private double cpuLoadTargetFraction; - - @BeforeEach - void setUp() { - isCpuAssaultActiveOriginal = settings.getAssaultProperties().isCpuActive(); - cpuLoadTargetFraction = settings.getAssaultProperties().getCpuLoadTargetFraction(); - } - - @AfterEach - void tearDown() { - settings.getAssaultProperties().setCpuActive(isCpuAssaultActiveOriginal); - } - - @Test - void cpuAssault_configured() { - assertNotNull(cpuAssault); - assertTrue(cpuAssault.isActive()); - } - - @Test - void runAttack() { - OperatingSystemMXBean os = ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class); - long start = System.nanoTime(); - - Thread backgroundThread = new Thread(cpuAssault::attack); - backgroundThread.start(); - - // make sure we timeout if we never reach the target fill fraction - while (System.nanoTime() - start < TimeUnit.SECONDS.toNanos(30)) { - // if we reach target approximately (cpu filled up - // correctly) check if it is still held after some time (and not just passed) - if (isInRange(os.getProcessCpuLoad(), cpuLoadTargetFraction, 0.05)) { - try { - Thread.sleep(2000); - } catch (InterruptedException ignored) { + @SpringBootTest(classes = ChaosDemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { + "management.endpoints.web.exposure.include=chaosmonkey", "management.endpoints.enabled-by-default=true", + "chaos.monkey.assaults.cpuActive=true", "chaos.monkey.assaults.cpuLoadTargetFraction=0.3", + "chaos.monkey.assaults.cpuMillisecondsHoldLoad=5000", "spring.profiles.active=chaos-monkey"}) + static class LowCPUAssaultIntegration extends CPUAssaultIntegration { + } + + @SpringBootTest(classes = ChaosDemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { + "management.endpoints.web.exposure.include=chaosmonkey", "management.endpoints.enabled-by-default=true", + "chaos.monkey.assaults.cpuActive=true", "chaos.monkey.assaults.cpuLoadTargetFraction=0.8", + "chaos.monkey.assaults.cpuMillisecondsHoldLoad=5000", "spring.profiles.active=chaos-monkey"}) + static class HighCPUAssaultIntegration extends CPUAssaultIntegration { + } + + @SpringBootTest(classes = ChaosDemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { + "management.endpoints.web.exposure.include=chaosmonkey", "management.endpoints.enabled-by-default=true", + "chaos.monkey.assaults.cpuActive=true", "chaos.monkey.assaults.cpuLoadTargetFraction=1.0", + "chaos.monkey.assaults.cpuMillisecondsHoldLoad=5000", "spring.profiles.active=chaos-monkey"}) + static class MaxCPUAssaultIntegration extends CPUAssaultIntegration { + } + + @Autowired + private CpuAssault cpuAssault; + + @Autowired + private ChaosMonkeySettings settings; + + @NotNull + private boolean isCpuAssaultActiveOriginal; + + @NotNull + private double cpuLoadTargetFraction; + + @BeforeEach + void setUp() { + isCpuAssaultActiveOriginal = settings.getAssaultProperties().isCpuActive(); + cpuLoadTargetFraction = settings.getAssaultProperties().getCpuLoadTargetFraction(); + } + + @AfterEach + void tearDown() { + settings.getAssaultProperties().setCpuActive(isCpuAssaultActiveOriginal); + } + + @Test + void cpuAssault_configured() { + assertNotNull(cpuAssault); + assertTrue(cpuAssault.isActive()); + } + + @Test + void runAttack() { + OperatingSystemMXBean os = ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class); + long start = System.nanoTime(); + + Thread backgroundThread = new Thread(cpuAssault::attack); + backgroundThread.start(); + + // make sure we timeout if we never reach the target fill fraction + while (System.nanoTime() - start < TimeUnit.SECONDS.toNanos(30)) { + // if we reach target approximately (cpu filled up + // correctly) check if it is still held after some time (and not just passed) + if (isInRange(os.getProcessCpuLoad(), cpuLoadTargetFraction, 0.05)) { + try { + Thread.sleep(2000); + } catch (InterruptedException ignored) { + } + assertTrue(isInRange(os.getProcessCpuLoad(), cpuLoadTargetFraction, 0.05), + String.format("Failed to hold CPU load. Was %.2f %% but should have been %.2f %%", os.getProcessCpuLoad() * 100, + cpuLoadTargetFraction * 100)); + return; + } + // have to wait between checks to make sure the test thread doesn't generate too + // much load + try { + Thread.sleep(100); + } catch (InterruptedException ignored) { + } } - assertTrue( - isInRange(os.getProcessCpuLoad(), cpuLoadTargetFraction, 0.05), - String.format( - "Failed to hold CPU load. Was %.2f %% but should have been %.2f %%", - os.getProcessCpuLoad() * 100, cpuLoadTargetFraction * 100)); - return; - } - // have to wait between checks to make sure the test thread doesn't generate too much load - try { - Thread.sleep(100); - } catch (InterruptedException ignored) { - } + + // if timeout reached + fail(String.format("CPU did not fill up in time. Filled %.2f %% but should have filled %.2f %%", os.getProcessCpuLoad() * 100, + cpuLoadTargetFraction * 100)); } - // if timeout reached - fail( - String.format( - "CPU did not fill up in time. Filled %.2f %% but should have filled %.2f %%", - os.getProcessCpuLoad() * 100, cpuLoadTargetFraction * 100)); - } - - /** - * Checks if `value` is in range of designated `target`, depending on given `deviationFactor` - * - * @param value value to check against target if its in range - * @param deviationFactor factor in percentage (10% = 0.1) of how much value is allowed to deviate - * from target - * @param target value against value is checked against - * @return true if in range - */ - private boolean isInRange(double value, double target, double deviationFactor) { - double deviation = target * deviationFactor; - double lowerBoundary = Math.max(target - deviation, 0); - double upperBoundary = Math.max(target + deviation, 1); - - return value >= lowerBoundary && value <= upperBoundary; - } + /** + * Checks if `value` is in range of designated `target`, depending on given + * `deviationFactor` + * + * @param value + * value to check against target if its in range + * @param deviationFactor + * factor in percentage (10% = 0.1) of how much value is allowed to + * deviate from target + * @param target + * value against value is checked against + * @return true if in range + */ + private boolean isInRange(double value, double target, double deviationFactor) { + double deviation = target * deviationFactor; + double lowerBoundary = Math.max(target - deviation, 0); + double upperBoundary = Math.max(target + deviation, 1); + + return value >= lowerBoundary && value <= upperBoundary; + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/ExceptionAssaultTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/ExceptionAssaultTest.java index a3967974..a53f5862 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/ExceptionAssaultTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/ExceptionAssaultTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.assaults; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -30,123 +29,109 @@ /** @author Thorsten Deelmann */ class ExceptionAssaultTest { - @Mock MetricEventPublisher metricsMock; - - @Test - void throwsRuntimeExceptionWithDefaultAssaultSettings() { - ExceptionAssault exceptionAssault = new ExceptionAssault(getChaosMonkeySettings(), metricsMock); - assertThrows(RuntimeException.class, exceptionAssault::attack); - } - - @Test - void throwsRuntimeExceptionWithNullTypeAndNullArgument() { - ChaosMonkeySettings settings = getChaosMonkeySettings(); - settings.getAssaultProperties().setException(null); - ExceptionAssault exceptionAssault = new ExceptionAssault(settings, metricsMock); - assertThrows(RuntimeException.class, exceptionAssault::attack); - } - - @Test - void throwsDefaultRuntimeExceptionWithNullTypeAndNonNullArgument() { - String exceptionArgumentClassName = "java.lang.String"; - String exceptionArgumentValue = "Chaos Monkey - RuntimeException"; - - ChaosMonkeySettings settings = getChaosMonkeySettings(); - settings - .getAssaultProperties() - .setException( - getAssaultException(null, exceptionArgumentClassName, exceptionArgumentValue)); - - ExceptionAssault exceptionAssault = new ExceptionAssault(settings, metricsMock); - assertThrows(RuntimeException.class, exceptionAssault::attack, exceptionArgumentValue); - } - - @Test - void throwsRuntimeExceptionWithNonNullTypeAndNullArgument() { - ChaosMonkeySettings settings = getChaosMonkeySettings(); - settings - .getAssaultProperties() - .setException(getAssaultException("java.lang.ArithmeticException", null, null)); - - ExceptionAssault exceptionAssault = new ExceptionAssault(settings, metricsMock); - assertThrows(ArithmeticException.class, exceptionAssault::attack); - } - - @Test - void throwsRuntimeExceptionWithNonnullTypeAndNonNullArgument() { - String exceptionArgumentClassName = "java.lang.String"; - String exceptionArgumentValue = "ArithmeticException Test"; - - ChaosMonkeySettings settings = getChaosMonkeySettings(); - settings - .getAssaultProperties() - .setException( - getAssaultException( - "java.lang.ArithmeticException", - exceptionArgumentClassName, - exceptionArgumentValue)); - - ExceptionAssault exceptionAssault = new ExceptionAssault(settings, metricsMock); - assertThrows(ArithmeticException.class, exceptionAssault::attack, exceptionArgumentValue); - } - - @Test - void throwsGeneralException() { - ChaosMonkeySettings settings = getChaosMonkeySettings(); - settings - .getAssaultProperties() - .setException(getAssaultException("java.io.IOException", null, null)); - - ExceptionAssault exceptionAssault = new ExceptionAssault(settings, metricsMock); - assertThrows(IOException.class, exceptionAssault::attack); - } - - @Test - void throwsError() { - ChaosMonkeySettings settings = getChaosMonkeySettings(); - settings - .getAssaultProperties() - .setException(getAssaultException("java.lang.OutOfMemoryError", null, null)); - - ExceptionAssault exceptionAssault = new ExceptionAssault(settings, metricsMock); - assertThrows(OutOfMemoryError.class, exceptionAssault::attack); - } - - private ChaosMonkeySettings getChaosMonkeySettings() { - ChaosMonkeySettings settings = new ChaosMonkeySettings(); - settings.setAssaultProperties(getDefaultAssaultProperties()); - return settings; - } - - private AssaultProperties getDefaultAssaultProperties() { - AssaultProperties assaultProperties = new AssaultProperties(); - assaultProperties.setLevel(5); - assaultProperties.setLatencyRangeStart(1000); - assaultProperties.setLatencyRangeEnd(3000); - assaultProperties.setLatencyActive(true); - assaultProperties.setExceptionsActive(false); - assaultProperties.setException(getAssaultException(null, null, null)); - assaultProperties.setKillApplicationActive(false); - assaultProperties.setWatchedCustomServices(null); - - return assaultProperties; - } - - private AssaultException getAssaultException( - String exceptionClassName, String argumentClass, String argumentValue) { - AssaultException assaultException = new AssaultException(); - - if (exceptionClassName != null) { - assaultException.setType(exceptionClassName); + @Mock + MetricEventPublisher metricsMock; + + @Test + void throwsRuntimeExceptionWithDefaultAssaultSettings() { + ExceptionAssault exceptionAssault = new ExceptionAssault(getChaosMonkeySettings(), metricsMock); + assertThrows(RuntimeException.class, exceptionAssault::attack); + } + + @Test + void throwsRuntimeExceptionWithNullTypeAndNullArgument() { + ChaosMonkeySettings settings = getChaosMonkeySettings(); + settings.getAssaultProperties().setException(null); + ExceptionAssault exceptionAssault = new ExceptionAssault(settings, metricsMock); + assertThrows(RuntimeException.class, exceptionAssault::attack); + } + + @Test + void throwsDefaultRuntimeExceptionWithNullTypeAndNonNullArgument() { + String exceptionArgumentClassName = "java.lang.String"; + String exceptionArgumentValue = "Chaos Monkey - RuntimeException"; + + ChaosMonkeySettings settings = getChaosMonkeySettings(); + settings.getAssaultProperties().setException(getAssaultException(null, exceptionArgumentClassName, exceptionArgumentValue)); + + ExceptionAssault exceptionAssault = new ExceptionAssault(settings, metricsMock); + assertThrows(RuntimeException.class, exceptionAssault::attack, exceptionArgumentValue); } - if (argumentClass != null) { - AssaultException.ExceptionArgument argument = new AssaultException.ExceptionArgument(); - argument.setType(argumentClass); - argument.setValue(argumentValue); - assaultException.setArguments(Collections.singletonList(argument)); + @Test + void throwsRuntimeExceptionWithNonNullTypeAndNullArgument() { + ChaosMonkeySettings settings = getChaosMonkeySettings(); + settings.getAssaultProperties().setException(getAssaultException("java.lang.ArithmeticException", null, null)); + + ExceptionAssault exceptionAssault = new ExceptionAssault(settings, metricsMock); + assertThrows(ArithmeticException.class, exceptionAssault::attack); } - return assaultException; - } + @Test + void throwsRuntimeExceptionWithNonnullTypeAndNonNullArgument() { + String exceptionArgumentClassName = "java.lang.String"; + String exceptionArgumentValue = "ArithmeticException Test"; + + ChaosMonkeySettings settings = getChaosMonkeySettings(); + settings.getAssaultProperties() + .setException(getAssaultException("java.lang.ArithmeticException", exceptionArgumentClassName, exceptionArgumentValue)); + + ExceptionAssault exceptionAssault = new ExceptionAssault(settings, metricsMock); + assertThrows(ArithmeticException.class, exceptionAssault::attack, exceptionArgumentValue); + } + + @Test + void throwsGeneralException() { + ChaosMonkeySettings settings = getChaosMonkeySettings(); + settings.getAssaultProperties().setException(getAssaultException("java.io.IOException", null, null)); + + ExceptionAssault exceptionAssault = new ExceptionAssault(settings, metricsMock); + assertThrows(IOException.class, exceptionAssault::attack); + } + + @Test + void throwsError() { + ChaosMonkeySettings settings = getChaosMonkeySettings(); + settings.getAssaultProperties().setException(getAssaultException("java.lang.OutOfMemoryError", null, null)); + + ExceptionAssault exceptionAssault = new ExceptionAssault(settings, metricsMock); + assertThrows(OutOfMemoryError.class, exceptionAssault::attack); + } + + private ChaosMonkeySettings getChaosMonkeySettings() { + ChaosMonkeySettings settings = new ChaosMonkeySettings(); + settings.setAssaultProperties(getDefaultAssaultProperties()); + return settings; + } + + private AssaultProperties getDefaultAssaultProperties() { + AssaultProperties assaultProperties = new AssaultProperties(); + assaultProperties.setLevel(5); + assaultProperties.setLatencyRangeStart(1000); + assaultProperties.setLatencyRangeEnd(3000); + assaultProperties.setLatencyActive(true); + assaultProperties.setExceptionsActive(false); + assaultProperties.setException(getAssaultException(null, null, null)); + assaultProperties.setKillApplicationActive(false); + assaultProperties.setWatchedCustomServices(null); + + return assaultProperties; + } + + private AssaultException getAssaultException(String exceptionClassName, String argumentClass, String argumentValue) { + AssaultException assaultException = new AssaultException(); + + if (exceptionClassName != null) { + assaultException.setType(exceptionClassName); + } + + if (argumentClass != null) { + AssaultException.ExceptionArgument argument = new AssaultException.ExceptionArgument(); + argument.setType(argumentClass); + argument.setValue(argumentValue); + assaultException.setArguments(Collections.singletonList(argument)); + } + + return assaultException; + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/KillAppAssaultTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/KillAppAssaultTest.java index 6c5dca63..e7ab42c0 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/KillAppAssaultTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/KillAppAssaultTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.assaults; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -37,36 +36,33 @@ @ExtendWith(MockitoExtension.class) class KillAppAssaultTest { - @Mock private Appender mockAppender; + @Mock + private Appender mockAppender; - @Captor private ArgumentCaptor captorLoggingEvent; + @Captor + private ArgumentCaptor captorLoggingEvent; - @Mock private MetricEventPublisher metricsMock; + @Mock + private MetricEventPublisher metricsMock; - @BeforeEach - void setUp() { - ch.qos.logback.classic.Logger root = - (ch.qos.logback.classic.Logger) - LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME); - root.addAppender(mockAppender); + @BeforeEach + void setUp() { + ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME); + root.addAppender(mockAppender); - captorLoggingEvent = ArgumentCaptor.forClass(LoggingEvent.class); - } + captorLoggingEvent = ArgumentCaptor.forClass(LoggingEvent.class); + } - @Test - void killsSpringBootApplication() { - KillAppAssault killAppAssault = new KillAppAssault(null, metricsMock); - killAppAssault.attack(); + @Test + void killsSpringBootApplication() { + KillAppAssault killAppAssault = new KillAppAssault(null, metricsMock); + killAppAssault.attack(); - verify(mockAppender, times(2)).doAppend(captorLoggingEvent.capture()); + verify(mockAppender, times(2)).doAppend(captorLoggingEvent.capture()); - assertEquals(Level.INFO, captorLoggingEvent.getAllValues().get(0).getLevel()); - assertEquals(Level.INFO, captorLoggingEvent.getAllValues().get(1).getLevel()); - assertEquals( - "Chaos Monkey - I am killing your Application!", - captorLoggingEvent.getAllValues().get(0).getMessage()); - assertEquals( - "Chaos Monkey - Unable to kill the App, I am not the BOSS!", - captorLoggingEvent.getAllValues().get(1).getMessage()); - } + assertEquals(Level.INFO, captorLoggingEvent.getAllValues().get(0).getLevel()); + assertEquals(Level.INFO, captorLoggingEvent.getAllValues().get(1).getLevel()); + assertEquals("Chaos Monkey - I am killing your Application!", captorLoggingEvent.getAllValues().get(0).getMessage()); + assertEquals("Chaos Monkey - Unable to kill the App, I am not the BOSS!", captorLoggingEvent.getAllValues().get(1).getMessage()); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/LatencyAssaultRangeTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/LatencyAssaultRangeTest.java index 9f9a30b5..4e9200ac 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/LatencyAssaultRangeTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/LatencyAssaultRangeTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2019-2022 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 + * + * https://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.spring.boot.chaos.monkey.assaults; import static org.assertj.core.api.Assertions.assertThat; @@ -26,45 +41,42 @@ @ExtendWith(MockitoExtension.class) class LatencyAssaultRangeTest { - @Captor private ArgumentCaptor captorTimeoutValue; + @Captor + private ArgumentCaptor captorTimeoutValue; - @Test - void fixedLatencyIsPossible() { - final int fixedLatency = 1000; + @Test + void fixedLatencyIsPossible() { + final int fixedLatency = 1000; - assertThatLatencyConfiguration(fixedLatency, fixedLatency).isEqualTo(fixedLatency); - } + assertThatLatencyConfiguration(fixedLatency, fixedLatency).isEqualTo(fixedLatency); + } - @Test - void latencyRangeIsPossible() { - final int latencyRangeStart = 1000; - final int latencyRangeEnd = 5000; + @Test + void latencyRangeIsPossible() { + final int latencyRangeStart = 1000; + final int latencyRangeEnd = 5000; - assertThatLatencyConfiguration(latencyRangeStart, latencyRangeEnd) - .isBetween(latencyRangeStart, latencyRangeEnd); - } + assertThatLatencyConfiguration(latencyRangeStart, latencyRangeEnd).isBetween(latencyRangeStart, latencyRangeEnd); + } - private AbstractIntegerAssert assertThatLatencyConfiguration( - int latencyRangeStart, int latencyRangeEnd) { - final AssaultProperties assaultProperties = new AssaultProperties(); - assaultProperties.setLatencyRangeStart(latencyRangeStart); - assaultProperties.setLatencyRangeEnd(latencyRangeEnd); + private AbstractIntegerAssert assertThatLatencyConfiguration(int latencyRangeStart, int latencyRangeEnd) { + final AssaultProperties assaultProperties = new AssaultProperties(); + assaultProperties.setLatencyRangeStart(latencyRangeStart); + assaultProperties.setLatencyRangeEnd(latencyRangeEnd); - final ChaosMonkeySettings chaosMonkeySettings = mock(ChaosMonkeySettings.class); - when(chaosMonkeySettings.getAssaultProperties()).thenReturn(assaultProperties); + final ChaosMonkeySettings chaosMonkeySettings = mock(ChaosMonkeySettings.class); + when(chaosMonkeySettings.getAssaultProperties()).thenReturn(assaultProperties); - final ApplicationEventPublisher publisher = mock(ApplicationEventPublisher.class); - doNothing().when(publisher).publishEvent(any(ApplicationEvent.class)); + final ApplicationEventPublisher publisher = mock(ApplicationEventPublisher.class); + doNothing().when(publisher).publishEvent(any(ApplicationEvent.class)); - final MetricEventPublisher metricEventPublisher = spy(new MetricEventPublisher()); - metricEventPublisher.setApplicationEventPublisher(publisher); + final MetricEventPublisher metricEventPublisher = spy(new MetricEventPublisher()); + metricEventPublisher.setApplicationEventPublisher(publisher); - final LatencyAssault latencyAssault = - new LatencyAssault(chaosMonkeySettings, metricEventPublisher); - latencyAssault.attack(); + final LatencyAssault latencyAssault = new LatencyAssault(chaosMonkeySettings, metricEventPublisher); + latencyAssault.attack(); - verify(metricEventPublisher) - .publishMetricEvent(eq(MetricType.LATENCY_ASSAULT), captorTimeoutValue.capture()); - return assertThat(captorTimeoutValue.getValue().get()); - } + verify(metricEventPublisher).publishMetricEvent(eq(MetricType.LATENCY_ASSAULT), captorTimeoutValue.capture()); + return assertThat(captorTimeoutValue.getValue().get()); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/LatencyAssaultTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/LatencyAssaultTest.java index 4b933f6a..39bc009e 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/LatencyAssaultTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/LatencyAssaultTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.assaults; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -30,44 +29,46 @@ @ExtendWith(MockitoExtension.class) class LatencyAssaultTest { - @Mock private ChaosMonkeySettings chaosMonkeySettings; + @Mock + private ChaosMonkeySettings chaosMonkeySettings; - @Mock private AssaultProperties assaultProperties; + @Mock + private AssaultProperties assaultProperties; - @Test - void threadSleepHasBeenCalled() { - int latencyRangeStart = 100; - int latencyRangeEnd = 200; - TestLatencyAssaultExecutor executor = new TestLatencyAssaultExecutor(); + @Test + void threadSleepHasBeenCalled() { + int latencyRangeStart = 100; + int latencyRangeEnd = 200; + TestLatencyAssaultExecutor executor = new TestLatencyAssaultExecutor(); - when(assaultProperties.getLatencyRangeStart()).thenReturn(latencyRangeStart); - when(assaultProperties.getLatencyRangeEnd()).thenReturn(latencyRangeEnd); - when(chaosMonkeySettings.getAssaultProperties()).thenReturn(assaultProperties); + when(assaultProperties.getLatencyRangeStart()).thenReturn(latencyRangeStart); + when(assaultProperties.getLatencyRangeEnd()).thenReturn(latencyRangeEnd); + when(chaosMonkeySettings.getAssaultProperties()).thenReturn(assaultProperties); - LatencyAssault latencyAssault = new LatencyAssault(chaosMonkeySettings, null, executor); - latencyAssault.attack(); + LatencyAssault latencyAssault = new LatencyAssault(chaosMonkeySettings, null, executor); + latencyAssault.attack(); - assertTrue(executor.executed); - String assertionMessage = "Latency not in range 100-200, actual latency: " + executor.duration; - assertTrue(executor.duration >= latencyRangeStart, assertionMessage); - assertTrue(executor.duration <= latencyRangeEnd, assertionMessage); - } + assertTrue(executor.executed); + String assertionMessage = "Latency not in range 100-200, actual latency: " + executor.duration; + assertTrue(executor.duration >= latencyRangeStart, assertionMessage); + assertTrue(executor.duration <= latencyRangeEnd, assertionMessage); + } - class TestLatencyAssaultExecutor implements ChaosMonkeyLatencyAssaultExecutor { + class TestLatencyAssaultExecutor implements ChaosMonkeyLatencyAssaultExecutor { - private long duration; + private long duration; - private boolean executed; + private boolean executed; - TestLatencyAssaultExecutor() { - this.duration = 0; - this.executed = false; - } + TestLatencyAssaultExecutor() { + this.duration = 0; + this.executed = false; + } - @Override - public void execute(long duration) { - this.duration = duration; - this.executed = true; + @Override + public void execute(long duration) { + this.duration = duration; + this.executed = true; + } } - } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/MemoryAssaultIntegrationTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/MemoryAssaultIntegrationTest.java index 1793c36b..024df9b1 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/MemoryAssaultIntegrationTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/assaults/MemoryAssaultIntegrationTest.java @@ -1,20 +1,18 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2018-2022 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 + * https://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.spring.boot.chaos.monkey.assaults; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -38,181 +36,167 @@ import org.springframework.http.ResponseEntity; /** @author Benjamin Wilms */ -@SpringBootTest( - classes = ChaosDemoApplication.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = { - "management.endpoints.web.exposure.include=chaosmonkey", - "management.endpoints.enabled-by-default=true", - "chaos.monkey.assaults.memoryActive=true", - "chaos.monkey.assaults.memoryFillTargetFraction=0.80", - "chaos.monkey.assaults.memoryMillisecondsWaitNextIncrease=100", - "chaos.monkey.assaults.memoryFillIncrementFraction=0.99", - "chaos.monkey.assaults.memoryMillisecondsHoldFilledMemory=2000", - "spring.profiles.active=chaos-monkey" - }) +@SpringBootTest(classes = ChaosDemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { + "management.endpoints.web.exposure.include=chaosmonkey", "management.endpoints.enabled-by-default=true", + "chaos.monkey.assaults.memoryActive=true", "chaos.monkey.assaults.memoryFillTargetFraction=0.80", + "chaos.monkey.assaults.memoryMillisecondsWaitNextIncrease=100", "chaos.monkey.assaults.memoryFillIncrementFraction=0.99", + "chaos.monkey.assaults.memoryMillisecondsHoldFilledMemory=2000", "spring.profiles.active=chaos-monkey"}) class MemoryAssaultIntegrationTest { - @LocalServerPort private int serverPort; + @LocalServerPort + private int serverPort; - private String baseUrl; + private String baseUrl; - @Autowired private TestRestTemplate restTemplate; + @Autowired + private TestRestTemplate restTemplate; - @Autowired private MemoryAssault memoryAssault; + @Autowired + private MemoryAssault memoryAssault; - @Autowired private ChaosMonkeySettings settings; + @Autowired + private ChaosMonkeySettings settings; - @NotNull private boolean isMemoryAssaultActiveOriginal; + @NotNull + private boolean isMemoryAssaultActiveOriginal; - @NotNull private double memoryFillTargetFraction; + @NotNull + private double memoryFillTargetFraction; - @BeforeEach - void setUp() { - isMemoryAssaultActiveOriginal = settings.getAssaultProperties().isMemoryActive(); - memoryFillTargetFraction = settings.getAssaultProperties().getMemoryFillTargetFraction(); - baseUrl = "http://localhost:" + this.serverPort + "/actuator/chaosmonkey"; - } - - @AfterEach - void tearDown() { - settings.getAssaultProperties().setMemoryActive(isMemoryAssaultActiveOriginal); - } + @BeforeEach + void setUp() { + isMemoryAssaultActiveOriginal = settings.getAssaultProperties().isMemoryActive(); + memoryFillTargetFraction = settings.getAssaultProperties().getMemoryFillTargetFraction(); + baseUrl = "http://localhost:" + this.serverPort + "/actuator/chaosmonkey"; + } - @Test - void memoryAssault_configured() { - assertNotNull(memoryAssault); - assertTrue(memoryAssault.isActive()); - } + @AfterEach + void tearDown() { + settings.getAssaultProperties().setMemoryActive(isMemoryAssaultActiveOriginal); + } - @Test - void runAttack() { - Runtime rt = Runtime.getRuntime(); - long start = System.nanoTime(); + @Test + void memoryAssault_configured() { + assertNotNull(memoryAssault); + assertTrue(memoryAssault.isActive()); + } - Thread backgroundThread = new Thread(memoryAssault::attack); - backgroundThread.start(); + @Test + void runAttack() { + Runtime rt = Runtime.getRuntime(); + long start = System.nanoTime(); + + Thread backgroundThread = new Thread(memoryAssault::attack); + backgroundThread.start(); + + // make sure we timeout if we never reach the target fill fraction + while (System.nanoTime() - start < TimeUnit.SECONDS.toNanos(30)) { + // if we reach target approximately (memory filled up + // correctly) we can return (test is successful) + double target = rt.maxMemory() * memoryFillTargetFraction; + if (isInRange(rt.totalMemory(), target, 0.2)) { + return; + } + } - // make sure we timeout if we never reach the target fill fraction - while (System.nanoTime() - start < TimeUnit.SECONDS.toNanos(30)) { - // if we reach target approximately (memory filled up - // correctly) we can return (test is successful) - double target = rt.maxMemory() * memoryFillTargetFraction; - if (isInRange(rt.totalMemory(), target, 0.2)) { - return; - } + // if timeout reached + fail("Memory did not fill up in time. Filled " + SizeConverter.toMegabytes(rt.totalMemory()) + " MB but should have filled " + + SizeConverter.toMegabytes(rt.maxMemory() * memoryFillTargetFraction) + " MB"); } - // if timeout reached - fail( - "Memory did not fill up in time. Filled " - + SizeConverter.toMegabytes(rt.totalMemory()) - + " MB but should have filled " - + SizeConverter.toMegabytes(rt.maxMemory() * memoryFillTargetFraction) - + " MB"); - } - - /** - * Checks if `value` is in range of designated `target`, depending on given `deviationFactor` - * - * @param value value to check against target if its in range - * @param deviationFactor factor in percentage (10% = 0.1) of how much value is allowed to deviate - * from target - * @param target value against value is checked against - * @return true if in range - */ - private boolean isInRange(double value, double target, double deviationFactor) { - double deviation = target * deviationFactor; - double lowerBoundary = Math.max(target - deviation, 0); - double upperBoundary = Math.max(target + deviation, Runtime.getRuntime().maxMemory()); - - return value >= lowerBoundary && value <= upperBoundary; - } - - @SuppressWarnings("StatementWithEmptyBody") - @Test - void runAndAbortAttack() throws Throwable { - AssaultPropertiesUpdate assaultProperties = new AssaultPropertiesUpdate(); - assaultProperties.setMemoryActive(false); - - Runtime rt = Runtime.getRuntime(); - long start = System.nanoTime(); - - long usedMemoryBeforeAttack = rt.totalMemory() - rt.freeMemory(); - Thread backgroundThread = new Thread(memoryAssault::attack); - - backgroundThread.start(); - Thread.sleep(100); - long usedMemoryDuringAttack = rt.totalMemory() - rt.freeMemory(); - - assertTrue(usedMemoryBeforeAttack <= usedMemoryDuringAttack); - - ResponseEntity result = - restTemplate.postForEntity(baseUrl + "/assaults", assaultProperties, String.class); - assertEquals(200, result.getStatusCodeValue()); - - while (backgroundThread.isAlive() && System.nanoTime() - start < TimeUnit.SECONDS.toNanos(30)) { - // wait for thread to finish gracefully or time out + /** + * Checks if `value` is in range of designated `target`, depending on given + * `deviationFactor` + * + * @param value + * value to check against target if its in range + * @param deviationFactor + * factor in percentage (10% = 0.1) of how much value is allowed to + * deviate from target + * @param target + * value against value is checked against + * @return true if in range + */ + private boolean isInRange(double value, double target, double deviationFactor) { + double deviation = target * deviationFactor; + double lowerBoundary = Math.max(target - deviation, 0); + double upperBoundary = Math.max(target + deviation, Runtime.getRuntime().maxMemory()); + + return value >= lowerBoundary && value <= upperBoundary; } - assertFalse("Assault is still running", backgroundThread.isAlive()); - - // TODO: Check again when JAVA 8 can be dropped. - // Apparently java 8 needs a bit more time to finish up things - Thread.sleep(1000); - - long usedMemoryAfterAttack = rt.totalMemory() - rt.freeMemory(); - - // garbage collection should have ran by now - assertTrue( - usedMemoryAfterAttack <= usedMemoryDuringAttack, - "Memory after attack was " - + SizeConverter.toMegabytes(usedMemoryAfterAttack) - + " MB but should have been less amount of memory during attack (" - + SizeConverter.toMegabytes(usedMemoryDuringAttack) - + " MB)."); - } - - @Test - void allowInterruptionOfAssaultDuringHoldPeriod() throws Throwable { - AssaultPropertiesUpdate assaultProperties = new AssaultPropertiesUpdate(); - assaultProperties.setMemoryActive(false); - - Runtime rt = Runtime.getRuntime(); - long start = System.nanoTime(); - - Thread backgroundThread = new Thread(memoryAssault::attack); - assertFalse("Assault already active", backgroundThread.isAlive()); - - backgroundThread.start(); - assertTrue(backgroundThread.isAlive(), "Assault not active"); - - outer: - { - double fillTargetMemory = rt.maxMemory() * memoryFillTargetFraction; - while (System.nanoTime() - start < TimeUnit.SECONDS.toNanos(30)) { - long totalMemoryDuringAttack = rt.totalMemory(); - if (isInRange(totalMemoryDuringAttack, fillTargetMemory, 0.2)) { - break outer; + @SuppressWarnings("StatementWithEmptyBody") + @Test + void runAndAbortAttack() throws Throwable { + AssaultPropertiesUpdate assaultProperties = new AssaultPropertiesUpdate(); + assaultProperties.setMemoryActive(false); + + Runtime rt = Runtime.getRuntime(); + long start = System.nanoTime(); + + long usedMemoryBeforeAttack = rt.totalMemory() - rt.freeMemory(); + Thread backgroundThread = new Thread(memoryAssault::attack); + + backgroundThread.start(); + Thread.sleep(100); + long usedMemoryDuringAttack = rt.totalMemory() - rt.freeMemory(); + + assertTrue(usedMemoryBeforeAttack <= usedMemoryDuringAttack); + + ResponseEntity result = restTemplate.postForEntity(baseUrl + "/assaults", assaultProperties, String.class); + assertEquals(200, result.getStatusCodeValue()); + + while (backgroundThread.isAlive() && System.nanoTime() - start < TimeUnit.SECONDS.toNanos(30)) { + // wait for thread to finish gracefully or time out } - } - - fail( - "Memory did not fill up in time. Filled " - + SizeConverter.toMegabytes(rt.totalMemory()) - + " MB but should have filled " - + SizeConverter.toMegabytes(fillTargetMemory) - + " MB"); + + assertFalse("Assault is still running", backgroundThread.isAlive()); + + // TODO: Check again when JAVA 8 can be dropped. + // Apparently java 8 needs a bit more time to finish up things + Thread.sleep(1000); + + long usedMemoryAfterAttack = rt.totalMemory() - rt.freeMemory(); + + // garbage collection should have ran by now + assertTrue(usedMemoryAfterAttack <= usedMemoryDuringAttack, "Memory after attack was " + SizeConverter.toMegabytes(usedMemoryAfterAttack) + + " MB but should have been less amount of memory during attack (" + SizeConverter.toMegabytes(usedMemoryDuringAttack) + " MB)."); } - ResponseEntity result = - restTemplate.postForEntity(baseUrl + "/assaults", assaultProperties, String.class); - assertEquals(200, result.getStatusCodeValue(), "Request was not successful"); + @Test + void allowInterruptionOfAssaultDuringHoldPeriod() throws Throwable { + AssaultPropertiesUpdate assaultProperties = new AssaultPropertiesUpdate(); + assaultProperties.setMemoryActive(false); + + Runtime rt = Runtime.getRuntime(); + long start = System.nanoTime(); + + Thread backgroundThread = new Thread(memoryAssault::attack); + assertFalse("Assault already active", backgroundThread.isAlive()); - // TODO: Check again when JAVA 8 can be dropped. - // Apparently java 8 needs a bit more time to finish up things - Thread.sleep(1000); + backgroundThread.start(); + assertTrue(backgroundThread.isAlive(), "Assault not active"); - assertFalse("Assault is still running", backgroundThread.isAlive()); - } + outer : { + double fillTargetMemory = rt.maxMemory() * memoryFillTargetFraction; + while (System.nanoTime() - start < TimeUnit.SECONDS.toNanos(30)) { + long totalMemoryDuringAttack = rt.totalMemory(); + if (isInRange(totalMemoryDuringAttack, fillTargetMemory, 0.2)) { + break outer; + } + } + + fail("Memory did not fill up in time. Filled " + SizeConverter.toMegabytes(rt.totalMemory()) + " MB but should have filled " + + SizeConverter.toMegabytes(fillTargetMemory) + " MB"); + } + + ResponseEntity result = restTemplate.postForEntity(baseUrl + "/assaults", assaultProperties, String.class); + assertEquals(200, result.getStatusCodeValue(), "Request was not successful"); + + // TODO: Check again when JAVA 8 can be dropped. + // Apparently java 8 needs a bit more time to finish up things + Thread.sleep(1000); + + assertFalse("Assault is still running", backgroundThread.isAlive()); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeyRequestScopeTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeyRequestScopeTest.java index e8c3b1d8..bdac739c 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeyRequestScopeTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeyRequestScopeTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.component; import static org.mockito.BDDMockito.given; @@ -43,273 +42,256 @@ @ExtendWith(MockitoExtension.class) class ChaosMonkeyRequestScopeTest { - ChaosMonkeyRequestScope chaosMonkeyRequestScope; + ChaosMonkeyRequestScope chaosMonkeyRequestScope; - @Mock AssaultProperties assaultProperties; + @Mock + AssaultProperties assaultProperties; - @Mock ChaosMonkeyProperties chaosMonkeyProperties; + @Mock + ChaosMonkeyProperties chaosMonkeyProperties; - @Mock ChaosMonkeySettings chaosMonkeySettings; + @Mock + ChaosMonkeySettings chaosMonkeySettings; - @Mock LatencyAssault latencyAssault; + @Mock + LatencyAssault latencyAssault; - @Mock ExceptionAssault exceptionAssault; + @Mock + ExceptionAssault exceptionAssault; - @Mock MetricEventPublisher metricEventPublisherMock; + @Mock + MetricEventPublisher metricEventPublisherMock; - @BeforeEach - void setUpCommon() { - given(chaosMonkeySettings.getChaosMonkeyProperties()).willReturn(chaosMonkeyProperties); + @BeforeEach + void setUpCommon() { + given(chaosMonkeySettings.getChaosMonkeyProperties()).willReturn(chaosMonkeyProperties); - chaosMonkeyRequestScope = - new ChaosMonkeyRequestScope( - chaosMonkeySettings, - Arrays.asList(latencyAssault, exceptionAssault), - Collections.emptyList(), - metricEventPublisherMock, - new DefaultChaosToggles(), - new DefaultChaosToggleNameMapper(chaosMonkeyProperties.getTogglePrefix())); - } + chaosMonkeyRequestScope = new ChaosMonkeyRequestScope(chaosMonkeySettings, Arrays.asList(latencyAssault, exceptionAssault), + Collections.emptyList(), metricEventPublisherMock, new DefaultChaosToggles(), + new DefaultChaosToggleNameMapper(chaosMonkeyProperties.getTogglePrefix())); + } - @Test - void givenChaosMonkeyExecutionIsDisabledExpectNoInteractions() { - given(chaosMonkeyProperties.isEnabled()).willReturn(false); + @Test + void givenChaosMonkeyExecutionIsDisabledExpectNoInteractions() { + given(chaosMonkeyProperties.isEnabled()).willReturn(false); - chaosMonkeyRequestScope.callChaosMonkey(null, null); + chaosMonkeyRequestScope.callChaosMonkey(null, null); - verify(latencyAssault, never()).attack(); - verify(exceptionAssault, never()).attack(); - } + verify(latencyAssault, never()).attack(); + verify(exceptionAssault, never()).attack(); + } - @Nested - class GivenChaosMonekyExecutionIsEnabled { + @Nested + class GivenChaosMonekyExecutionIsEnabled { - @BeforeEach - void setUpForChaosMonkeyExecutionEnabled() { - given(assaultProperties.getLevel()).willReturn(1); - given(assaultProperties.getTroubleRandom()).willReturn(1); - given(chaosMonkeyProperties.isEnabled()).willReturn(true); - given(chaosMonkeySettings.getAssaultProperties()).willReturn(assaultProperties); - } + @BeforeEach + void setUpForChaosMonkeyExecutionEnabled() { + given(assaultProperties.getLevel()).willReturn(1); + given(assaultProperties.getTroubleRandom()).willReturn(1); + given(chaosMonkeyProperties.isEnabled()).willReturn(true); + given(chaosMonkeySettings.getAssaultProperties()).willReturn(assaultProperties); + } - @Test - void allAssaultsActiveExpectLatencyAttack() { - given(exceptionAssault.isActive()).willReturn(true); - given(latencyAssault.isActive()).willReturn(true); - given(assaultProperties.chooseAssault(2)).willReturn(0); + @Test + void allAssaultsActiveExpectLatencyAttack() { + given(exceptionAssault.isActive()).willReturn(true); + given(latencyAssault.isActive()).willReturn(true); + given(assaultProperties.chooseAssault(2)).willReturn(0); - chaosMonkeyRequestScope.callChaosMonkey(null, null); + chaosMonkeyRequestScope.callChaosMonkey(null, null); - verify(latencyAssault, times(1)).attack(); - } + verify(latencyAssault, times(1)).attack(); + } - @Test - void allAssaultsActiveExpectExceptionAttack() { - given(exceptionAssault.isActive()).willReturn(true); - given(latencyAssault.isActive()).willReturn(true); - given(assaultProperties.chooseAssault(2)).willReturn(1); + @Test + void allAssaultsActiveExpectExceptionAttack() { + given(exceptionAssault.isActive()).willReturn(true); + given(latencyAssault.isActive()).willReturn(true); + given(assaultProperties.chooseAssault(2)).willReturn(1); - chaosMonkeyRequestScope.callChaosMonkey(null, null); + chaosMonkeyRequestScope.callChaosMonkey(null, null); - verify(exceptionAssault, times(1)).attack(); - } + verify(exceptionAssault, times(1)).attack(); + } - @Test - void isLatencyAssaultActive() { - given(latencyAssault.isActive()).willReturn(true); - given(exceptionAssault.isActive()).willReturn(false); + @Test + void isLatencyAssaultActive() { + given(latencyAssault.isActive()).willReturn(true); + given(exceptionAssault.isActive()).willReturn(false); - chaosMonkeyRequestScope.callChaosMonkey(null, null); + chaosMonkeyRequestScope.callChaosMonkey(null, null); - verify(latencyAssault, times(1)).attack(); - } + verify(latencyAssault, times(1)).attack(); + } - @Test - void isExceptionAssaultActive() { - given(exceptionAssault.isActive()).willReturn(true); - given(latencyAssault.isActive()).willReturn(false); + @Test + void isExceptionAssaultActive() { + given(exceptionAssault.isActive()).willReturn(true); + given(latencyAssault.isActive()).willReturn(false); - chaosMonkeyRequestScope.callChaosMonkey(null, null); + chaosMonkeyRequestScope.callChaosMonkey(null, null); - verify(exceptionAssault, times(1)).attack(); - } + verify(exceptionAssault, times(1)).attack(); + } - @Test - void isExceptionAndLatencyAssaultActiveExpectExceptionAttack() { - given(exceptionAssault.isActive()).willReturn(true); - given(latencyAssault.isActive()).willReturn(true); - given(assaultProperties.chooseAssault(2)).willReturn(1); + @Test + void isExceptionAndLatencyAssaultActiveExpectExceptionAttack() { + given(exceptionAssault.isActive()).willReturn(true); + given(latencyAssault.isActive()).willReturn(true); + given(assaultProperties.chooseAssault(2)).willReturn(1); - chaosMonkeyRequestScope.callChaosMonkey(null, null); + chaosMonkeyRequestScope.callChaosMonkey(null, null); - verify(exceptionAssault, times(1)).attack(); - } + verify(exceptionAssault, times(1)).attack(); + } - @Test - void isExceptionAndLatencyAssaultActiveExpectLatencyAttack() { + @Test + void isExceptionAndLatencyAssaultActiveExpectLatencyAttack() { - given(exceptionAssault.isActive()).willReturn(true); - given(latencyAssault.isActive()).willReturn(true); - given(assaultProperties.chooseAssault(2)).willReturn(0); + given(exceptionAssault.isActive()).willReturn(true); + given(latencyAssault.isActive()).willReturn(true); + given(assaultProperties.chooseAssault(2)).willReturn(0); - chaosMonkeyRequestScope.callChaosMonkey(null, null); + chaosMonkeyRequestScope.callChaosMonkey(null, null); - verify(latencyAssault, times(1)).attack(); - } + verify(latencyAssault, times(1)).attack(); + } - @Test - void isExceptionActiveExpectExceptionAttack() { - given(exceptionAssault.isActive()).willReturn(true); - given(latencyAssault.isActive()).willReturn(false); + @Test + void isExceptionActiveExpectExceptionAttack() { + given(exceptionAssault.isActive()).willReturn(true); + given(latencyAssault.isActive()).willReturn(false); - chaosMonkeyRequestScope.callChaosMonkey(null, null); + chaosMonkeyRequestScope.callChaosMonkey(null, null); - verify(exceptionAssault, times(1)).attack(); - } + verify(exceptionAssault, times(1)).attack(); + } - @Test - void isLatencyActiveExpectLatencyAttack() { - given(exceptionAssault.isActive()).willReturn(false); - given(latencyAssault.isActive()).willReturn(true); + @Test + void isLatencyActiveExpectLatencyAttack() { + given(exceptionAssault.isActive()).willReturn(false); + given(latencyAssault.isActive()).willReturn(true); - chaosMonkeyRequestScope.callChaosMonkey(null, null); + chaosMonkeyRequestScope.callChaosMonkey(null, null); - verify(latencyAssault, times(1)).attack(); - } + verify(latencyAssault, times(1)).attack(); + } - @Test - void givenNoAssaultsActiveExpectNoAttack() { - chaosMonkeyRequestScope.callChaosMonkey(null, null); + @Test + void givenNoAssaultsActiveExpectNoAttack() { + chaosMonkeyRequestScope.callChaosMonkey(null, null); - verify(latencyAssault, never()).attack(); - verify(exceptionAssault, never()).attack(); - } + verify(latencyAssault, never()).attack(); + verify(exceptionAssault, never()).attack(); + } - @Test - void givenAssaultLevelTooHighExpectNoLogging() { - given(assaultProperties.getLevel()).willReturn(1000); - given(assaultProperties.getTroubleRandom()).willReturn(9); + @Test + void givenAssaultLevelTooHighExpectNoLogging() { + given(assaultProperties.getLevel()).willReturn(1000); + given(assaultProperties.getTroubleRandom()).willReturn(9); - chaosMonkeyRequestScope.callChaosMonkey(null, null); + chaosMonkeyRequestScope.callChaosMonkey(null, null); - verify(latencyAssault, never()).attack(); - verify(exceptionAssault, never()).attack(); - } + verify(latencyAssault, never()).attack(); + verify(exceptionAssault, never()).attack(); + } - @Test - void chaosMonkeyIsNotCalledWhenServiceNotWatched() { - String customService = "CustomService"; + @Test + void chaosMonkeyIsNotCalledWhenServiceNotWatched() { + String customService = "CustomService"; - given(assaultProperties.getWatchedCustomServices()) - .willReturn(Collections.singletonList(customService)); - given(chaosMonkeySettings.getAssaultProperties().isWatchedCustomServicesActive()) - .willReturn(true); + given(assaultProperties.getWatchedCustomServices()).willReturn(Collections.singletonList(customService)); + given(chaosMonkeySettings.getAssaultProperties().isWatchedCustomServicesActive()).willReturn(true); - chaosMonkeyRequestScope.callChaosMonkey(null, "notInListService"); + chaosMonkeyRequestScope.callChaosMonkey(null, "notInListService"); - verify(latencyAssault, never()).attack(); - verify(exceptionAssault, never()).attack(); - } + verify(latencyAssault, never()).attack(); + verify(exceptionAssault, never()).attack(); + } - @Test - void chaosMonkeyIsCalledWhenServiceIsWatched() { - String customService = "CustomService"; + @Test + void chaosMonkeyIsCalledWhenServiceIsWatched() { + String customService = "CustomService"; - given(exceptionAssault.isActive()).willReturn(true); - given(assaultProperties.getWatchedCustomServices()) - .willReturn(Collections.singletonList(customService)); - given(chaosMonkeySettings.getAssaultProperties().isWatchedCustomServicesActive()) - .willReturn(true); - given(latencyAssault.isActive()).willReturn(true); - given(assaultProperties.chooseAssault(2)).willReturn(0); + given(exceptionAssault.isActive()).willReturn(true); + given(assaultProperties.getWatchedCustomServices()).willReturn(Collections.singletonList(customService)); + given(chaosMonkeySettings.getAssaultProperties().isWatchedCustomServicesActive()).willReturn(true); + given(latencyAssault.isActive()).willReturn(true); + given(assaultProperties.chooseAssault(2)).willReturn(0); - chaosMonkeyRequestScope.callChaosMonkey(null, customService); + chaosMonkeyRequestScope.callChaosMonkey(null, customService); - verify(latencyAssault, times(1)).attack(); - verify(exceptionAssault, never()).attack(); - } + verify(latencyAssault, times(1)).attack(); + verify(exceptionAssault, never()).attack(); + } - @Test - void chaosMonkeyIsCalledWhenServiceIsWatchedWhenSimpleNameIsMethodReference() { - String customRepository = "org.springframework.data.repository.CrudRepository"; - - given(exceptionAssault.isActive()).willReturn(true); - given(assaultProperties.getWatchedCustomServices()) - .willReturn(Collections.singletonList(customRepository)); - given(chaosMonkeySettings.getAssaultProperties().isWatchedCustomServicesActive()) - .willReturn(true); - given(latencyAssault.isActive()).willReturn(true); - given(assaultProperties.chooseAssault(2)).willReturn(0); - - String simpleName = customRepository + ".findAll"; - chaosMonkeyRequestScope.callChaosMonkey(null, simpleName); - - verify(latencyAssault, times(1)).attack(); - verify(exceptionAssault, never()).attack(); - } + @Test + void chaosMonkeyIsCalledWhenServiceIsWatchedWhenSimpleNameIsMethodReference() { + String customRepository = "org.springframework.data.repository.CrudRepository"; - @Test - void chaosMonkeyIsCalledWhenServiceIsWatchedWhenSimpleNameIsPackageReference() { - String packageName = "org.springframework.data.repository"; - - given(exceptionAssault.isActive()).willReturn(true); - given(assaultProperties.getWatchedCustomServices()) - .willReturn(Collections.singletonList(packageName)); - given(chaosMonkeySettings.getAssaultProperties().isWatchedCustomServicesActive()) - .willReturn(true); - given(latencyAssault.isActive()).willReturn(true); - given(assaultProperties.chooseAssault(2)).willReturn(0); - - String simpleName = packageName + "CrudRepository.findAll"; - chaosMonkeyRequestScope.callChaosMonkey(null, simpleName); - - verify(latencyAssault, times(1)).attack(); - verify(exceptionAssault, never()).attack(); + given(exceptionAssault.isActive()).willReturn(true); + given(assaultProperties.getWatchedCustomServices()).willReturn(Collections.singletonList(customRepository)); + given(chaosMonkeySettings.getAssaultProperties().isWatchedCustomServicesActive()).willReturn(true); + given(latencyAssault.isActive()).willReturn(true); + given(assaultProperties.chooseAssault(2)).willReturn(0); + + String simpleName = customRepository + ".findAll"; + chaosMonkeyRequestScope.callChaosMonkey(null, simpleName); + + verify(latencyAssault, times(1)).attack(); + verify(exceptionAssault, never()).attack(); + } + + @Test + void chaosMonkeyIsCalledWhenServiceIsWatchedWhenSimpleNameIsPackageReference() { + String packageName = "org.springframework.data.repository"; + + given(exceptionAssault.isActive()).willReturn(true); + given(assaultProperties.getWatchedCustomServices()).willReturn(Collections.singletonList(packageName)); + given(chaosMonkeySettings.getAssaultProperties().isWatchedCustomServicesActive()).willReturn(true); + given(latencyAssault.isActive()).willReturn(true); + given(assaultProperties.chooseAssault(2)).willReturn(0); + + String simpleName = packageName + "CrudRepository.findAll"; + chaosMonkeyRequestScope.callChaosMonkey(null, simpleName); + + verify(latencyAssault, times(1)).attack(); + verify(exceptionAssault, never()).attack(); + } + + @Test + void shouldMakeUncategorizedCustomAssaultsRequestScopeByDefault() { + // create an assault that is neither runtime nor request + ChaosMonkeyAssault customAssault = mock(ChaosMonkeyAssault.class); + given(customAssault.isActive()).willReturn(true); + ChaosMonkeyRequestScope customScope = new ChaosMonkeyRequestScope(chaosMonkeySettings, Collections.emptyList(), + Collections.singletonList(customAssault), metricEventPublisherMock, new DefaultChaosToggles(), + new DefaultChaosToggleNameMapper(chaosMonkeyProperties.getTogglePrefix())); + + customScope.callChaosMonkey(null, "foo"); + verify(customAssault).attack(); + } } @Test - void shouldMakeUncategorizedCustomAssaultsRequestScopeByDefault() { - // create an assault that is neither runtime nor request - ChaosMonkeyAssault customAssault = mock(ChaosMonkeyAssault.class); - given(customAssault.isActive()).willReturn(true); - ChaosMonkeyRequestScope customScope = - new ChaosMonkeyRequestScope( - chaosMonkeySettings, - Collections.emptyList(), - Collections.singletonList(customAssault), - metricEventPublisherMock, - new DefaultChaosToggles(), - new DefaultChaosToggleNameMapper(chaosMonkeyProperties.getTogglePrefix())); - - customScope.callChaosMonkey(null, "foo"); - verify(customAssault).attack(); + void assaultShouldBeDeterministicIfConfigured() { + ChaosMonkeyAssault customAssault = mock(ChaosMonkeyAssault.class); + given(customAssault.isActive()).willReturn(true); + given(chaosMonkeyProperties.isEnabled()).willReturn(true); + given(chaosMonkeySettings.getAssaultProperties()).willReturn(assaultProperties); + + given(assaultProperties.isDeterministic()).willReturn(true); + given(assaultProperties.getLevel()).willReturn(3); + + ChaosMonkeyRequestScope customScope = new ChaosMonkeyRequestScope(chaosMonkeySettings, Collections.emptyList(), + Collections.singletonList(customAssault), metricEventPublisherMock, new DefaultChaosToggles(), + new DefaultChaosToggleNameMapper(chaosMonkeyProperties.getTogglePrefix())); + + customScope.callChaosMonkey(null, "foo"); + verify(customAssault, never()).attack(); + customScope.callChaosMonkey(null, "foo"); + verify(customAssault, never()).attack(); + customScope.callChaosMonkey(null, "foo"); + verify(customAssault, times(1)).attack(); } - } - - @Test - void assaultShouldBeDeterministicIfConfigured() { - ChaosMonkeyAssault customAssault = mock(ChaosMonkeyAssault.class); - given(customAssault.isActive()).willReturn(true); - given(chaosMonkeyProperties.isEnabled()).willReturn(true); - given(chaosMonkeySettings.getAssaultProperties()).willReturn(assaultProperties); - - given(assaultProperties.isDeterministic()).willReturn(true); - given(assaultProperties.getLevel()).willReturn(3); - - ChaosMonkeyRequestScope customScope = - new ChaosMonkeyRequestScope( - chaosMonkeySettings, - Collections.emptyList(), - Collections.singletonList(customAssault), - metricEventPublisherMock, - new DefaultChaosToggles(), - new DefaultChaosToggleNameMapper(chaosMonkeyProperties.getTogglePrefix())); - - customScope.callChaosMonkey(null, "foo"); - verify(customAssault, never()).attack(); - customScope.callChaosMonkey(null, "foo"); - verify(customAssault, never()).attack(); - customScope.callChaosMonkey(null, "foo"); - verify(customAssault, times(1)).attack(); - } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeySchedulerTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeySchedulerTest.java index 6aff92d1..65538ae6 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeySchedulerTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/component/ChaosMonkeySchedulerTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2019-2022 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 + * + * https://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.spring.boot.chaos.monkey.component; import static org.mockito.ArgumentMatchers.any; @@ -22,112 +37,111 @@ @ExtendWith(MockitoExtension.class) class ChaosMonkeySchedulerTest { - @Mock private ScheduledTaskRegistrar registrar; + @Mock + private ScheduledTaskRegistrar registrar; - @Mock private AssaultProperties config; + @Mock + private AssaultProperties config; - @Mock private KillAppAssault killAppAssault; + @Mock + private KillAppAssault killAppAssault; - @Mock private MemoryAssault memoryAssault; + @Mock + private MemoryAssault memoryAssault; - @Mock private CpuAssault cpuAssault; + @Mock + private CpuAssault cpuAssault; - @Test - void shouldRespectTheOffSetting() { - when(memoryAssault.getCronExpression(any())).thenReturn("OFF"); - when(killAppAssault.getCronExpression(any())).thenReturn("OFF"); - when(cpuAssault.getCronExpression(any())).thenReturn("OFF"); + @Test + void shouldRespectTheOffSetting() { + when(memoryAssault.getCronExpression(any())).thenReturn("OFF"); + when(killAppAssault.getCronExpression(any())).thenReturn("OFF"); + when(cpuAssault.getCronExpression(any())).thenReturn("OFF"); - new ChaosMonkeyScheduler( - registrar, config, Arrays.asList(memoryAssault, killAppAssault, cpuAssault)); - verify(killAppAssault, never()).attack(); - verify(memoryAssault, never()).attack(); - verify(cpuAssault, never()).attack(); - verify(registrar, never()).scheduleCronTask(any()); - } + new ChaosMonkeyScheduler(registrar, config, Arrays.asList(memoryAssault, killAppAssault, cpuAssault)); + verify(killAppAssault, never()).attack(); + verify(memoryAssault, never()).attack(); + verify(cpuAssault, never()).attack(); + verify(registrar, never()).scheduleCronTask(any()); + } - @Test - void shouldScheduleATask() { - String schedule = "*/1 * * * * ?"; - ScheduledTask scheduledTask = mock(ScheduledTask.class); - when(memoryAssault.getCronExpression(any())).thenReturn(schedule); - when(registrar.scheduleCronTask(any())).thenReturn(scheduledTask); + @Test + void shouldScheduleATask() { + String schedule = "*/1 * * * * ?"; + ScheduledTask scheduledTask = mock(ScheduledTask.class); + when(memoryAssault.getCronExpression(any())).thenReturn(schedule); + when(registrar.scheduleCronTask(any())).thenReturn(scheduledTask); - new ChaosMonkeyScheduler(registrar, config, Collections.singletonList(memoryAssault)); + new ChaosMonkeyScheduler(registrar, config, Collections.singletonList(memoryAssault)); + + verify(registrar).scheduleCronTask(argThat(hasScheduleLike(schedule))); + } + + @Test + void shouldNotScheduleNewTasksAfterUnrelatedUpdate() { + String schedule = "*/1 * * * * ?"; + ScheduledTask oldTask = mockScheduledTask("memory", schedule); + when(memoryAssault.getCronExpression(any())).thenReturn(schedule); + when(registrar.scheduleCronTask(any())).thenReturn(oldTask); + + ChaosMonkeyScheduler cms = new ChaosMonkeyScheduler(registrar, config, Collections.singletonList(memoryAssault)); + verify(registrar, times(1)).scheduleCronTask(argThat(hasScheduleLike(schedule))); + + reset(registrar); + + cms.reloadConfig(); - verify(registrar).scheduleCronTask(argThat(hasScheduleLike(schedule))); - } + verify(registrar, never()).scheduleCronTask(argThat(hasScheduleLike(schedule))); + } - @Test - void shouldNotScheduleNewTasksAfterUnrelatedUpdate() { - String schedule = "*/1 * * * * ?"; - ScheduledTask oldTask = mockScheduledTask("memory", schedule); - when(memoryAssault.getCronExpression(any())).thenReturn(schedule); - when(registrar.scheduleCronTask(any())).thenReturn(oldTask); + @Test + void shouldTriggerRuntimeScopeRunAttack() { + String schedule = "*/1 * * * * ?"; + when(memoryAssault.isActive()).thenReturn(true); + when(memoryAssault.getCronExpression(any())).thenReturn(schedule); + when(registrar.scheduleCronTask(any())).thenAnswer(iom -> { + iom.getArgument(0, CronTask.class).getRunnable().run(); + return null; + }); - ChaosMonkeyScheduler cms = new ChaosMonkeyScheduler(registrar, config, Collections.singletonList(memoryAssault)); - verify(registrar, times(1)).scheduleCronTask(argThat(hasScheduleLike(schedule))); - - reset(registrar); - - cms.reloadConfig(); - - verify(registrar, never()).scheduleCronTask(argThat(hasScheduleLike(schedule))); - } - - @Test - void shouldTriggerRuntimeScopeRunAttack() { - String schedule = "*/1 * * * * ?"; - when(memoryAssault.isActive()).thenReturn(true); - when(memoryAssault.getCronExpression(any())).thenReturn(schedule); - when(registrar.scheduleCronTask(any())) - .thenAnswer( - iom -> { - iom.getArgument(0, CronTask.class).getRunnable().run(); - return null; - }); - - new ChaosMonkeyScheduler(registrar, config, Collections.singletonList(memoryAssault)); - verify(memoryAssault).attack(); - } - - @Test - void shouldRescheduleOnlyChangedTasks() { - String memorySchedule = "*/1 * * * * ?"; - String killAppSchedule = "*/2 * * * * ?"; - ScheduledTask memoryTask = mockScheduledTask("memory", memorySchedule); - ScheduledTask oldTask = mockScheduledTask("killApp", killAppSchedule); - ScheduledTask newTask = mock(ScheduledTask.class); - when(memoryAssault.getCronExpression(any())).thenReturn(memorySchedule); - when(killAppAssault.getCronExpression(any())).thenReturn(killAppSchedule); - when(registrar.scheduleCronTask(argThat(hasScheduleLike(memorySchedule)))) - .thenReturn(memoryTask); - when(registrar.scheduleCronTask(argThat(hasScheduleLike(killAppSchedule)))) - .thenReturn(oldTask, newTask); - - ChaosMonkeyScheduler cms = - new ChaosMonkeyScheduler(registrar, config, Arrays.asList(memoryAssault, killAppAssault)); - verify(registrar).scheduleCronTask(argThat(hasScheduleLike(memorySchedule))); - verify(registrar).scheduleCronTask(argThat(hasScheduleLike(killAppSchedule))); - - reset(registrar); - String killAppSchedule2 = "*/3 * * * * ?"; - when(killAppAssault.getCronExpression(any())).thenReturn(killAppSchedule2); - - cms.reloadConfig(); - verify(registrar).scheduleCronTask(argThat(hasScheduleLike(killAppSchedule2))); - verify(memoryTask, never()).cancel(); - verify(oldTask).cancel(); - } - - private ArgumentMatcher hasScheduleLike(String schedule) { - return cronTask -> cronTask != null && cronTask.getExpression().equals(schedule); - } - - private static ScheduledTask mockScheduledTask(String name, String schedule) { - ScheduledTask scheduledTask = mock(ScheduledTask.class, name); - when(scheduledTask.getTask()).thenReturn(new CronTask(() -> {}, schedule)); - return scheduledTask; - } + verify(memoryAssault).attack(); + } + + @Test + void shouldRescheduleOnlyChangedTasks() { + String memorySchedule = "*/1 * * * * ?"; + String killAppSchedule = "*/2 * * * * ?"; + ScheduledTask memoryTask = mockScheduledTask("memory", memorySchedule); + ScheduledTask oldTask = mockScheduledTask("killApp", killAppSchedule); + ScheduledTask newTask = mock(ScheduledTask.class); + when(memoryAssault.getCronExpression(any())).thenReturn(memorySchedule); + when(killAppAssault.getCronExpression(any())).thenReturn(killAppSchedule); + when(registrar.scheduleCronTask(argThat(hasScheduleLike(memorySchedule)))).thenReturn(memoryTask); + when(registrar.scheduleCronTask(argThat(hasScheduleLike(killAppSchedule)))).thenReturn(oldTask, newTask); + + ChaosMonkeyScheduler cms = new ChaosMonkeyScheduler(registrar, config, Arrays.asList(memoryAssault, killAppAssault)); + verify(registrar).scheduleCronTask(argThat(hasScheduleLike(memorySchedule))); + verify(registrar).scheduleCronTask(argThat(hasScheduleLike(killAppSchedule))); + + reset(registrar); + String killAppSchedule2 = "*/3 * * * * ?"; + when(killAppAssault.getCronExpression(any())).thenReturn(killAppSchedule2); + + cms.reloadConfig(); + verify(registrar).scheduleCronTask(argThat(hasScheduleLike(killAppSchedule2))); + verify(memoryTask, never()).cancel(); + verify(oldTask).cancel(); + } + + private ArgumentMatcher hasScheduleLike(String schedule) { + return cronTask -> cronTask != null && cronTask.getExpression().equals(schedule); + } + + private static ScheduledTask mockScheduledTask(String name, String schedule) { + ScheduledTask scheduledTask = mock(ScheduledTask.class, name); + when(scheduledTask.getTask()).thenReturn(new CronTask(() -> { + }, schedule)); + return scheduledTask; + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/AssaultExceptionTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/AssaultExceptionTest.java index 4acf8326..5226b3d6 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/AssaultExceptionTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/AssaultExceptionTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2022 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 + * + * https://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.spring.boot.chaos.monkey.configuration; import static org.assertj.core.api.Assertions.assertThat; @@ -12,138 +27,118 @@ import org.junit.jupiter.api.Test; class AssaultExceptionTest { - @Test - void testStandardCase() { - AssaultException assaultException = new AssaultException(); - - RuntimeException exception = - assertThrows(RuntimeException.class, assaultException::throwExceptionInstance); - assertThat(exception.getMessage()).isEqualTo("Chaos Monkey - RuntimeException"); - } - - @Test - void testFaultyTypeConfiguration() { - AssaultException assaultException = new AssaultException(); - assaultException.setType("NonExistentClass"); - - RuntimeException exception = - assertThrows(RuntimeException.class, assaultException::throwExceptionInstance); - assertThat(exception.getMessage()).isEqualTo("Chaos Monkey - RuntimeException (Fallback)"); - } - - @Test - void testFaultyMethodConfiguration() { - AssaultException assaultException = new AssaultException(); - assaultException.setMethod("NonExistentMethod"); - - RuntimeException exception = - assertThrows(RuntimeException.class, assaultException::throwExceptionInstance); - assertThat(exception.getMessage()).isEqualTo("Chaos Monkey - RuntimeException (Fallback)"); - } - - @Test - void testFaultyArgumentTypeConfiguration() { - AssaultException assaultException = new AssaultException(); - assaultException.setArguments( - Collections.singletonList( - new AssaultException.ExceptionArgument("NonExistentClass", "value"))); - - RuntimeException exception = - assertThrows(RuntimeException.class, assaultException::throwExceptionInstance); - assertThat(exception.getMessage()).isEqualTo("Chaos Monkey - RuntimeException (Fallback)"); - } - - @Test - void testFaultyArgumentValueConfiguration() { - AssaultException assaultException = new AssaultException(); - assaultException.setArguments( - Collections.singletonList(new AssaultException.ExceptionArgument("int", "notAnInteger"))); - - RuntimeException exception = - assertThrows(RuntimeException.class, assaultException::throwExceptionInstance); - assertThat(exception.getMessage()).isEqualTo("Chaos Monkey - RuntimeException (Fallback)"); - } - - @RequiredArgsConstructor - private static class IntException extends RuntimeException { - private final int anInt; - } - - @Test - void testPrimitiveArgumentValueConfiguration() { - AssaultException assaultException = new AssaultException(); - assaultException.setType(IntException.class.getName()); - assaultException.setArguments( - Collections.singletonList(new AssaultException.ExceptionArgument("int", "1"))); - - IntException exception = - assertThrows(IntException.class, assaultException::throwExceptionInstance); - assertThat(exception.anInt).isEqualTo(1); - } - - @RequiredArgsConstructor - private static class EnumException extends RuntimeException { - private final ChaosTarget enumValue; - } - - @Test - void testEnumArgumentValueConfiguration() { - AssaultException assaultException = new AssaultException(); - assaultException.setType(EnumException.class.getName()); - assaultException.setArguments( - Collections.singletonList( - new AssaultException.ExceptionArgument(ChaosTarget.class.getName(), "CONTROLLER"))); - - EnumException exception = - assertThrows(EnumException.class, assaultException::throwExceptionInstance); - assertThat(exception.enumValue).isEqualTo(ChaosTarget.CONTROLLER); - } - - @Data - @NoArgsConstructor - @AllArgsConstructor - private static class ComplexObject { - private int i; - private ComplexObject complexObject; - } - - @RequiredArgsConstructor - private static class ComplexObjectException extends RuntimeException { - private final ComplexObject complexObject; - } - - @Test - void testComplexObjectArgumentValueConfiguration() { - AssaultException assaultException = new AssaultException(); - assaultException.setType(ComplexObjectException.class.getName()); - assaultException.setArguments( - Collections.singletonList( - new AssaultException.ExceptionArgument( - ComplexObject.class.getName(), + @Test + void testStandardCase() { + AssaultException assaultException = new AssaultException(); + + RuntimeException exception = assertThrows(RuntimeException.class, assaultException::throwExceptionInstance); + assertThat(exception.getMessage()).isEqualTo("Chaos Monkey - RuntimeException"); + } + + @Test + void testFaultyTypeConfiguration() { + AssaultException assaultException = new AssaultException(); + assaultException.setType("NonExistentClass"); + + RuntimeException exception = assertThrows(RuntimeException.class, assaultException::throwExceptionInstance); + assertThat(exception.getMessage()).isEqualTo("Chaos Monkey - RuntimeException (Fallback)"); + } + + @Test + void testFaultyMethodConfiguration() { + AssaultException assaultException = new AssaultException(); + assaultException.setMethod("NonExistentMethod"); + + RuntimeException exception = assertThrows(RuntimeException.class, assaultException::throwExceptionInstance); + assertThat(exception.getMessage()).isEqualTo("Chaos Monkey - RuntimeException (Fallback)"); + } + + @Test + void testFaultyArgumentTypeConfiguration() { + AssaultException assaultException = new AssaultException(); + assaultException.setArguments(Collections.singletonList(new AssaultException.ExceptionArgument("NonExistentClass", "value"))); + + RuntimeException exception = assertThrows(RuntimeException.class, assaultException::throwExceptionInstance); + assertThat(exception.getMessage()).isEqualTo("Chaos Monkey - RuntimeException (Fallback)"); + } + + @Test + void testFaultyArgumentValueConfiguration() { + AssaultException assaultException = new AssaultException(); + assaultException.setArguments(Collections.singletonList(new AssaultException.ExceptionArgument("int", "notAnInteger"))); + + RuntimeException exception = assertThrows(RuntimeException.class, assaultException::throwExceptionInstance); + assertThat(exception.getMessage()).isEqualTo("Chaos Monkey - RuntimeException (Fallback)"); + } + + @RequiredArgsConstructor + private static class IntException extends RuntimeException { + private final int anInt; + } + + @Test + void testPrimitiveArgumentValueConfiguration() { + AssaultException assaultException = new AssaultException(); + assaultException.setType(IntException.class.getName()); + assaultException.setArguments(Collections.singletonList(new AssaultException.ExceptionArgument("int", "1"))); + + IntException exception = assertThrows(IntException.class, assaultException::throwExceptionInstance); + assertThat(exception.anInt).isEqualTo(1); + } + + @RequiredArgsConstructor + private static class EnumException extends RuntimeException { + private final ChaosTarget enumValue; + } + + @Test + void testEnumArgumentValueConfiguration() { + AssaultException assaultException = new AssaultException(); + assaultException.setType(EnumException.class.getName()); + assaultException.setArguments(Collections.singletonList(new AssaultException.ExceptionArgument(ChaosTarget.class.getName(), "CONTROLLER"))); + + EnumException exception = assertThrows(EnumException.class, assaultException::throwExceptionInstance); + assertThat(exception.enumValue).isEqualTo(ChaosTarget.CONTROLLER); + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + private static class ComplexObject { + private int i; + private ComplexObject complexObject; + } + + @RequiredArgsConstructor + private static class ComplexObjectException extends RuntimeException { + private final ComplexObject complexObject; + } + + @Test + void testComplexObjectArgumentValueConfiguration() { + AssaultException assaultException = new AssaultException(); + assaultException.setType(ComplexObjectException.class.getName()); + assaultException.setArguments(Collections.singletonList(new AssaultException.ExceptionArgument(ComplexObject.class.getName(), "{\"i\": 1, \"complexObject\": {\"i\": 2, \"complexObject\": null}}"))); - ComplexObjectException exception = - assertThrows(ComplexObjectException.class, assaultException::throwExceptionInstance); - assertThat(exception.complexObject).isEqualTo(new ComplexObject(1, new ComplexObject(2, null))); - } - - @SuppressWarnings("unused") - public static Throwable createThrowable(String message) { - return new RuntimeException(message); - } - - @Test - void testStaticInitializerConfiguration() { - AssaultException assaultException = new AssaultException(); - assaultException.setType(AssaultExceptionTest.class.getName()); - assaultException.setMethod("createThrowable"); - assaultException.setArguments( - Collections.singletonList( - new AssaultException.ExceptionArgument( - String.class.getName(), "test static initializer"))); - - RuntimeException exception = - assertThrows(RuntimeException.class, assaultException::throwExceptionInstance); - assertThat(exception.getMessage()).isEqualTo("test static initializer"); - } + ComplexObjectException exception = assertThrows(ComplexObjectException.class, assaultException::throwExceptionInstance); + assertThat(exception.complexObject).isEqualTo(new ComplexObject(1, new ComplexObject(2, null))); + } + + @SuppressWarnings("unused") + public static Throwable createThrowable(String message) { + return new RuntimeException(message); + } + + @Test + void testStaticInitializerConfiguration() { + AssaultException assaultException = new AssaultException(); + assaultException.setType(AssaultExceptionTest.class.getName()); + assaultException.setMethod("createThrowable"); + assaultException + .setArguments(Collections.singletonList(new AssaultException.ExceptionArgument(String.class.getName(), "test static initializer"))); + + RuntimeException exception = assertThrows(RuntimeException.class, assaultException::throwExceptionInstance); + assertThat(exception.getMessage()).isEqualTo("test static initializer"); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyConditionTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyConditionTest.java index cdb7465d..6f564e9b 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyConditionTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyConditionTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.configuration; import static org.assertj.core.api.Assertions.assertThat; @@ -8,26 +23,22 @@ class ChaosMonkeyConditionTest { - private final ApplicationContextRunner runner = - new ApplicationContextRunner() - .withConfiguration(UserConfigurations.of(ChaosMonkeyConfiguration.class)); + private final ApplicationContextRunner runner = new ApplicationContextRunner() + .withConfiguration(UserConfigurations.of(ChaosMonkeyConfiguration.class)); - @Test - public void chaosmonkeyShouldBeUnload() { - runner.run(ctx -> assertThat(ctx.containsBean("chaosMonkeyRequestScope")).isFalse()); - } + @Test + public void chaosmonkeyShouldBeUnload() { + runner.run(ctx -> assertThat(ctx.containsBean("chaosMonkeyRequestScope")).isFalse()); + } - @Test - public void chaosmonkeyShouldBeloadedWithProfile() { - runner - .withSystemProperties("spring.profiles.active=chaos-monkey") - .run(ctx -> assertThat(ctx.containsBean("chaosMonkeyRequestScope")).isTrue()); - } + @Test + public void chaosmonkeyShouldBeloadedWithProfile() { + runner.withSystemProperties("spring.profiles.active=chaos-monkey") + .run(ctx -> assertThat(ctx.containsBean("chaosMonkeyRequestScope")).isTrue()); + } - @Test - public void chaosmonkeyShouldBeloadedWithProperty() { - runner - .withSystemProperties("LOAD_CHAOS_MONKEY=true") - .run(ctx -> assertThat(ctx.containsBean("chaosMonkeyRequestScope")).isTrue()); - } + @Test + public void chaosmonkeyShouldBeloadedWithProperty() { + runner.withSystemProperties("LOAD_CHAOS_MONKEY=true").run(ctx -> assertThat(ctx.containsBean("chaosMonkeyRequestScope")).isTrue()); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyRequestScopeSettingsTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyRequestScopeSettingsTest.java index 7567e48b..71118235 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyRequestScopeSettingsTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/ChaosMonkeyRequestScopeSettingsTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.configuration; import static org.assertj.core.api.Assertions.assertThat; @@ -24,120 +23,115 @@ /** @author Benjamin Wilms */ class ChaosMonkeyRequestScopeSettingsTest { - private ChaosMonkeySettings settings; - - @Test - void noArgsTest() { - settings = new ChaosMonkeySettings(); - ChaosMonkeyProperties chaosMonkeyProperties = getChaosMonkeyProperties(); - settings.setChaosMonkeyProperties(chaosMonkeyProperties); - AssaultProperties assaultProperties = getAssaultProperties(); - settings.setAssaultProperties(assaultProperties); - WatcherProperties watcherProperties = getWatcherProperties(); - settings.setWatcherProperties(watcherProperties); - - validate(chaosMonkeyProperties, assaultProperties, watcherProperties); - } - - @Test - void allArgsTest() { - ChaosMonkeyProperties chaosMonkeyProperties = getChaosMonkeyProperties(); - AssaultProperties assaultProperties = getAssaultProperties(); - WatcherProperties watcherProperties = getWatcherProperties(); - settings = new ChaosMonkeySettings(chaosMonkeyProperties, assaultProperties, watcherProperties); - - validate(chaosMonkeyProperties, assaultProperties, watcherProperties); - } - - @Test - void lombokDataTest() { - ChaosMonkeyProperties chaosMonkeyProperties = getChaosMonkeyProperties(); - AssaultProperties assaultProperties = getAssaultProperties(); - WatcherProperties watcherProperties = getWatcherProperties(); - settings = new ChaosMonkeySettings(chaosMonkeyProperties, assaultProperties, watcherProperties); - - assertThat(settings.getChaosMonkeyProperties()).isNotNull(); - assertThat(settings.getAssaultProperties()).isNotNull(); - assertThat(settings.getWatcherProperties()).isNotNull(); - } - - @Test - void lombokDataSetTest() { - settings = new ChaosMonkeySettings(); - - ChaosMonkeyProperties chaosMonkeyProperties = getChaosMonkeyProperties(); - settings.setChaosMonkeyProperties(chaosMonkeyProperties); - - WatcherProperties watcherProperties = getWatcherProperties(); - settings.setWatcherProperties(watcherProperties); - - AssaultProperties assaultProperties = getAssaultProperties(); - settings.setAssaultProperties(assaultProperties); - - assertThat(settings.getChaosMonkeyProperties()).isNotNull(); - assertThat(settings.getAssaultProperties()).isNotNull(); - assertThat(settings.getWatcherProperties()).isNotNull(); - } - - @Test - void lombokDataNullTest() { - settings = new ChaosMonkeySettings(null, null, null); - - assertThat(settings.getChaosMonkeyProperties()).isNull(); - assertThat(settings.getAssaultProperties()).isNull(); - assertThat(settings.getWatcherProperties()).isNull(); - } - - private void validate( - ChaosMonkeyProperties chaosMonkeyProperties, - AssaultProperties assaultProperties, - WatcherProperties watcherProperties) { - assertThat(settings.getChaosMonkeyProperties()).isEqualTo(chaosMonkeyProperties); - assertThat(settings.getAssaultProperties()).isEqualTo(assaultProperties); - assertThat(settings.getWatcherProperties()).isEqualTo(watcherProperties); - assertThat(settings.getChaosMonkeyProperties().isEnabled()).isTrue(); - assertThat(settings.getWatcherProperties().isController()).isTrue(); - assertThat(settings.getWatcherProperties().isRepository()).isTrue(); - assertThat(settings.getWatcherProperties().isService()).isTrue(); - assertThat(settings.getWatcherProperties().isRestController()).isTrue(); - assertThat(settings.getAssaultProperties().isKillApplicationActive()).isTrue(); - assertThat(settings.getAssaultProperties().isExceptionsActive()).isTrue(); - assertThat(settings.getAssaultProperties().isLatencyActive()).isTrue(); - assertThat(settings.getAssaultProperties().getLevel()).isEqualTo(assaultProperties.getLevel()); - assertThat(settings.getAssaultProperties().getLatencyRangeEnd()) - .isEqualTo(assaultProperties.getLatencyRangeEnd()); - assertThat(settings.getAssaultProperties().getLatencyRangeStart()) - .isEqualTo(assaultProperties.getLatencyRangeStart()); - - int troubleRandom = settings.getAssaultProperties().getTroubleRandom(); - assertTrue(troubleRandom < 1001, "Trouble random is to high!"); - - assertThat(settings.getAssaultProperties().getLevel()).isEqualTo(assaultProperties.getLevel()); - } - - private ChaosMonkeyProperties getChaosMonkeyProperties() { - ChaosMonkeyProperties chaosMonkeyProperties = new ChaosMonkeyProperties(); - chaosMonkeyProperties.setEnabled(true); - return chaosMonkeyProperties; - } - - private AssaultProperties getAssaultProperties() { - AssaultProperties assaultProperties = new AssaultProperties(); - assaultProperties.setExceptionsActive(true); - assaultProperties.setKillApplicationActive(true); - assaultProperties.setLatencyActive(true); - assaultProperties.setLatencyRangeEnd(100); - assaultProperties.setLatencyRangeStart(1); - assaultProperties.setLevel(99); - return assaultProperties; - } - - private WatcherProperties getWatcherProperties() { - WatcherProperties watcherProperties = new WatcherProperties(); - watcherProperties.setController(true); - watcherProperties.setRepository(true); - watcherProperties.setRestController(true); - watcherProperties.setService(true); - return watcherProperties; - } + private ChaosMonkeySettings settings; + + @Test + void noArgsTest() { + settings = new ChaosMonkeySettings(); + ChaosMonkeyProperties chaosMonkeyProperties = getChaosMonkeyProperties(); + settings.setChaosMonkeyProperties(chaosMonkeyProperties); + AssaultProperties assaultProperties = getAssaultProperties(); + settings.setAssaultProperties(assaultProperties); + WatcherProperties watcherProperties = getWatcherProperties(); + settings.setWatcherProperties(watcherProperties); + + validate(chaosMonkeyProperties, assaultProperties, watcherProperties); + } + + @Test + void allArgsTest() { + ChaosMonkeyProperties chaosMonkeyProperties = getChaosMonkeyProperties(); + AssaultProperties assaultProperties = getAssaultProperties(); + WatcherProperties watcherProperties = getWatcherProperties(); + settings = new ChaosMonkeySettings(chaosMonkeyProperties, assaultProperties, watcherProperties); + + validate(chaosMonkeyProperties, assaultProperties, watcherProperties); + } + + @Test + void lombokDataTest() { + ChaosMonkeyProperties chaosMonkeyProperties = getChaosMonkeyProperties(); + AssaultProperties assaultProperties = getAssaultProperties(); + WatcherProperties watcherProperties = getWatcherProperties(); + settings = new ChaosMonkeySettings(chaosMonkeyProperties, assaultProperties, watcherProperties); + + assertThat(settings.getChaosMonkeyProperties()).isNotNull(); + assertThat(settings.getAssaultProperties()).isNotNull(); + assertThat(settings.getWatcherProperties()).isNotNull(); + } + + @Test + void lombokDataSetTest() { + settings = new ChaosMonkeySettings(); + + ChaosMonkeyProperties chaosMonkeyProperties = getChaosMonkeyProperties(); + settings.setChaosMonkeyProperties(chaosMonkeyProperties); + + WatcherProperties watcherProperties = getWatcherProperties(); + settings.setWatcherProperties(watcherProperties); + + AssaultProperties assaultProperties = getAssaultProperties(); + settings.setAssaultProperties(assaultProperties); + + assertThat(settings.getChaosMonkeyProperties()).isNotNull(); + assertThat(settings.getAssaultProperties()).isNotNull(); + assertThat(settings.getWatcherProperties()).isNotNull(); + } + + @Test + void lombokDataNullTest() { + settings = new ChaosMonkeySettings(null, null, null); + + assertThat(settings.getChaosMonkeyProperties()).isNull(); + assertThat(settings.getAssaultProperties()).isNull(); + assertThat(settings.getWatcherProperties()).isNull(); + } + + private void validate(ChaosMonkeyProperties chaosMonkeyProperties, AssaultProperties assaultProperties, WatcherProperties watcherProperties) { + assertThat(settings.getChaosMonkeyProperties()).isEqualTo(chaosMonkeyProperties); + assertThat(settings.getAssaultProperties()).isEqualTo(assaultProperties); + assertThat(settings.getWatcherProperties()).isEqualTo(watcherProperties); + assertThat(settings.getChaosMonkeyProperties().isEnabled()).isTrue(); + assertThat(settings.getWatcherProperties().isController()).isTrue(); + assertThat(settings.getWatcherProperties().isRepository()).isTrue(); + assertThat(settings.getWatcherProperties().isService()).isTrue(); + assertThat(settings.getWatcherProperties().isRestController()).isTrue(); + assertThat(settings.getAssaultProperties().isKillApplicationActive()).isTrue(); + assertThat(settings.getAssaultProperties().isExceptionsActive()).isTrue(); + assertThat(settings.getAssaultProperties().isLatencyActive()).isTrue(); + assertThat(settings.getAssaultProperties().getLevel()).isEqualTo(assaultProperties.getLevel()); + assertThat(settings.getAssaultProperties().getLatencyRangeEnd()).isEqualTo(assaultProperties.getLatencyRangeEnd()); + assertThat(settings.getAssaultProperties().getLatencyRangeStart()).isEqualTo(assaultProperties.getLatencyRangeStart()); + + int troubleRandom = settings.getAssaultProperties().getTroubleRandom(); + assertTrue(troubleRandom < 1001, "Trouble random is to high!"); + + assertThat(settings.getAssaultProperties().getLevel()).isEqualTo(assaultProperties.getLevel()); + } + + private ChaosMonkeyProperties getChaosMonkeyProperties() { + ChaosMonkeyProperties chaosMonkeyProperties = new ChaosMonkeyProperties(); + chaosMonkeyProperties.setEnabled(true); + return chaosMonkeyProperties; + } + + private AssaultProperties getAssaultProperties() { + AssaultProperties assaultProperties = new AssaultProperties(); + assaultProperties.setExceptionsActive(true); + assaultProperties.setKillApplicationActive(true); + assaultProperties.setLatencyActive(true); + assaultProperties.setLatencyRangeEnd(100); + assaultProperties.setLatencyRangeStart(1); + assaultProperties.setLevel(99); + return assaultProperties; + } + + private WatcherProperties getWatcherProperties() { + WatcherProperties watcherProperties = new WatcherProperties(); + watcherProperties.setController(true); + watcherProperties.setRepository(true); + watcherProperties.setRestController(true); + watcherProperties.setService(true); + return watcherProperties; + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/DefaultChaosToggleNameMapperTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/DefaultChaosToggleNameMapperTest.java index b034dee4..1e95cc4f 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/DefaultChaosToggleNameMapperTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/DefaultChaosToggleNameMapperTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.configuration.toggles; import static org.junit.jupiter.api.Assertions.*; @@ -8,22 +23,20 @@ class DefaultChaosToggleNameMapperTest { - private DefaultChaosToggleNameMapper sut; + private DefaultChaosToggleNameMapper sut; - @BeforeEach - public void setup() { - sut = new DefaultChaosToggleNameMapper("toggle.prefix"); - } + @BeforeEach + public void setup() { + sut = new DefaultChaosToggleNameMapper("toggle.prefix"); + } - @Test - public void chaosTypeCanBeNull() { - assertEquals(sut.mapName(null, "com.example.MyController.hello"), "toggle.prefix.unknown"); - } + @Test + public void chaosTypeCanBeNull() { + assertEquals(sut.mapName(null, "com.example.MyController.hello"), "toggle.prefix.unknown"); + } - @Test - public void chaosTypeNameIsUsedAsSuffix() { - assertEquals( - sut.mapName(ChaosTarget.REPOSITORY, "com.example.MyController.hello"), - "toggle.prefix.repository"); - } + @Test + public void chaosTypeNameIsUsedAsSuffix() { + assertEquals(sut.mapName(ChaosTarget.REPOSITORY, "com.example.MyController.hello"), "toggle.prefix.repository"); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/DefaultChaosTogglesTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/DefaultChaosTogglesTest.java index 6c2ceac8..dea59f75 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/DefaultChaosTogglesTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/DefaultChaosTogglesTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.configuration.toggles; import static org.junit.jupiter.api.Assertions.*; @@ -7,16 +22,16 @@ class DefaultChaosTogglesTest { - private DefaultChaosToggles sut; + private DefaultChaosToggles sut; - @BeforeEach - public void setup() { - sut = new DefaultChaosToggles(); - } + @BeforeEach + public void setup() { + sut = new DefaultChaosToggles(); + } - @Test - public void defaultToggleShouldBeEnabledAlways() { - assertTrue(sut.isEnabled("chaos.monkey.repository")); - assertTrue(sut.isEnabled("")); - } + @Test + public void defaultToggleShouldBeEnabledAlways() { + assertTrue(sut.isEnabled("chaos.monkey.repository")); + assertTrue(sut.isEnabled("")); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/UnleashChaosTogglesTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/UnleashChaosTogglesTest.java index 3144ffe4..ae5c4882 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/UnleashChaosTogglesTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/configuration/toggles/UnleashChaosTogglesTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.configuration.toggles; import static org.junit.jupiter.api.Assertions.*; @@ -7,29 +22,29 @@ import org.junit.jupiter.api.Test; class UnleashChaosTogglesTest { - private UnleashChaosToggles sut; - private FakeUnleash fakeUnleash; + private UnleashChaosToggles sut; + private FakeUnleash fakeUnleash; - @BeforeEach - public void setup() { - fakeUnleash = new FakeUnleash(); - sut = new UnleashChaosToggles(fakeUnleash); - } + @BeforeEach + public void setup() { + fakeUnleash = new FakeUnleash(); + sut = new UnleashChaosToggles(fakeUnleash); + } - @Test - public void unleashTogglesAreDisabledByDefault() { - assertFalse(sut.isEnabled("chaos.monkey.repository")); - } + @Test + public void unleashTogglesAreDisabledByDefault() { + assertFalse(sut.isEnabled("chaos.monkey.repository")); + } - @Test - public void unleashTogglesThatAreEnabledAlsoEnableTheChaosToggle() { - fakeUnleash.enable("chaos.monkey.repository"); - assertTrue(sut.isEnabled("chaos.monkey.repository")); - } + @Test + public void unleashTogglesThatAreEnabledAlsoEnableTheChaosToggle() { + fakeUnleash.enable("chaos.monkey.repository"); + assertTrue(sut.isEnabled("chaos.monkey.repository")); + } - @Test - public void unleashTogglesThatAreEnabledThatDontMatchTheChaosToggleAUnaffected() { - fakeUnleash.enable("chaos.monkey.controller"); - assertFalse(sut.isEnabled("chaos.monkey.repository")); - } + @Test + public void unleashTogglesThatAreEnabledThatDontMatchTheChaosToggleAUnaffected() { + fakeUnleash.enable("chaos.monkey.controller"); + assertFalse(sut.isEnabled("chaos.monkey.repository")); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRequestScopeJmxEndpointTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRequestScopeJmxEndpointTest.java index 0e0e2754..6fdd5120 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRequestScopeJmxEndpointTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRequestScopeJmxEndpointTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.endpoints; import static org.assertj.core.api.Assertions.assertThat; @@ -30,96 +29,88 @@ /** @author Benjamin Wilms */ class ChaosMonkeyRequestScopeJmxEndpointTest { - private ChaosMonkeyJmxEndpoint chaosMonkeyJmxEndpoint; - - private ChaosMonkeySettings chaosMonkeySettings; - - @BeforeEach - void setUp() { - AssaultProperties assaultProperties = new AssaultProperties(); - assaultProperties.setLevel(1); - assaultProperties.setLatencyRangeStart(100); - assaultProperties.setLatencyRangeEnd(200); - WatcherProperties watcherProperties = new WatcherProperties(); - watcherProperties.setComponent(true); - ChaosMonkeyProperties chaosMonkeyProperties = new ChaosMonkeyProperties(); - chaosMonkeyProperties.setEnabled(true); - chaosMonkeySettings = - new ChaosMonkeySettings(chaosMonkeyProperties, assaultProperties, watcherProperties); - chaosMonkeyJmxEndpoint = new ChaosMonkeyJmxEndpoint(chaosMonkeySettings); - } - - @Test - void getAssaultProperties() { - assertThat(chaosMonkeyJmxEndpoint.getAssaultProperties()) - .isEqualTo(chaosMonkeySettings.getAssaultProperties().toDto()); - } - - @Test - void toggleLatencyAssault() { - boolean latencyActive = chaosMonkeySettings.getAssaultProperties().isLatencyActive(); - - chaosMonkeyJmxEndpoint.toggleLatencyAssault(); - - assertThat(chaosMonkeyJmxEndpoint.getAssaultProperties().getLatencyActive()) - .isNotEqualTo(latencyActive); - } - - @Test - void toggleExceptionAssault() { - boolean exceptionsActive = chaosMonkeySettings.getAssaultProperties().isExceptionsActive(); - chaosMonkeyJmxEndpoint.toggleExceptionAssault(); - - assertThat(chaosMonkeyJmxEndpoint.getAssaultProperties().getExceptionsActive()) - .isNotEqualTo(exceptionsActive); - } - - @Test - void toggleKillApplicationAssault() { - boolean killApplicationActive = - chaosMonkeySettings.getAssaultProperties().isKillApplicationActive(); - chaosMonkeyJmxEndpoint.toggleKillApplicationAssault(); - - assertThat(chaosMonkeyJmxEndpoint.getAssaultProperties().getKillApplicationActive()) - .isNotEqualTo(killApplicationActive); - } - - @Test - void toggleCpuAssault() { - boolean cpuActive = chaosMonkeySettings.getAssaultProperties().isCpuActive(); - chaosMonkeyJmxEndpoint.toggleCpuAssault(); - - assertThat(chaosMonkeyJmxEndpoint.getAssaultProperties().getCpuActive()) - .isNotEqualTo(cpuActive); - } - - @Test - void isChaosMonkeyActive() { - assertThat(chaosMonkeyJmxEndpoint.isChaosMonkeyActive()) - .isEqualTo(String.valueOf(chaosMonkeySettings.getChaosMonkeyProperties().isEnabled())); - } - - @Test - void enableChaosMonkey() { - OffsetDateTime enabledAt = OffsetDateTime.now().withNano(0); - ChaosMonkeyStatusResponseDto enabledDto = chaosMonkeyJmxEndpoint.enableChaosMonkey(); - assertThat(enabledDto.isEnabled()).isEqualTo(true); - assertThat(enabledDto.getEnabledAt()).isAfterOrEqualTo(enabledAt); - assertThat(chaosMonkeySettings.getChaosMonkeyProperties().isEnabled()).isTrue(); - } - - @Test - void disableChaosMonkey() { - OffsetDateTime disabledAt = OffsetDateTime.now().withNano(0); - ChaosMonkeyStatusResponseDto disabledDto = chaosMonkeyJmxEndpoint.disableChaosMonkey(); - assertThat(disabledDto.isEnabled()).isEqualTo(false); - assertThat(disabledDto.getDisabledAt()).isAfterOrEqualTo(disabledAt); - assertThat(chaosMonkeySettings.getChaosMonkeyProperties().isEnabled()).isFalse(); - } - - @Test - void getWatcherProperties() { - assertThat(chaosMonkeyJmxEndpoint.getWatcherProperties()) - .isEqualTo(chaosMonkeySettings.getWatcherProperties()); - } + private ChaosMonkeyJmxEndpoint chaosMonkeyJmxEndpoint; + + private ChaosMonkeySettings chaosMonkeySettings; + + @BeforeEach + void setUp() { + AssaultProperties assaultProperties = new AssaultProperties(); + assaultProperties.setLevel(1); + assaultProperties.setLatencyRangeStart(100); + assaultProperties.setLatencyRangeEnd(200); + WatcherProperties watcherProperties = new WatcherProperties(); + watcherProperties.setComponent(true); + ChaosMonkeyProperties chaosMonkeyProperties = new ChaosMonkeyProperties(); + chaosMonkeyProperties.setEnabled(true); + chaosMonkeySettings = new ChaosMonkeySettings(chaosMonkeyProperties, assaultProperties, watcherProperties); + chaosMonkeyJmxEndpoint = new ChaosMonkeyJmxEndpoint(chaosMonkeySettings); + } + + @Test + void getAssaultProperties() { + assertThat(chaosMonkeyJmxEndpoint.getAssaultProperties()).isEqualTo(chaosMonkeySettings.getAssaultProperties().toDto()); + } + + @Test + void toggleLatencyAssault() { + boolean latencyActive = chaosMonkeySettings.getAssaultProperties().isLatencyActive(); + + chaosMonkeyJmxEndpoint.toggleLatencyAssault(); + + assertThat(chaosMonkeyJmxEndpoint.getAssaultProperties().getLatencyActive()).isNotEqualTo(latencyActive); + } + + @Test + void toggleExceptionAssault() { + boolean exceptionsActive = chaosMonkeySettings.getAssaultProperties().isExceptionsActive(); + chaosMonkeyJmxEndpoint.toggleExceptionAssault(); + + assertThat(chaosMonkeyJmxEndpoint.getAssaultProperties().getExceptionsActive()).isNotEqualTo(exceptionsActive); + } + + @Test + void toggleKillApplicationAssault() { + boolean killApplicationActive = chaosMonkeySettings.getAssaultProperties().isKillApplicationActive(); + chaosMonkeyJmxEndpoint.toggleKillApplicationAssault(); + + assertThat(chaosMonkeyJmxEndpoint.getAssaultProperties().getKillApplicationActive()).isNotEqualTo(killApplicationActive); + } + + @Test + void toggleCpuAssault() { + boolean cpuActive = chaosMonkeySettings.getAssaultProperties().isCpuActive(); + chaosMonkeyJmxEndpoint.toggleCpuAssault(); + + assertThat(chaosMonkeyJmxEndpoint.getAssaultProperties().getCpuActive()).isNotEqualTo(cpuActive); + } + + @Test + void isChaosMonkeyActive() { + assertThat(chaosMonkeyJmxEndpoint.isChaosMonkeyActive()) + .isEqualTo(String.valueOf(chaosMonkeySettings.getChaosMonkeyProperties().isEnabled())); + } + + @Test + void enableChaosMonkey() { + OffsetDateTime enabledAt = OffsetDateTime.now().withNano(0); + ChaosMonkeyStatusResponseDto enabledDto = chaosMonkeyJmxEndpoint.enableChaosMonkey(); + assertThat(enabledDto.isEnabled()).isEqualTo(true); + assertThat(enabledDto.getEnabledAt()).isAfterOrEqualTo(enabledAt); + assertThat(chaosMonkeySettings.getChaosMonkeyProperties().isEnabled()).isTrue(); + } + + @Test + void disableChaosMonkey() { + OffsetDateTime disabledAt = OffsetDateTime.now().withNano(0); + ChaosMonkeyStatusResponseDto disabledDto = chaosMonkeyJmxEndpoint.disableChaosMonkey(); + assertThat(disabledDto.isEnabled()).isEqualTo(false); + assertThat(disabledDto.getDisabledAt()).isAfterOrEqualTo(disabledAt); + assertThat(chaosMonkeySettings.getChaosMonkeyProperties().isEnabled()).isFalse(); + } + + @Test + void getWatcherProperties() { + assertThat(chaosMonkeyJmxEndpoint.getWatcherProperties()).isEqualTo(chaosMonkeySettings.getWatcherProperties()); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRequestScopeRestEndpointDisabledIntegrationTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRequestScopeRestEndpointDisabledIntegrationTest.java index 6da71d0d..72ae621e 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRequestScopeRestEndpointDisabledIntegrationTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRequestScopeRestEndpointDisabledIntegrationTest.java @@ -1,20 +1,18 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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.spring.boot.chaos.monkey.endpoints; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -32,28 +30,27 @@ import org.springframework.test.context.TestPropertySource; /** @author Benjamin Wilms */ -@SpringBootTest( - classes = ChaosDemoApplication.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(classes = ChaosDemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestPropertySource("classpath:test-chaos-monkey-endpoints-disabled.properties") class ChaosMonkeyRequestScopeRestEndpointDisabledIntegrationTest { - @LocalServerPort private int serverPort; + @LocalServerPort + private int serverPort; - @Autowired private TestRestTemplate testRestTemplate; + @Autowired + private TestRestTemplate testRestTemplate; - private String baseUrl; + private String baseUrl; - @BeforeEach - void setUp() { - baseUrl = "http://localhost:" + this.serverPort + "/actuator/chaosmonkey"; - } + @BeforeEach + void setUp() { + baseUrl = "http://localhost:" + this.serverPort + "/actuator/chaosmonkey"; + } - @Test - void getConfiguration() { - ResponseEntity chaosMonkeySettingsResult = - testRestTemplate.getForEntity(baseUrl, ChaosMonkeySettings.class); + @Test + void getConfiguration() { + ResponseEntity chaosMonkeySettingsResult = testRestTemplate.getForEntity(baseUrl, ChaosMonkeySettings.class); - assertEquals(HttpStatus.NOT_FOUND, chaosMonkeySettingsResult.getStatusCode()); - } + assertEquals(HttpStatus.NOT_FOUND, chaosMonkeySettingsResult.getStatusCode()); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRequestScopeRestEndpointIntegrationTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRequestScopeRestEndpointIntegrationTest.java index a25f5a38..6fd2fc4b 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRequestScopeRestEndpointIntegrationTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRequestScopeRestEndpointIntegrationTest.java @@ -1,20 +1,18 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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.spring.boot.chaos.monkey.endpoints; import static org.assertj.core.api.Assertions.assertThat; @@ -49,274 +47,251 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.context.TestPropertySource; -@SpringBootTest( - classes = ChaosDemoApplication.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(classes = ChaosDemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestPropertySource("classpath:application-test-chaos-monkey-profile.properties") class ChaosMonkeyRequestScopeRestEndpointIntegrationTest { - @LocalServerPort private int serverPort; - - @Autowired private ChaosMonkeySettings chaosMonkeySettings; - - @Autowired private TestRestTemplate testRestTemplate; - - private final ObjectMapper objectMapper = new ObjectMapper(); - - private String baseUrl; - - @BeforeEach - void setUp() { - baseUrl = "http://localhost:" + this.serverPort + "/actuator/chaosmonkey"; - objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - } - - @Test - void disableChaosMonkeyExecutionNotAllowed() { - ChaosMonkeyProperties chaosMonkeyProperties = new ChaosMonkeyProperties(); - chaosMonkeyProperties.setEnabled(false); - chaosMonkeySettings.setChaosMonkeyProperties(chaosMonkeyProperties); - - assertEquals( - postChaosMonkeySettings(chaosMonkeySettings).getStatusCode(), - HttpStatus.METHOD_NOT_ALLOWED); - assertFalse(this.chaosMonkeySettings.getChaosMonkeyProperties().isEnabled()); - } - - @Test - void getConfiguration() { - ResponseEntity chaosMonkeySettingsResult = - testRestTemplate.getForEntity(baseUrl, ChaosMonkeySettings.class); - - assertEquals(HttpStatus.OK, chaosMonkeySettingsResult.getStatusCode()); - assertEquals(chaosMonkeySettings.toString(), chaosMonkeySettingsResult.getBody().toString()); - } - - @Test - void postChaosMonkeySettingsEqualsNull() { - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - HttpEntity entity = new HttpEntity<>(null, headers); - - ResponseEntity responseEntity = postHttpEntity(entity); - assertEquals(HttpStatus.METHOD_NOT_ALLOWED, responseEntity.getStatusCode()); - } - - @Test - void postChaosMonkeySettingsValueObjectAssaultPropertiesNull() { - ResponseEntity responseEntity = - postChaosMonkeySettings( - new ChaosMonkeySettings(new ChaosMonkeyProperties(), null, new WatcherProperties())); - assertEquals(HttpStatus.METHOD_NOT_ALLOWED, responseEntity.getStatusCode()); - } - - @Test - void postChaosMonkeySettingsValueObjectWatcherPropertiesNull() { - ResponseEntity responseEntity = - postChaosMonkeySettings( - new ChaosMonkeySettings(new ChaosMonkeyProperties(), new AssaultProperties(), null)); - assertEquals(HttpStatus.METHOD_NOT_ALLOWED, responseEntity.getStatusCode()); - } - - // Watcher Tests - @Test - void getWatcherConfiguration() { - ResponseEntity result = - testRestTemplate.getForEntity(baseUrl + "/watchers", WatcherProperties.class); - - assertEquals(HttpStatus.OK, result.getStatusCode()); - assertEquals( - chaosMonkeySettings.getWatcherProperties().toString(), result.getBody().toString()); - } - - @Test - void postWatcherConfigurationGoodCase() { - - WatcherPropertiesUpdate watcherProperties = new WatcherPropertiesUpdate(); - watcherProperties.setService(true); - - ResponseEntity result = - testRestTemplate.postForEntity(baseUrl + "/watchers", watcherProperties, String.class); - - assertEquals(HttpStatus.OK, result.getStatusCode()); - assertEquals("Watcher config has changed", result.getBody()); - } - - // Assault Tests - @Test - void getAssaultConfiguration() throws JsonProcessingException { - ResponseEntity result = - testRestTemplate.getForEntity(baseUrl + "/assaults", AssaultPropertiesUpdate.class); - - assertEquals(HttpStatus.OK, result.getStatusCode()); - assertEquals( - objectMapper.writeValueAsString(chaosMonkeySettings.getAssaultProperties()), - objectMapper.writeValueAsString(result.getBody())); - } - - @Test - void postAssaultConfigurationGoodCase() { - AssaultPropertiesUpdate assaultProperties = new AssaultPropertiesUpdate(); - assaultProperties.setLevel(10); - assaultProperties.setLatencyRangeStart(100); - assaultProperties.setLatencyRangeEnd(200); - assaultProperties.setLatencyActive(true); - assaultProperties.setExceptionsActive(false); - assaultProperties.setException(new AssaultException()); - - // Do not set memory properties - optional :) - ResponseEntity result = - testRestTemplate.postForEntity(baseUrl + "/assaults", assaultProperties, String.class); - - assertEquals(HttpStatus.OK, result.getStatusCode()); - assertEquals("Assault config has changed", result.getBody()); - } - - @Test - void postMinimalUpdate() { - @Data - class MinimalSubmission { - - private int level = 10; + @LocalServerPort + private int serverPort; + + @Autowired + private ChaosMonkeySettings chaosMonkeySettings; + + @Autowired + private TestRestTemplate testRestTemplate; + + private final ObjectMapper objectMapper = new ObjectMapper(); + + private String baseUrl; + + @BeforeEach + void setUp() { + baseUrl = "http://localhost:" + this.serverPort + "/actuator/chaosmonkey"; + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + } + + @Test + void disableChaosMonkeyExecutionNotAllowed() { + ChaosMonkeyProperties chaosMonkeyProperties = new ChaosMonkeyProperties(); + chaosMonkeyProperties.setEnabled(false); + chaosMonkeySettings.setChaosMonkeyProperties(chaosMonkeyProperties); + + assertEquals(postChaosMonkeySettings(chaosMonkeySettings).getStatusCode(), HttpStatus.METHOD_NOT_ALLOWED); + assertFalse(this.chaosMonkeySettings.getChaosMonkeyProperties().isEnabled()); + } + + @Test + void getConfiguration() { + ResponseEntity chaosMonkeySettingsResult = testRestTemplate.getForEntity(baseUrl, ChaosMonkeySettings.class); + + assertEquals(HttpStatus.OK, chaosMonkeySettingsResult.getStatusCode()); + assertEquals(chaosMonkeySettings.toString(), chaosMonkeySettingsResult.getBody().toString()); + } + + @Test + void postChaosMonkeySettingsEqualsNull() { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity entity = new HttpEntity<>(null, headers); + + ResponseEntity responseEntity = postHttpEntity(entity); + assertEquals(HttpStatus.METHOD_NOT_ALLOWED, responseEntity.getStatusCode()); + } + + @Test + void postChaosMonkeySettingsValueObjectAssaultPropertiesNull() { + ResponseEntity responseEntity = postChaosMonkeySettings( + new ChaosMonkeySettings(new ChaosMonkeyProperties(), null, new WatcherProperties())); + assertEquals(HttpStatus.METHOD_NOT_ALLOWED, responseEntity.getStatusCode()); + } + + @Test + void postChaosMonkeySettingsValueObjectWatcherPropertiesNull() { + ResponseEntity responseEntity = postChaosMonkeySettings( + new ChaosMonkeySettings(new ChaosMonkeyProperties(), new AssaultProperties(), null)); + assertEquals(HttpStatus.METHOD_NOT_ALLOWED, responseEntity.getStatusCode()); } - ResponseEntity result = - testRestTemplate.postForEntity( - baseUrl + "/assaults", new MinimalSubmission(), String.class); - - assertEquals(HttpStatus.OK, result.getStatusCode()); - assertEquals("Assault config has changed", result.getBody()); - } - - @Test - void postAssaultConfigurationBadCaseLevelEmpty() { - AssaultPropertiesUpdate assaultProperties = new AssaultPropertiesUpdate(); - assaultProperties.setLatencyRangeEnd(100); - assaultProperties.setLatencyRangeStart(200); - assaultProperties.setLatencyActive(true); - - ResponseEntity result = - testRestTemplate.postForEntity(baseUrl + "/assaults", assaultProperties, String.class); - - assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode()); - } - - @Test - void postAssaultConfigurationBadCaseLatencyRangeEndEmpty() { - AssaultPropertiesUpdate assaultProperties = new AssaultPropertiesUpdate(); - assaultProperties.setLevel(1000); - assaultProperties.setLatencyRangeStart(200); - assaultProperties.setLatencyActive(true); - - ResponseEntity result = - testRestTemplate.postForEntity(baseUrl + "/assaults", assaultProperties, String.class); - - assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode()); - } - - @Test - void postAssaultConfigurationBadCaseLatencyRangeStartEmpty() { - AssaultPropertiesUpdate assaultProperties = new AssaultPropertiesUpdate(); - assaultProperties.setLevel(1000); - assaultProperties.setLatencyRangeEnd(200); - assaultProperties.setLatencyActive(true); - - ResponseEntity result = - testRestTemplate.postForEntity(baseUrl + "/assaults", assaultProperties, String.class); - - assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode()); - } - - @Test - void postAssaultConfigurationBadCaseInvalidExceptionType() { - AssaultException exception = new AssaultException(); - exception.setType("SomeInvalidException"); - - AssaultPropertiesUpdate assaultProperties = new AssaultPropertiesUpdate(); - assaultProperties.setLevel(10); - assaultProperties.setLatencyRangeEnd(100); - assaultProperties.setLatencyRangeStart(200); - assaultProperties.setLatencyActive(true); - assaultProperties.setExceptionsActive(false); - assaultProperties.setException(exception); - - ResponseEntity result = - testRestTemplate.postForEntity(baseUrl + "/assaults", assaultProperties, String.class); - - assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode()); - } - - // STATUS - @Test - void getStatusIsEnabled() { - chaosMonkeySettings.getChaosMonkeyProperties().setEnabled(true); - - ResponseEntity result = - testRestTemplate.getForEntity(baseUrl + "/status", ChaosMonkeyStatusResponseDto.class); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody().isEnabled()).isTrue(); - } - - @Test - void getStatusIsDisabled() { - chaosMonkeySettings.getChaosMonkeyProperties().setEnabled(false); - - ResponseEntity result = - testRestTemplate.getForEntity(baseUrl + "/status", ChaosMonkeyStatusResponseDto.class); - - assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(result.getBody().isEnabled()).isFalse(); - } - - // ENABLE CHAOS MONKEY - - @Test - void postToEnableChaosMonkey() { - OffsetDateTime enabledAt = OffsetDateTime.now().withNano(0); - ResponseEntity result = - testRestTemplate.postForEntity( - baseUrl + "/enable", null, ChaosMonkeyStatusResponseDto.class); - - assertEquals(HttpStatus.OK, result.getStatusCode()); - assertThat(Objects.requireNonNull(result.getBody()).isEnabled()).isTrue(); - assertThat(Objects.requireNonNull(result.getBody()).getEnabledAt()).isAfterOrEqualTo(enabledAt); - } - - // DISABLE CHAOS MONKEY - @Test - void postToDisableChaosMonkey() { - ResponseEntity result = - testRestTemplate.postForEntity( - baseUrl + "/disable", null, ChaosMonkeyStatusResponseDto.class); - - assertEquals(HttpStatus.OK, result.getStatusCode()); - assertThat(Objects.requireNonNull(result.getBody()).isEnabled()).isEqualTo(false); - assertThat(Objects.requireNonNull(result.getBody()).getDisabledAt()).isNull(); - } - - @Test - void postToDisableAfterEnableChaosMonkey() { - testRestTemplate.postForEntity(baseUrl + "/enable", null, ChaosMonkeyStatusResponseDto.class); - - OffsetDateTime disabledAt = OffsetDateTime.now().withNano(0); - ResponseEntity result = - testRestTemplate.postForEntity( - baseUrl + "/disable", null, ChaosMonkeyStatusResponseDto.class); - - assertEquals(HttpStatus.OK, result.getStatusCode()); - assertThat(Objects.requireNonNull(result.getBody()).isEnabled()).isEqualTo(false); - assertThat(Objects.requireNonNull(result.getBody()).getDisabledAt()) - .isAfterOrEqualTo(disabledAt); - } - - private ResponseEntity postChaosMonkeySettings(ChaosMonkeySettings chaosMonkeySettings) { - - return this.testRestTemplate.postForEntity(baseUrl, chaosMonkeySettings, String.class); - } - - private ResponseEntity postHttpEntity(HttpEntity value) { - - return this.testRestTemplate.postForEntity(baseUrl, value, String.class); - } + // Watcher Tests + @Test + void getWatcherConfiguration() { + ResponseEntity result = testRestTemplate.getForEntity(baseUrl + "/watchers", WatcherProperties.class); + + assertEquals(HttpStatus.OK, result.getStatusCode()); + assertEquals(chaosMonkeySettings.getWatcherProperties().toString(), result.getBody().toString()); + } + + @Test + void postWatcherConfigurationGoodCase() { + + WatcherPropertiesUpdate watcherProperties = new WatcherPropertiesUpdate(); + watcherProperties.setService(true); + + ResponseEntity result = testRestTemplate.postForEntity(baseUrl + "/watchers", watcherProperties, String.class); + + assertEquals(HttpStatus.OK, result.getStatusCode()); + assertEquals("Watcher config has changed", result.getBody()); + } + + // Assault Tests + @Test + void getAssaultConfiguration() throws JsonProcessingException { + ResponseEntity result = testRestTemplate.getForEntity(baseUrl + "/assaults", AssaultPropertiesUpdate.class); + + assertEquals(HttpStatus.OK, result.getStatusCode()); + assertEquals(objectMapper.writeValueAsString(chaosMonkeySettings.getAssaultProperties()), objectMapper.writeValueAsString(result.getBody())); + } + + @Test + void postAssaultConfigurationGoodCase() { + AssaultPropertiesUpdate assaultProperties = new AssaultPropertiesUpdate(); + assaultProperties.setLevel(10); + assaultProperties.setLatencyRangeStart(100); + assaultProperties.setLatencyRangeEnd(200); + assaultProperties.setLatencyActive(true); + assaultProperties.setExceptionsActive(false); + assaultProperties.setException(new AssaultException()); + + // Do not set memory properties - optional :) + ResponseEntity result = testRestTemplate.postForEntity(baseUrl + "/assaults", assaultProperties, String.class); + + assertEquals(HttpStatus.OK, result.getStatusCode()); + assertEquals("Assault config has changed", result.getBody()); + } + + @Test + void postMinimalUpdate() { + @Data + class MinimalSubmission { + + private int level = 10; + } + + ResponseEntity result = testRestTemplate.postForEntity(baseUrl + "/assaults", new MinimalSubmission(), String.class); + + assertEquals(HttpStatus.OK, result.getStatusCode()); + assertEquals("Assault config has changed", result.getBody()); + } + + @Test + void postAssaultConfigurationBadCaseLevelEmpty() { + AssaultPropertiesUpdate assaultProperties = new AssaultPropertiesUpdate(); + assaultProperties.setLatencyRangeEnd(100); + assaultProperties.setLatencyRangeStart(200); + assaultProperties.setLatencyActive(true); + + ResponseEntity result = testRestTemplate.postForEntity(baseUrl + "/assaults", assaultProperties, String.class); + + assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode()); + } + + @Test + void postAssaultConfigurationBadCaseLatencyRangeEndEmpty() { + AssaultPropertiesUpdate assaultProperties = new AssaultPropertiesUpdate(); + assaultProperties.setLevel(1000); + assaultProperties.setLatencyRangeStart(200); + assaultProperties.setLatencyActive(true); + + ResponseEntity result = testRestTemplate.postForEntity(baseUrl + "/assaults", assaultProperties, String.class); + + assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode()); + } + + @Test + void postAssaultConfigurationBadCaseLatencyRangeStartEmpty() { + AssaultPropertiesUpdate assaultProperties = new AssaultPropertiesUpdate(); + assaultProperties.setLevel(1000); + assaultProperties.setLatencyRangeEnd(200); + assaultProperties.setLatencyActive(true); + + ResponseEntity result = testRestTemplate.postForEntity(baseUrl + "/assaults", assaultProperties, String.class); + + assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode()); + } + + @Test + void postAssaultConfigurationBadCaseInvalidExceptionType() { + AssaultException exception = new AssaultException(); + exception.setType("SomeInvalidException"); + + AssaultPropertiesUpdate assaultProperties = new AssaultPropertiesUpdate(); + assaultProperties.setLevel(10); + assaultProperties.setLatencyRangeEnd(100); + assaultProperties.setLatencyRangeStart(200); + assaultProperties.setLatencyActive(true); + assaultProperties.setExceptionsActive(false); + assaultProperties.setException(exception); + + ResponseEntity result = testRestTemplate.postForEntity(baseUrl + "/assaults", assaultProperties, String.class); + + assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode()); + } + + // STATUS + @Test + void getStatusIsEnabled() { + chaosMonkeySettings.getChaosMonkeyProperties().setEnabled(true); + + ResponseEntity result = testRestTemplate.getForEntity(baseUrl + "/status", ChaosMonkeyStatusResponseDto.class); + + assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(result.getBody().isEnabled()).isTrue(); + } + + @Test + void getStatusIsDisabled() { + chaosMonkeySettings.getChaosMonkeyProperties().setEnabled(false); + + ResponseEntity result = testRestTemplate.getForEntity(baseUrl + "/status", ChaosMonkeyStatusResponseDto.class); + + assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(result.getBody().isEnabled()).isFalse(); + } + + // ENABLE CHAOS MONKEY + + @Test + void postToEnableChaosMonkey() { + OffsetDateTime enabledAt = OffsetDateTime.now().withNano(0); + ResponseEntity result = testRestTemplate.postForEntity(baseUrl + "/enable", null, + ChaosMonkeyStatusResponseDto.class); + + assertEquals(HttpStatus.OK, result.getStatusCode()); + assertThat(Objects.requireNonNull(result.getBody()).isEnabled()).isTrue(); + assertThat(Objects.requireNonNull(result.getBody()).getEnabledAt()).isAfterOrEqualTo(enabledAt); + } + + // DISABLE CHAOS MONKEY + @Test + void postToDisableChaosMonkey() { + ResponseEntity result = testRestTemplate.postForEntity(baseUrl + "/disable", null, + ChaosMonkeyStatusResponseDto.class); + + assertEquals(HttpStatus.OK, result.getStatusCode()); + assertThat(Objects.requireNonNull(result.getBody()).isEnabled()).isEqualTo(false); + assertThat(Objects.requireNonNull(result.getBody()).getDisabledAt()).isNull(); + } + + @Test + void postToDisableAfterEnableChaosMonkey() { + testRestTemplate.postForEntity(baseUrl + "/enable", null, ChaosMonkeyStatusResponseDto.class); + + OffsetDateTime disabledAt = OffsetDateTime.now().withNano(0); + ResponseEntity result = testRestTemplate.postForEntity(baseUrl + "/disable", null, + ChaosMonkeyStatusResponseDto.class); + + assertEquals(HttpStatus.OK, result.getStatusCode()); + assertThat(Objects.requireNonNull(result.getBody()).isEnabled()).isEqualTo(false); + assertThat(Objects.requireNonNull(result.getBody()).getDisabledAt()).isAfterOrEqualTo(disabledAt); + } + + private ResponseEntity postChaosMonkeySettings(ChaosMonkeySettings chaosMonkeySettings) { + + return this.testRestTemplate.postForEntity(baseUrl, chaosMonkeySettings, String.class); + } + + private ResponseEntity postHttpEntity(HttpEntity value) { + + return this.testRestTemplate.postForEntity(baseUrl, value, String.class); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRestEndpointTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRestEndpointTest.java index 625a7dc8..89e1acd3 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRestEndpointTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/ChaosMonkeyRestEndpointTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.endpoints; import static org.mockito.Mockito.times; @@ -23,49 +38,45 @@ @ActiveProfiles("chaos-monkey") @ContextConfiguration(classes = {ChaosDemoApplication.class}) -@SpringBootTest( - webEnvironment = WebEnvironment.RANDOM_PORT, - properties = { - "management.endpoint.chaosmonkey.enabled=true", - "management.endpoints.web.exposure.include=chaosmonkey", - "management.endpoints.enabled-by-default=true" - }) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {"management.endpoint.chaosmonkey.enabled=true", + "management.endpoints.web.exposure.include=chaosmonkey", "management.endpoints.enabled-by-default=true"}) public class ChaosMonkeyRestEndpointTest { - @Autowired private TestRestTemplate testRestTemplate; - @MockBean private ChaosMonkeySettings chaosMonkeySettings; - @MockBean private ChaosMonkeyScheduler chaosMonkeyScheduler; + @Autowired + private TestRestTemplate testRestTemplate; + @MockBean + private ChaosMonkeySettings chaosMonkeySettings; + @MockBean + private ChaosMonkeyScheduler chaosMonkeyScheduler; - @Test - public void testWatcherPropertiesUpdateApplied() { - final WatcherPropertiesUpdate watcherPropertiesUpdate = new WatcherPropertiesUpdate(); - watcherPropertiesUpdate.setController(Boolean.TRUE); - watcherPropertiesUpdate.setRestController(Boolean.TRUE); - watcherPropertiesUpdate.setComponent(Boolean.TRUE); - watcherPropertiesUpdate.setService(Boolean.TRUE); - watcherPropertiesUpdate.setRepository(Boolean.TRUE); - watcherPropertiesUpdate.setRestTemplate(Boolean.TRUE); - watcherPropertiesUpdate.setWebClient(Boolean.TRUE); - watcherPropertiesUpdate.setActuatorHealth(Boolean.TRUE); + @Test + public void testWatcherPropertiesUpdateApplied() { + final WatcherPropertiesUpdate watcherPropertiesUpdate = new WatcherPropertiesUpdate(); + watcherPropertiesUpdate.setController(Boolean.TRUE); + watcherPropertiesUpdate.setRestController(Boolean.TRUE); + watcherPropertiesUpdate.setComponent(Boolean.TRUE); + watcherPropertiesUpdate.setService(Boolean.TRUE); + watcherPropertiesUpdate.setRepository(Boolean.TRUE); + watcherPropertiesUpdate.setRestTemplate(Boolean.TRUE); + watcherPropertiesUpdate.setWebClient(Boolean.TRUE); + watcherPropertiesUpdate.setActuatorHealth(Boolean.TRUE); - final WatcherProperties watcherProperties = new WatcherProperties(); + final WatcherProperties watcherProperties = new WatcherProperties(); - when(chaosMonkeySettings.getWatcherProperties()).thenReturn(watcherProperties); + when(chaosMonkeySettings.getWatcherProperties()).thenReturn(watcherProperties); - ResponseEntity response = - testRestTemplate.postForEntity( - "/actuator/chaosmonkey/watchers", watcherPropertiesUpdate, String.class); + ResponseEntity response = testRestTemplate.postForEntity("/actuator/chaosmonkey/watchers", watcherPropertiesUpdate, String.class); - BDDAssertions.then(response.getStatusCode()).isEqualTo(HttpStatus.OK); - BDDAssertions.then(watcherProperties.isController()).isTrue(); - BDDAssertions.then(watcherProperties.isRestController()).isTrue(); - BDDAssertions.then(watcherProperties.isComponent()).isTrue(); - BDDAssertions.then(watcherProperties.isService()).isTrue(); - BDDAssertions.then(watcherProperties.isRepository()).isTrue(); - BDDAssertions.then(watcherProperties.isRestTemplate()).isTrue(); - BDDAssertions.then(watcherProperties.isWebClient()).isTrue(); - BDDAssertions.then(watcherProperties.isActuatorHealth()).isTrue(); + BDDAssertions.then(response.getStatusCode()).isEqualTo(HttpStatus.OK); + BDDAssertions.then(watcherProperties.isController()).isTrue(); + BDDAssertions.then(watcherProperties.isRestController()).isTrue(); + BDDAssertions.then(watcherProperties.isComponent()).isTrue(); + BDDAssertions.then(watcherProperties.isService()).isTrue(); + BDDAssertions.then(watcherProperties.isRepository()).isTrue(); + BDDAssertions.then(watcherProperties.isRestTemplate()).isTrue(); + BDDAssertions.then(watcherProperties.isWebClient()).isTrue(); + BDDAssertions.then(watcherProperties.isActuatorHealth()).isTrue(); - verify(chaosMonkeyScheduler, times(1)).reloadConfig(); - } + verify(chaosMonkeyScheduler, times(1)).reloadConfig(); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultPropertiesLatencyRangeValidatorTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultPropertiesLatencyRangeValidatorTest.java index 7dc46e90..fc2ba0ac 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultPropertiesLatencyRangeValidatorTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/endpoints/dto/validation/AssaultPropertiesLatencyRangeValidatorTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2019-2022 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 + * + * https://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.spring.boot.chaos.monkey.endpoints.dto.validation; import static org.assertj.core.api.Assertions.assertThat; @@ -7,46 +22,44 @@ class AssaultPropertiesUpdateLatencyRangeValidatorTest { - final AssaultPropertiesUpdateLatencyRangeValidator assaultPropertiesValidator = - new AssaultPropertiesUpdateLatencyRangeValidator(); - - @Test - void rangeStartSmallerThanRangeEndIsValid() { - validateRange(1000, 1001, true); - } - - @Test - void rangeStartAsBigAsRangeEndIsValid() { - validateRange(1000, 1000, true); - } - - @Test - void rangeStartBiggerThanRangeEndIsNotValid() { - validateRange(1001, 1000, false); - } - - @Test - void noRangeIsValid() { - validateRange(null, null, true); - } - - @Test - void onlyRangeStartIsNotValid() { - validateRange(1000, null, false); - } - - @Test - void onlyRangeEndIsNotValid() { - validateRange(null, 1000, false); - } - - private void validateRange( - final Integer rangeStart, final Integer rangeEnd, final boolean expectedValidationResult) { - final AssaultPropertiesUpdate assaultProperties = new AssaultPropertiesUpdate(); - assaultProperties.setLatencyRangeStart(rangeStart); - assaultProperties.setLatencyRangeEnd(rangeEnd); - - final boolean valid = assaultPropertiesValidator.isValid(assaultProperties, null); - assertThat(valid).isEqualTo(expectedValidationResult); - } + final AssaultPropertiesUpdateLatencyRangeValidator assaultPropertiesValidator = new AssaultPropertiesUpdateLatencyRangeValidator(); + + @Test + void rangeStartSmallerThanRangeEndIsValid() { + validateRange(1000, 1001, true); + } + + @Test + void rangeStartAsBigAsRangeEndIsValid() { + validateRange(1000, 1000, true); + } + + @Test + void rangeStartBiggerThanRangeEndIsNotValid() { + validateRange(1001, 1000, false); + } + + @Test + void noRangeIsValid() { + validateRange(null, null, true); + } + + @Test + void onlyRangeStartIsNotValid() { + validateRange(1000, null, false); + } + + @Test + void onlyRangeEndIsNotValid() { + validateRange(null, 1000, false); + } + + private void validateRange(final Integer rangeStart, final Integer rangeEnd, final boolean expectedValidationResult) { + final AssaultPropertiesUpdate assaultProperties = new AssaultPropertiesUpdate(); + assaultProperties.setLatencyRangeStart(rangeStart); + assaultProperties.setLatencyRangeEnd(rangeEnd); + + final boolean valid = assaultPropertiesValidator.isValid(assaultProperties, null); + assertThat(valid).isEqualTo(expectedValidationResult); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/ChaosMonkeyBeanPostProcessorTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/ChaosMonkeyBeanPostProcessorTest.java index b1394fdf..4190b812 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/ChaosMonkeyBeanPostProcessorTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/ChaosMonkeyBeanPostProcessorTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.watcher.aspect; import static org.mockito.Mockito.*; @@ -18,60 +33,62 @@ @ExtendWith(MockitoExtension.class) public class ChaosMonkeyBeanPostProcessorTest { - private DemoBean target = new DemoBean(); + private DemoBean target = new DemoBean(); - private WatcherProperties watcherProperties = new WatcherProperties(); + private WatcherProperties watcherProperties = new WatcherProperties(); - @Mock private ChaosMonkeyRequestScope requestScope; + @Mock + private ChaosMonkeyRequestScope requestScope; - @Mock private MetricEventPublisher metrics; + @Mock + private MetricEventPublisher metrics; - private ChaosMonkeyBeanPostProcessor postProcessor; + private ChaosMonkeyBeanPostProcessor postProcessor; - private String pointcutName = "execution.DemoBean.sayHello"; + private String pointcutName = "execution.DemoBean.sayHello"; - private String simpleName = "de.codecentric.spring.boot.demo.chaos.monkey.bean.DemoBean.sayHello"; + private String simpleName = "de.codecentric.spring.boot.demo.chaos.monkey.bean.DemoBean.sayHello"; - @BeforeEach - void setup() { - postProcessor = new ChaosMonkeyBeanPostProcessor(watcherProperties, requestScope, metrics); - } + @BeforeEach + void setup() { + postProcessor = new ChaosMonkeyBeanPostProcessor(watcherProperties, requestScope, metrics); + } - @Test - void chaosMonkeyIsCalledWhenEnabledInConfig() { - watcherProperties.setBeans(Collections.singletonList("demoBean")); + @Test + void chaosMonkeyIsCalledWhenEnabledInConfig() { + watcherProperties.setBeans(Collections.singletonList("demoBean")); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(1); - } + verifyDependenciesCalledXTimes(1); + } - @Test - void chaosMonkeyIsNotCalledWhenDisabledInConfig() { - watcherProperties.setBeans(Collections.emptyList()); + @Test + void chaosMonkeyIsNotCalledWhenDisabledInConfig() { + watcherProperties.setBeans(Collections.emptyList()); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(0); - } + verifyDependenciesCalledXTimes(0); + } - @Test - void chaosMonkeyIsNotCalledWithUnrelatedBeansInConfig() { - watcherProperties.setBeans(Collections.singletonList("demoComponent")); + @Test + void chaosMonkeyIsNotCalledWithUnrelatedBeansInConfig() { + watcherProperties.setBeans(Collections.singletonList("demoComponent")); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(0); - } + verifyDependenciesCalledXTimes(0); + } - private void callTargetMethod() { - DemoBean proxy = (DemoBean) postProcessor.postProcessAfterInitialization(target, "demoBean"); - proxy.sayHello(); - } + private void callTargetMethod() { + DemoBean proxy = (DemoBean) postProcessor.postProcessAfterInitialization(target, "demoBean"); + proxy.sayHello(); + } - private void verifyDependenciesCalledXTimes(int i) { - verify(requestScope, times(i)).callChaosMonkey(ChaosTarget.BEAN, simpleName); - verify(metrics, times(i)).publishMetricEvent(pointcutName, MetricType.BEAN); - verifyNoMoreInteractions(requestScope, metrics); - } + private void verifyDependenciesCalledXTimes(int i) { + verify(requestScope, times(i)).callChaosMonkey(ChaosTarget.BEAN, simpleName); + verify(metrics, times(i)).publishMetricEvent(pointcutName, MetricType.BEAN); + verifyNoMoreInteractions(requestScope, metrics); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringBootHealthIndicatorAspectIntegrationTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringBootHealthIndicatorAspectIntegrationTest.java index 9bdbd7f0..b6e35593 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringBootHealthIndicatorAspectIntegrationTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringBootHealthIndicatorAspectIntegrationTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.watcher.aspect; import static org.assertj.core.api.Assertions.assertThat; @@ -14,49 +29,37 @@ class SpringBootHealthIndicatorAspectIntegrationTest { - @SpringBootTest( - properties = { - "chaos.monkey.enabled=true", - "chaos.monkey.watcher.actuator-health=true", - "chaos.monkey.assaults.exceptions-active=true" - }, - classes = {ChaosDemoApplication.class}) - @ActiveProfiles("chaos-monkey") - @Nested - class HealthIndicatorEnabledIntegrationTest { - - @Autowired private List healthIndicators; - - @Test - public void testIndicatorsAreDown() { - this.healthIndicators.forEach( - healthIndicator -> { - assertThat(healthIndicator.getHealth(Boolean.TRUE).getStatus()) - .isEqualTo(Health.down().build().getStatus()); - }); + @SpringBootTest(properties = {"chaos.monkey.enabled=true", "chaos.monkey.watcher.actuator-health=true", + "chaos.monkey.assaults.exceptions-active=true"}, classes = {ChaosDemoApplication.class}) + @ActiveProfiles("chaos-monkey") + @Nested + class HealthIndicatorEnabledIntegrationTest { + + @Autowired + private List healthIndicators; + + @Test + public void testIndicatorsAreDown() { + this.healthIndicators.forEach(healthIndicator -> { + assertThat(healthIndicator.getHealth(Boolean.TRUE).getStatus()).isEqualTo(Health.down().build().getStatus()); + }); + } } - } - - @SpringBootTest( - properties = { - "chaos.monkey.enabled=true", - "chaos.monkey.watcher.actuator-health=false", - "chaos.monkey.assaults.exceptions-active=true" - }, - classes = {ChaosDemoApplication.class}) - @ActiveProfiles("chaos-monkey") - @Nested - class HealthIndicatorDisabledIntegrationTest { - - @Autowired private List healthIndicators; - - @Test - public void testIndicatorsAreDown() { - this.healthIndicators.forEach( - healthIndicator -> { - assertThat(healthIndicator.getHealth(Boolean.TRUE).getStatus()) - .isEqualTo(Health.up().build().getStatus()); - }); + + @SpringBootTest(properties = {"chaos.monkey.enabled=true", "chaos.monkey.watcher.actuator-health=false", + "chaos.monkey.assaults.exceptions-active=true"}, classes = {ChaosDemoApplication.class}) + @ActiveProfiles("chaos-monkey") + @Nested + class HealthIndicatorDisabledIntegrationTest { + + @Autowired + private List healthIndicators; + + @Test + public void testIndicatorsAreDown() { + this.healthIndicators.forEach(healthIndicator -> { + assertThat(healthIndicator.getHealth(Boolean.TRUE).getStatus()).isEqualTo(Health.up().build().getStatus()); + }); + } } - } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringComponentAspectIntegrationTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringComponentAspectIntegrationTest.java index 36c9bdfc..88cedc65 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringComponentAspectIntegrationTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringComponentAspectIntegrationTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2020 the original author or authors. + * Copyright 2020-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.watcher.aspect; import static org.mockito.Mockito.mock; @@ -42,134 +41,117 @@ @SpringBootTest class SpringComponentAspectIntegrationTest { - private static final String demoComponentPointcutName = "execution.DemoComponent.sayHello"; - private static final String finalDemoComponentPointcutName = - "execution.FinalDemoComponent.sayHello"; - private static final String beanPostProcessorComponentPointcutName = - "execution.BeanPostProcessorComponent.postProcessBeforeInitialization"; - private static final String applicationListenerComponentPointcutName = - "execution.ApplicationListenerComponent.onApplicationEvent"; - private static final String beanFactorySingletonComponentPointcutName = - "execution.FactoryBeanComponent.isSingleton"; - private static final String beanFactoryObjectTypeComponentPointcutName = - "execution.FactoryBeanComponent.getObjectType"; - - private static final String demoComponentSimpleName = - "de.codecentric.spring.boot.demo.chaos.monkey.component.DemoComponent.sayHello"; - private static final String finalDemoComponentSimpleName = - "de.codecentric.spring.boot.demo.chaos.monkey.component.FinalDemoComponent.sayHello"; - private static final String beanPostProcessorComponentSimpleName = - "de.codecentric.spring.boot.demo.chaos.monkey.component.BeanPostProcessorComponent.postProcessBeforeInitialization"; - private static final String applicationListenerComponentSimpleName = - "de.codecentric.spring.boot.demo.chaos.monkey.component.ApplicationListenerComponent.onApplicationEvent"; - private static final String beanFactorySingletonComponentSimpleName = - "de.codecentric.spring.boot.demo.chaos.monkey.component.BeanFactoryComponent.isSingleton"; - private static final String beanFactoryObjectTypeComponentSimpleName = - "de.codecentric.spring.boot.demo.chaos.monkey.component.BeanFactoryComponent.getObjectType"; - - @Autowired DemoComponent demoComponent; - - @Autowired FinalDemoComponent finalDemoComponent; - - @Autowired BeanPostProcessorComponent beanPostProcessorComponent; - - @Autowired ApplicationListenerComponent applicationListenerComponent; - - @Autowired ChaosMonkeyRequestScope chaosMonkeyRequestScopeMock; - - @Autowired MetricEventPublisher metricsMock; - - @Autowired FactoryBeanComponent factoryBeanComponent; - - @Test - public void chaosMonkeyIsCalledWhenComponentIsNotFinal() { - demoComponent.sayHello(); - verify(chaosMonkeyRequestScopeMock, times(1)) - .callChaosMonkey(ChaosTarget.COMPONENT, demoComponentSimpleName); - verify(metricsMock, times(1)) - .publishMetricEvent(demoComponentPointcutName, MetricType.COMPONENT); - } - - @Test - public void chaosMonkeyIsNotCalledWhenComponentIsFinal() { - finalDemoComponent.sayHello(); - verify(chaosMonkeyRequestScopeMock, times(0)) - .callChaosMonkey(ChaosTarget.COMPONENT, finalDemoComponentSimpleName); - verify(metricsMock, times(0)) - .publishMetricEvent(finalDemoComponentPointcutName, MetricType.COMPONENT); - } - - @Test - public void chaosMonkeyDoesNotProxyIgnoredSpringInterfaces() { - beanPostProcessorComponent.postProcessBeforeInitialization(new Object(), "fakeBean"); - applicationListenerComponent.onApplicationEvent(mock(ApplicationEvent.class)); - factoryBeanComponent.getObject(); - - verify(chaosMonkeyRequestScopeMock, times(0)) - .callChaosMonkey(null, beanPostProcessorComponentSimpleName); - verify(metricsMock, times(0)) - .publishMetricEvent(beanPostProcessorComponentPointcutName, MetricType.COMPONENT); - - verify(chaosMonkeyRequestScopeMock, times(0)) - .callChaosMonkey(null, applicationListenerComponentSimpleName); - verify(metricsMock, times(0)) - .publishMetricEvent(applicationListenerComponentPointcutName, MetricType.COMPONENT); - - verify(chaosMonkeyRequestScopeMock, times(0)) - .callChaosMonkey(null, beanFactorySingletonComponentSimpleName); - verify(chaosMonkeyRequestScopeMock, times(0)) - .callChaosMonkey(null, beanFactoryObjectTypeComponentSimpleName); - verify(metricsMock, times(0)) - .publishMetricEvent(beanFactorySingletonComponentPointcutName, MetricType.COMPONENT); - verify(metricsMock, times(0)) - .publishMetricEvent(beanFactoryObjectTypeComponentPointcutName, MetricType.COMPONENT); - } - - @Configuration - @EnableAspectJAutoProxy(proxyTargetClass = true) - public static class TestContext { - - @Bean - public ChaosMonkeyRequestScope chaosMonkeyRequestScopeMock() { - return mock(ChaosMonkeyRequestScope.class); - } + private static final String demoComponentPointcutName = "execution.DemoComponent.sayHello"; + private static final String finalDemoComponentPointcutName = "execution.FinalDemoComponent.sayHello"; + private static final String beanPostProcessorComponentPointcutName = "execution.BeanPostProcessorComponent.postProcessBeforeInitialization"; + private static final String applicationListenerComponentPointcutName = "execution.ApplicationListenerComponent.onApplicationEvent"; + private static final String beanFactorySingletonComponentPointcutName = "execution.FactoryBeanComponent.isSingleton"; + private static final String beanFactoryObjectTypeComponentPointcutName = "execution.FactoryBeanComponent.getObjectType"; - @Bean - public MetricEventPublisher metricsMock() { - return mock(MetricEventPublisher.class); - } + private static final String demoComponentSimpleName = "de.codecentric.spring.boot.demo.chaos.monkey.component.DemoComponent.sayHello"; + private static final String finalDemoComponentSimpleName = "de.codecentric.spring.boot.demo.chaos.monkey.component.FinalDemoComponent.sayHello"; + private static final String beanPostProcessorComponentSimpleName = "de.codecentric.spring.boot.demo.chaos.monkey.component.BeanPostProcessorComponent.postProcessBeforeInitialization"; + private static final String applicationListenerComponentSimpleName = "de.codecentric.spring.boot.demo.chaos.monkey.component.ApplicationListenerComponent.onApplicationEvent"; + private static final String beanFactorySingletonComponentSimpleName = "de.codecentric.spring.boot.demo.chaos.monkey.component.BeanFactoryComponent.isSingleton"; + private static final String beanFactoryObjectTypeComponentSimpleName = "de.codecentric.spring.boot.demo.chaos.monkey.component.BeanFactoryComponent.getObjectType"; - @Bean - SpringComponentAspect aspect() { - WatcherProperties watcherProperties = new WatcherProperties(); - watcherProperties.setComponent(true); - return new SpringComponentAspect( - chaosMonkeyRequestScopeMock(), metricsMock(), watcherProperties); - } + @Autowired + DemoComponent demoComponent; - @Bean - DemoComponent demoComponent() { - return mock(DemoComponent.class); - } + @Autowired + FinalDemoComponent finalDemoComponent; + + @Autowired + BeanPostProcessorComponent beanPostProcessorComponent; + + @Autowired + ApplicationListenerComponent applicationListenerComponent; - @Bean - FinalDemoComponent finalDemoComponent() { - return mock(FinalDemoComponent.class); + @Autowired + ChaosMonkeyRequestScope chaosMonkeyRequestScopeMock; + + @Autowired + MetricEventPublisher metricsMock; + + @Autowired + FactoryBeanComponent factoryBeanComponent; + + @Test + public void chaosMonkeyIsCalledWhenComponentIsNotFinal() { + demoComponent.sayHello(); + verify(chaosMonkeyRequestScopeMock, times(1)).callChaosMonkey(ChaosTarget.COMPONENT, demoComponentSimpleName); + verify(metricsMock, times(1)).publishMetricEvent(demoComponentPointcutName, MetricType.COMPONENT); } - @Bean - BeanPostProcessorComponent beanPostProcessorComponent() { - return mock(BeanPostProcessorComponent.class); + @Test + public void chaosMonkeyIsNotCalledWhenComponentIsFinal() { + finalDemoComponent.sayHello(); + verify(chaosMonkeyRequestScopeMock, times(0)).callChaosMonkey(ChaosTarget.COMPONENT, finalDemoComponentSimpleName); + verify(metricsMock, times(0)).publishMetricEvent(finalDemoComponentPointcutName, MetricType.COMPONENT); } - @Bean - FactoryBeanComponent factoryBeanComponent() { - return mock(FactoryBeanComponent.class); + @Test + public void chaosMonkeyDoesNotProxyIgnoredSpringInterfaces() { + beanPostProcessorComponent.postProcessBeforeInitialization(new Object(), "fakeBean"); + applicationListenerComponent.onApplicationEvent(mock(ApplicationEvent.class)); + factoryBeanComponent.getObject(); + + verify(chaosMonkeyRequestScopeMock, times(0)).callChaosMonkey(null, beanPostProcessorComponentSimpleName); + verify(metricsMock, times(0)).publishMetricEvent(beanPostProcessorComponentPointcutName, MetricType.COMPONENT); + + verify(chaosMonkeyRequestScopeMock, times(0)).callChaosMonkey(null, applicationListenerComponentSimpleName); + verify(metricsMock, times(0)).publishMetricEvent(applicationListenerComponentPointcutName, MetricType.COMPONENT); + + verify(chaosMonkeyRequestScopeMock, times(0)).callChaosMonkey(null, beanFactorySingletonComponentSimpleName); + verify(chaosMonkeyRequestScopeMock, times(0)).callChaosMonkey(null, beanFactoryObjectTypeComponentSimpleName); + verify(metricsMock, times(0)).publishMetricEvent(beanFactorySingletonComponentPointcutName, MetricType.COMPONENT); + verify(metricsMock, times(0)).publishMetricEvent(beanFactoryObjectTypeComponentPointcutName, MetricType.COMPONENT); } - @Bean - ApplicationListenerComponent applicationListenerComponent() { - return mock(ApplicationListenerComponent.class); + @Configuration + @EnableAspectJAutoProxy(proxyTargetClass = true) + public static class TestContext { + + @Bean + public ChaosMonkeyRequestScope chaosMonkeyRequestScopeMock() { + return mock(ChaosMonkeyRequestScope.class); + } + + @Bean + public MetricEventPublisher metricsMock() { + return mock(MetricEventPublisher.class); + } + + @Bean + SpringComponentAspect aspect() { + WatcherProperties watcherProperties = new WatcherProperties(); + watcherProperties.setComponent(true); + return new SpringComponentAspect(chaosMonkeyRequestScopeMock(), metricsMock(), watcherProperties); + } + + @Bean + DemoComponent demoComponent() { + return mock(DemoComponent.class); + } + + @Bean + FinalDemoComponent finalDemoComponent() { + return mock(FinalDemoComponent.class); + } + + @Bean + BeanPostProcessorComponent beanPostProcessorComponent() { + return mock(BeanPostProcessorComponent.class); + } + + @Bean + FactoryBeanComponent factoryBeanComponent() { + return mock(FactoryBeanComponent.class); + } + + @Bean + ApplicationListenerComponent applicationListenerComponent() { + return mock(ApplicationListenerComponent.class); + } } - } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringComponentAspectTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringComponentAspectTest.java index 035789ed..a10fde93 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringComponentAspectTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringComponentAspectTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.watcher.aspect; import static org.mockito.Mockito.times; @@ -36,92 +35,87 @@ @ExtendWith(MockitoExtension.class) class SpringComponentAspectTest { - private DemoComponent target = new DemoComponent(); + private DemoComponent target = new DemoComponent(); - private WatcherProperties watcherProperties = new WatcherProperties(); + private WatcherProperties watcherProperties = new WatcherProperties(); - private AspectJProxyFactory factory = new AspectJProxyFactory(target); + private AspectJProxyFactory factory = new AspectJProxyFactory(target); - @Mock private ChaosMonkeyRequestScope chaosMonkeyRequestScopeMock; + @Mock + private ChaosMonkeyRequestScope chaosMonkeyRequestScopeMock; - @Mock private MetricEventPublisher metricsMock; + @Mock + private MetricEventPublisher metricsMock; - private String pointcutName = "execution.DemoComponent.sayHello"; + private String pointcutName = "execution.DemoComponent.sayHello"; - private String simpleName = - "de.codecentric.spring.boot.demo.chaos.monkey.component.DemoComponent.sayHello"; + private String simpleName = "de.codecentric.spring.boot.demo.chaos.monkey.component.DemoComponent.sayHello"; - @Test - void chaosMonkeyIsCalledWhenEnabledInConfig() { - watcherProperties.setComponent(true); + @Test + void chaosMonkeyIsCalledWhenEnabledInConfig() { + watcherProperties.setComponent(true); - addRelevantAspect(); + addRelevantAspect(); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(1); - } + verifyDependenciesCalledXTimes(1); + } - @Test - void chaosMonkeyIsNotCalledWhenDisabledInConfig() { - watcherProperties.setComponent(false); + @Test + void chaosMonkeyIsNotCalledWhenDisabledInConfig() { + watcherProperties.setComponent(false); - addRelevantAspect(); + addRelevantAspect(); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(0); - } + verifyDependenciesCalledXTimes(0); + } - @Test - void chaosMonkeyIsNotCalledByAspectsWithUnrelatedPointcuts() { - watcherProperties.setService(true); - watcherProperties.setComponent(true); - watcherProperties.setController(true); - watcherProperties.setRepository(true); - watcherProperties.setRestController(true); + @Test + void chaosMonkeyIsNotCalledByAspectsWithUnrelatedPointcuts() { + watcherProperties.setService(true); + watcherProperties.setComponent(true); + watcherProperties.setController(true); + watcherProperties.setRepository(true); + watcherProperties.setRestController(true); - addNonRelevantAspects(); + addNonRelevantAspects(); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(0); - } + verifyDependenciesCalledXTimes(0); + } - private void addRelevantAspect() { - SpringComponentAspect componentAspect = - new SpringComponentAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - factory.addAspect(componentAspect); - } + private void addRelevantAspect() { + SpringComponentAspect componentAspect = new SpringComponentAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + factory.addAspect(componentAspect); + } - private void addNonRelevantAspects() { - SpringControllerAspect controllerAspect = - new SpringControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringRestControllerAspect restControllerAspect = - new SpringRestControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringRepositoryAspectJPA repositoryAspect = - new SpringRepositoryAspectJPA(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringServiceAspect serviceAspect = - new SpringServiceAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringRepositoryAspectJDBC repositoryStereotypeAspect = - new SpringRepositoryAspectJDBC(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + private void addNonRelevantAspects() { + SpringControllerAspect controllerAspect = new SpringControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringRestControllerAspect restControllerAspect = new SpringRestControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringRepositoryAspectJPA repositoryAspect = new SpringRepositoryAspectJPA(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringServiceAspect serviceAspect = new SpringServiceAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringRepositoryAspectJDBC repositoryStereotypeAspect = new SpringRepositoryAspectJDBC(chaosMonkeyRequestScopeMock, metricsMock, + watcherProperties); - factory.addAspect(controllerAspect); - factory.addAspect(restControllerAspect); - factory.addAspect(repositoryAspect); - factory.addAspect(serviceAspect); - factory.addAspect(repositoryStereotypeAspect); - } + factory.addAspect(controllerAspect); + factory.addAspect(restControllerAspect); + factory.addAspect(repositoryAspect); + factory.addAspect(serviceAspect); + factory.addAspect(repositoryStereotypeAspect); + } - private void callTargetMethod() { - DemoComponent proxy = factory.getProxy(); - proxy.sayHello(); - } + private void callTargetMethod() { + DemoComponent proxy = factory.getProxy(); + proxy.sayHello(); + } - private void verifyDependenciesCalledXTimes(int i) { - verify(chaosMonkeyRequestScopeMock, times(i)) - .callChaosMonkey(ChaosTarget.COMPONENT, simpleName); - verify(metricsMock, times(i)).publishMetricEvent(pointcutName, MetricType.COMPONENT); - verifyNoMoreInteractions(chaosMonkeyRequestScopeMock, metricsMock); - } + private void verifyDependenciesCalledXTimes(int i) { + verify(chaosMonkeyRequestScopeMock, times(i)).callChaosMonkey(ChaosTarget.COMPONENT, simpleName); + verify(metricsMock, times(i)).publishMetricEvent(pointcutName, MetricType.COMPONENT); + verifyNoMoreInteractions(chaosMonkeyRequestScopeMock, metricsMock); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringControllerAspectTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringControllerAspectTest.java index b0f62433..2c1c7044 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringControllerAspectTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringControllerAspectTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.watcher.aspect; import static org.mockito.Mockito.times; @@ -36,92 +35,87 @@ @ExtendWith(MockitoExtension.class) class SpringControllerAspectTest { - private DemoController target = new DemoController(); + private DemoController target = new DemoController(); - private WatcherProperties watcherProperties = new WatcherProperties(); + private WatcherProperties watcherProperties = new WatcherProperties(); - private AspectJProxyFactory factory = new AspectJProxyFactory(target); + private AspectJProxyFactory factory = new AspectJProxyFactory(target); - @Mock private ChaosMonkeyRequestScope chaosMonkeyRequestScopeMock; + @Mock + private ChaosMonkeyRequestScope chaosMonkeyRequestScopeMock; - @Mock private MetricEventPublisher metricsMock; + @Mock + private MetricEventPublisher metricsMock; - private String pointcutName = "execution.DemoController.sayHello"; + private String pointcutName = "execution.DemoController.sayHello"; - private String simpleName = - "de.codecentric.spring.boot.demo.chaos.monkey.controller.DemoController.sayHello"; + private String simpleName = "de.codecentric.spring.boot.demo.chaos.monkey.controller.DemoController.sayHello"; - @Test - void chaosMonkeyIsCalledWhenEnabledInConfig() { - watcherProperties.setController(true); + @Test + void chaosMonkeyIsCalledWhenEnabledInConfig() { + watcherProperties.setController(true); - addRelevantAspect(); + addRelevantAspect(); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(1); - } + verifyDependenciesCalledXTimes(1); + } - @Test - void chaosMonkeyIsNotCalledWhenDisabledInConfig() { - watcherProperties.setController(false); + @Test + void chaosMonkeyIsNotCalledWhenDisabledInConfig() { + watcherProperties.setController(false); - addRelevantAspect(); + addRelevantAspect(); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(0); - } + verifyDependenciesCalledXTimes(0); + } - @Test - void chaosMonkeyIsNotCalledByAspectsWithUnrelatedPointcuts() { - watcherProperties.setService(true); - watcherProperties.setComponent(true); - watcherProperties.setController(true); - watcherProperties.setRepository(true); - watcherProperties.setRestController(true); + @Test + void chaosMonkeyIsNotCalledByAspectsWithUnrelatedPointcuts() { + watcherProperties.setService(true); + watcherProperties.setComponent(true); + watcherProperties.setController(true); + watcherProperties.setRepository(true); + watcherProperties.setRestController(true); - addNonRelevantAspects(); + addNonRelevantAspects(); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(0); - } + verifyDependenciesCalledXTimes(0); + } - private void addRelevantAspect() { - SpringControllerAspect controllerAspect = - new SpringControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - factory.addAspect(controllerAspect); - } + private void addRelevantAspect() { + SpringControllerAspect controllerAspect = new SpringControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + factory.addAspect(controllerAspect); + } - private void addNonRelevantAspects() { - SpringServiceAspect serviceAspect = - new SpringServiceAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringComponentAspect componentAspect = - new SpringComponentAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringRestControllerAspect restControllerAspect = - new SpringRestControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringRepositoryAspectJPA repositoryAspect = - new SpringRepositoryAspectJPA(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringRepositoryAspectJDBC repositoryStereotypeAspect = - new SpringRepositoryAspectJDBC(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + private void addNonRelevantAspects() { + SpringServiceAspect serviceAspect = new SpringServiceAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringComponentAspect componentAspect = new SpringComponentAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringRestControllerAspect restControllerAspect = new SpringRestControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringRepositoryAspectJPA repositoryAspect = new SpringRepositoryAspectJPA(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringRepositoryAspectJDBC repositoryStereotypeAspect = new SpringRepositoryAspectJDBC(chaosMonkeyRequestScopeMock, metricsMock, + watcherProperties); - factory.addAspect(serviceAspect); - factory.addAspect(componentAspect); - factory.addAspect(restControllerAspect); - factory.addAspect(repositoryAspect); - factory.addAspect(repositoryStereotypeAspect); - } + factory.addAspect(serviceAspect); + factory.addAspect(componentAspect); + factory.addAspect(restControllerAspect); + factory.addAspect(repositoryAspect); + factory.addAspect(repositoryStereotypeAspect); + } - private void callTargetMethod() { - DemoController proxy = factory.getProxy(); - proxy.sayHello(); - } + private void callTargetMethod() { + DemoController proxy = factory.getProxy(); + proxy.sayHello(); + } - private void verifyDependenciesCalledXTimes(int i) { - verify(chaosMonkeyRequestScopeMock, times(i)) - .callChaosMonkey(ChaosTarget.CONTROLLER, simpleName); - verify(metricsMock, times(i)).publishMetricEvent(pointcutName, MetricType.CONTROLLER); - verifyNoMoreInteractions(chaosMonkeyRequestScopeMock, metricsMock); - } + private void verifyDependenciesCalledXTimes(int i) { + verify(chaosMonkeyRequestScopeMock, times(i)).callChaosMonkey(ChaosTarget.CONTROLLER, simpleName); + verify(metricsMock, times(i)).publishMetricEvent(pointcutName, MetricType.CONTROLLER); + verifyNoMoreInteractions(chaosMonkeyRequestScopeMock, metricsMock); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectJDBCTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectJDBCTest.java index 609acec6..8a233791 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectJDBCTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectJDBCTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.watcher.aspect; import static org.mockito.Mockito.times; @@ -36,92 +35,86 @@ @ExtendWith(MockitoExtension.class) class SpringRepositoryAspectJDBCTest { - private DemoRepositoryJDBC target = new DemoRepositoryJDBC(); + private DemoRepositoryJDBC target = new DemoRepositoryJDBC(); - private WatcherProperties watcherProperties = new WatcherProperties(); + private WatcherProperties watcherProperties = new WatcherProperties(); - private AspectJProxyFactory factory = new AspectJProxyFactory(target); + private AspectJProxyFactory factory = new AspectJProxyFactory(target); - @Mock private ChaosMonkeyRequestScope chaosMonkeyRequestScopeMock; + @Mock + private ChaosMonkeyRequestScope chaosMonkeyRequestScopeMock; - @Mock private MetricEventPublisher metricsMock; + @Mock + private MetricEventPublisher metricsMock; - private String pointcutName = "execution.DemoRepositoryJDBC.sayHello"; + private String pointcutName = "execution.DemoRepositoryJDBC.sayHello"; - private String simpleName = - "de.codecentric.spring.boot.demo.chaos.monkey.repository.DemoRepositoryJDBC.sayHello"; + private String simpleName = "de.codecentric.spring.boot.demo.chaos.monkey.repository.DemoRepositoryJDBC.sayHello"; - @Test - void chaosMonkeyIsCalledWhenEnabledInConfig() { - watcherProperties.setRepository(true); + @Test + void chaosMonkeyIsCalledWhenEnabledInConfig() { + watcherProperties.setRepository(true); - addRelevantAspect(); + addRelevantAspect(); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(1); - } + verifyDependenciesCalledXTimes(1); + } - @Test - void chaosMonkeyIsNotCalledWhenDisabledInConfig() { - watcherProperties.setRepository(false); + @Test + void chaosMonkeyIsNotCalledWhenDisabledInConfig() { + watcherProperties.setRepository(false); - addRelevantAspect(); + addRelevantAspect(); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(0); - } + verifyDependenciesCalledXTimes(0); + } - @Test - void chaosMonkeyIsNotCalledByAspectsWithUnrelatedPointcuts() { - watcherProperties.setService(true); - watcherProperties.setComponent(true); - watcherProperties.setController(true); - watcherProperties.setRepository(true); - watcherProperties.setRestController(true); + @Test + void chaosMonkeyIsNotCalledByAspectsWithUnrelatedPointcuts() { + watcherProperties.setService(true); + watcherProperties.setComponent(true); + watcherProperties.setController(true); + watcherProperties.setRepository(true); + watcherProperties.setRestController(true); - addNonRelevantAspects(); + addNonRelevantAspects(); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(0); - } + verifyDependenciesCalledXTimes(0); + } - private void addRelevantAspect() { - SpringRepositoryAspectJDBC repositoryAspectJDBC = - new SpringRepositoryAspectJDBC(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - factory.addAspect(repositoryAspectJDBC); - } + private void addRelevantAspect() { + SpringRepositoryAspectJDBC repositoryAspectJDBC = new SpringRepositoryAspectJDBC(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + factory.addAspect(repositoryAspectJDBC); + } - private void addNonRelevantAspects() { - SpringServiceAspect serviceAspect = - new SpringServiceAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringControllerAspect controllerAspect = - new SpringControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringComponentAspect componentAspect = - new SpringComponentAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringRestControllerAspect restControllerAspect = - new SpringRestControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringRepositoryAspectJPA repositoryAspect = - new SpringRepositoryAspectJPA(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + private void addNonRelevantAspects() { + SpringServiceAspect serviceAspect = new SpringServiceAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringControllerAspect controllerAspect = new SpringControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringComponentAspect componentAspect = new SpringComponentAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringRestControllerAspect restControllerAspect = new SpringRestControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringRepositoryAspectJPA repositoryAspect = new SpringRepositoryAspectJPA(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - factory.addAspect(serviceAspect); - factory.addAspect(controllerAspect); - factory.addAspect(componentAspect); - factory.addAspect(restControllerAspect); - factory.addAspect(repositoryAspect); - } + factory.addAspect(serviceAspect); + factory.addAspect(controllerAspect); + factory.addAspect(componentAspect); + factory.addAspect(restControllerAspect); + factory.addAspect(repositoryAspect); + } - private void callTargetMethod() { - DemoRepositoryJDBC proxy = factory.getProxy(); - proxy.sayHello(); - } + private void callTargetMethod() { + DemoRepositoryJDBC proxy = factory.getProxy(); + proxy.sayHello(); + } - private void verifyDependenciesCalledXTimes(int i) { - verify(chaosMonkeyRequestScopeMock, times(i)) - .callChaosMonkey(ChaosTarget.REPOSITORY, simpleName); - verify(metricsMock, times(i)).publishMetricEvent(pointcutName, MetricType.REPOSITORY); - verifyNoMoreInteractions(chaosMonkeyRequestScopeMock, metricsMock); - } + private void verifyDependenciesCalledXTimes(int i) { + verify(chaosMonkeyRequestScopeMock, times(i)).callChaosMonkey(ChaosTarget.REPOSITORY, simpleName); + verify(metricsMock, times(i)).publishMetricEvent(pointcutName, MetricType.REPOSITORY); + verifyNoMoreInteractions(chaosMonkeyRequestScopeMock, metricsMock); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectJPATest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectJPATest.java index 1ac35398..e53e845b 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectJPATest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectJPATest.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.watcher.aspect; import static org.mockito.Mockito.times; @@ -37,92 +36,87 @@ @ExtendWith(MockitoExtension.class) class SpringRepositoryAspectJPATest { - private DemoRepository target = new DemoRepositoryImpl(); + private DemoRepository target = new DemoRepositoryImpl(); - private WatcherProperties watcherProperties = new WatcherProperties(); + private WatcherProperties watcherProperties = new WatcherProperties(); - private AspectJProxyFactory factory = new AspectJProxyFactory(target); + private AspectJProxyFactory factory = new AspectJProxyFactory(target); - @Mock private ChaosMonkeyRequestScope chaosMonkeyRequestScopeMock; + @Mock + private ChaosMonkeyRequestScope chaosMonkeyRequestScopeMock; - @Mock private MetricEventPublisher metricsMock; + @Mock + private MetricEventPublisher metricsMock; - private String pointcutName = "execution.DemoRepository.dummyPublicSaveMethod"; + private String pointcutName = "execution.DemoRepository.dummyPublicSaveMethod"; - private String simpleName = - "de.codecentric.spring.boot.demo.chaos.monkey.repository.DemoRepository.dummyPublicSaveMethod"; + private String simpleName = "de.codecentric.spring.boot.demo.chaos.monkey.repository.DemoRepository.dummyPublicSaveMethod"; - @Test - void chaosMonkeyIsCalledWhenEnabledInConfig() { - watcherProperties.setRepository(true); + @Test + void chaosMonkeyIsCalledWhenEnabledInConfig() { + watcherProperties.setRepository(true); - addRelevantAspect(); + addRelevantAspect(); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(1); - } + verifyDependenciesCalledXTimes(1); + } - @Test - void chaosMonkeyIsNotCalledWhenDisabledInConfig() { - watcherProperties.setRepository(false); + @Test + void chaosMonkeyIsNotCalledWhenDisabledInConfig() { + watcherProperties.setRepository(false); - addRelevantAspect(); + addRelevantAspect(); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(0); - } + verifyDependenciesCalledXTimes(0); + } - @Test - void chaosMonkeyIsNotCalledByAspectsWithUnrelatedPointcuts() { - watcherProperties.setService(true); - watcherProperties.setComponent(true); - watcherProperties.setController(true); - watcherProperties.setRepository(true); - watcherProperties.setRestController(true); + @Test + void chaosMonkeyIsNotCalledByAspectsWithUnrelatedPointcuts() { + watcherProperties.setService(true); + watcherProperties.setComponent(true); + watcherProperties.setController(true); + watcherProperties.setRepository(true); + watcherProperties.setRestController(true); - addNonRelevantAspects(); + addNonRelevantAspects(); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(0); - } + verifyDependenciesCalledXTimes(0); + } - private void addRelevantAspect() { - SpringRepositoryAspectJPA repositoryAspect = - new SpringRepositoryAspectJPA(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - factory.addAspect(repositoryAspect); - } + private void addRelevantAspect() { + SpringRepositoryAspectJPA repositoryAspect = new SpringRepositoryAspectJPA(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + factory.addAspect(repositoryAspect); + } - private void addNonRelevantAspects() { - SpringControllerAspect controllerAspect = - new SpringControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringComponentAspect componentAspect = - new SpringComponentAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringRestControllerAspect restControllerAspect = - new SpringRestControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringServiceAspect serviceAspect = - new SpringServiceAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringRepositoryAspectJDBC repositoryStereotypeAspect = - new SpringRepositoryAspectJDBC(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + private void addNonRelevantAspects() { + SpringControllerAspect controllerAspect = new SpringControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringComponentAspect componentAspect = new SpringComponentAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringRestControllerAspect restControllerAspect = new SpringRestControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringServiceAspect serviceAspect = new SpringServiceAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringRepositoryAspectJDBC repositoryStereotypeAspect = new SpringRepositoryAspectJDBC(chaosMonkeyRequestScopeMock, metricsMock, + watcherProperties); - factory.addAspect(controllerAspect); - factory.addAspect(componentAspect); - factory.addAspect(restControllerAspect); - factory.addAspect(serviceAspect); - factory.addAspect(repositoryStereotypeAspect); - } + factory.addAspect(controllerAspect); + factory.addAspect(componentAspect); + factory.addAspect(restControllerAspect); + factory.addAspect(serviceAspect); + factory.addAspect(repositoryStereotypeAspect); + } - private void callTargetMethod() { - DemoRepository proxy = factory.getProxy(); - proxy.dummyPublicSaveMethod(); - } + private void callTargetMethod() { + DemoRepository proxy = factory.getProxy(); + proxy.dummyPublicSaveMethod(); + } - private void verifyDependenciesCalledXTimes(int i) { - verify(chaosMonkeyRequestScopeMock, times(i)) - .callChaosMonkey(ChaosTarget.REPOSITORY, simpleName); - verify(metricsMock, times(i)).publishMetricEvent(pointcutName, MetricType.REPOSITORY); - verifyNoMoreInteractions(chaosMonkeyRequestScopeMock, metricsMock); - } + private void verifyDependenciesCalledXTimes(int i) { + verify(chaosMonkeyRequestScopeMock, times(i)).callChaosMonkey(ChaosTarget.REPOSITORY, simpleName); + verify(metricsMock, times(i)).publishMetricEvent(pointcutName, MetricType.REPOSITORY); + verifyNoMoreInteractions(chaosMonkeyRequestScopeMock, metricsMock); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectRepositoryInterfaceTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectRepositoryInterfaceTest.java index 82fb5d6d..86296a0c 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectRepositoryInterfaceTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRepositoryAspectRepositoryInterfaceTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -24,21 +24,16 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; -@SpringBootTest( - properties = { - "chaos.monkey.watcher.repository=true", - "chaos.monkey.assaults.level=1", - "chaos.monkey.assaults.exceptions-active=true", - "chaos.monkey.enabled=true" - }, - classes = {ChaosDemoApplication.class}) +@SpringBootTest(properties = {"chaos.monkey.watcher.repository=true", "chaos.monkey.assaults.level=1", "chaos.monkey.assaults.exceptions-active=true", + "chaos.monkey.enabled=true"}, classes = {ChaosDemoApplication.class}) @ActiveProfiles("chaos-monkey") public class SpringRepositoryAspectRepositoryInterfaceTest { - @Autowired private CrudDemoRepository target; + @Autowired + private CrudDemoRepository target; - @Test - public void testRepoIsAttackedWhenRepoWatcherIsActive() { - assertThrows(Exception.class, () -> target.findAll()); - } + @Test + public void testRepoIsAttackedWhenRepoWatcherIsActive() { + assertThrows(Exception.class, () -> target.findAll()); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRestControllerAspectTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRestControllerAspectTest.java index faee3d6c..c2037a3d 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRestControllerAspectTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringRestControllerAspectTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.watcher.aspect; import static org.mockito.Mockito.times; @@ -36,92 +35,87 @@ @ExtendWith(MockitoExtension.class) class SpringRestControllerAspectTest { - private DemoRestController target = new DemoRestController(); + private DemoRestController target = new DemoRestController(); - private WatcherProperties watcherProperties = new WatcherProperties(); + private WatcherProperties watcherProperties = new WatcherProperties(); - private AspectJProxyFactory factory = new AspectJProxyFactory(target); + private AspectJProxyFactory factory = new AspectJProxyFactory(target); - @Mock private ChaosMonkeyRequestScope chaosMonkeyRequestScopeMock; + @Mock + private ChaosMonkeyRequestScope chaosMonkeyRequestScopeMock; - @Mock private MetricEventPublisher metricsMock; + @Mock + private MetricEventPublisher metricsMock; - private String pointcutName = "execution.DemoRestController.sayHello"; + private String pointcutName = "execution.DemoRestController.sayHello"; - private String simpleName = - "de.codecentric.spring.boot.demo.chaos.monkey.restcontroller.DemoRestController.sayHello"; + private String simpleName = "de.codecentric.spring.boot.demo.chaos.monkey.restcontroller.DemoRestController.sayHello"; - @Test - void chaosMonkeyIsCalledWhenEnabledInConfig() { - watcherProperties.setRestController(true); + @Test + void chaosMonkeyIsCalledWhenEnabledInConfig() { + watcherProperties.setRestController(true); - addRelevantAspect(); + addRelevantAspect(); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(1); - } + verifyDependenciesCalledXTimes(1); + } - @Test - void chaosMonkeyIsNotCalledWhenDisabledInConfig() { - watcherProperties.setController(false); + @Test + void chaosMonkeyIsNotCalledWhenDisabledInConfig() { + watcherProperties.setController(false); - addRelevantAspect(); + addRelevantAspect(); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(0); - } + verifyDependenciesCalledXTimes(0); + } - @Test - void chaosMonkeyIsNotCalledByAspectsWithUnrelatedPointcuts() { - watcherProperties.setService(true); - watcherProperties.setComponent(true); - watcherProperties.setController(true); - watcherProperties.setRepository(true); - watcherProperties.setRestController(true); + @Test + void chaosMonkeyIsNotCalledByAspectsWithUnrelatedPointcuts() { + watcherProperties.setService(true); + watcherProperties.setComponent(true); + watcherProperties.setController(true); + watcherProperties.setRepository(true); + watcherProperties.setRestController(true); - addNonRelevantAspects(); + addNonRelevantAspects(); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(0); - } + verifyDependenciesCalledXTimes(0); + } - private void addRelevantAspect() { - SpringRestControllerAspect restControllerAspect = - new SpringRestControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - factory.addAspect(restControllerAspect); - } + private void addRelevantAspect() { + SpringRestControllerAspect restControllerAspect = new SpringRestControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + factory.addAspect(restControllerAspect); + } - private void addNonRelevantAspects() { - SpringControllerAspect controllerAspect = - new SpringControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringComponentAspect componentAspect = - new SpringComponentAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringServiceAspect serviceAspect = - new SpringServiceAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringRepositoryAspectJPA repositoryAspect = - new SpringRepositoryAspectJPA(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringRepositoryAspectJDBC repositoryStereotypeAspect = - new SpringRepositoryAspectJDBC(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + private void addNonRelevantAspects() { + SpringControllerAspect controllerAspect = new SpringControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringComponentAspect componentAspect = new SpringComponentAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringServiceAspect serviceAspect = new SpringServiceAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringRepositoryAspectJPA repositoryAspect = new SpringRepositoryAspectJPA(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringRepositoryAspectJDBC repositoryStereotypeAspect = new SpringRepositoryAspectJDBC(chaosMonkeyRequestScopeMock, metricsMock, + watcherProperties); - factory.addAspect(controllerAspect); - factory.addAspect(componentAspect); - factory.addAspect(serviceAspect); - factory.addAspect(repositoryAspect); - factory.addAspect(repositoryStereotypeAspect); - } + factory.addAspect(controllerAspect); + factory.addAspect(componentAspect); + factory.addAspect(serviceAspect); + factory.addAspect(repositoryAspect); + factory.addAspect(repositoryStereotypeAspect); + } - private void callTargetMethod() { - DemoRestController proxy = factory.getProxy(); - proxy.sayHello(); - } + private void callTargetMethod() { + DemoRestController proxy = factory.getProxy(); + proxy.sayHello(); + } - private void verifyDependenciesCalledXTimes(int i) { - verify(chaosMonkeyRequestScopeMock, times(i)) - .callChaosMonkey(ChaosTarget.REST_CONTROLLER, simpleName); - verify(metricsMock, times(i)).publishMetricEvent(pointcutName, MetricType.RESTCONTROLLER); - verifyNoMoreInteractions(chaosMonkeyRequestScopeMock, metricsMock); - } + private void verifyDependenciesCalledXTimes(int i) { + verify(chaosMonkeyRequestScopeMock, times(i)).callChaosMonkey(ChaosTarget.REST_CONTROLLER, simpleName); + verify(metricsMock, times(i)).publishMetricEvent(pointcutName, MetricType.RESTCONTROLLER); + verifyNoMoreInteractions(chaosMonkeyRequestScopeMock, metricsMock); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringServiceAspectTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringServiceAspectTest.java index dba3f1d5..d235b5d3 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringServiceAspectTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/aspect/SpringServiceAspectTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.chaos.monkey.watcher.aspect; import static org.mockito.Mockito.times; @@ -36,91 +35,87 @@ @ExtendWith(MockitoExtension.class) class SpringServiceAspectTest { - private DemoService target = new DemoService(); + private DemoService target = new DemoService(); - private WatcherProperties watcherProperties = new WatcherProperties(); + private WatcherProperties watcherProperties = new WatcherProperties(); - private AspectJProxyFactory factory = new AspectJProxyFactory(target); + private AspectJProxyFactory factory = new AspectJProxyFactory(target); - @Mock private ChaosMonkeyRequestScope chaosMonkeyRequestScopeMock; + @Mock + private ChaosMonkeyRequestScope chaosMonkeyRequestScopeMock; - @Mock private MetricEventPublisher metricsMock; + @Mock + private MetricEventPublisher metricsMock; - private String pointcutName = "execution.DemoService.sayHello"; + private String pointcutName = "execution.DemoService.sayHello"; - private String simpleName = - "de.codecentric.spring.boot.demo.chaos.monkey.service.DemoService.sayHello"; + private String simpleName = "de.codecentric.spring.boot.demo.chaos.monkey.service.DemoService.sayHello"; - @Test - void chaosMonkeyIsCalledWhenEnabledInConfig() { - watcherProperties.setService(true); + @Test + void chaosMonkeyIsCalledWhenEnabledInConfig() { + watcherProperties.setService(true); - addRelevantAspect(); + addRelevantAspect(); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(1); - } + verifyDependenciesCalledXTimes(1); + } - @Test - void chaosMonkeyIsNotCalledWhenDisabledInConfig() { - watcherProperties.setService(false); + @Test + void chaosMonkeyIsNotCalledWhenDisabledInConfig() { + watcherProperties.setService(false); - addRelevantAspect(); + addRelevantAspect(); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(0); - } + verifyDependenciesCalledXTimes(0); + } - @Test - void chaosMonkeyIsNotCalledByAspectsWithUnrelatedPointcuts() { - watcherProperties.setService(true); - watcherProperties.setComponent(true); - watcherProperties.setController(true); - watcherProperties.setRepository(true); - watcherProperties.setRestController(true); + @Test + void chaosMonkeyIsNotCalledByAspectsWithUnrelatedPointcuts() { + watcherProperties.setService(true); + watcherProperties.setComponent(true); + watcherProperties.setController(true); + watcherProperties.setRepository(true); + watcherProperties.setRestController(true); - addNonRelevantAspects(); + addNonRelevantAspects(); - callTargetMethod(); + callTargetMethod(); - verifyDependenciesCalledXTimes(0); - } + verifyDependenciesCalledXTimes(0); + } - private void addRelevantAspect() { - SpringServiceAspect serviceAspect = - new SpringServiceAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - factory.addAspect(serviceAspect); - } + private void addRelevantAspect() { + SpringServiceAspect serviceAspect = new SpringServiceAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + factory.addAspect(serviceAspect); + } - private void addNonRelevantAspects() { - SpringControllerAspect controllerAspect = - new SpringControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringComponentAspect componentAspect = - new SpringComponentAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringRestControllerAspect restControllerAspect = - new SpringRestControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringRepositoryAspectJPA repositoryAspect = - new SpringRepositoryAspectJPA(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); - SpringRepositoryAspectJDBC repositoryStereotypeAspect = - new SpringRepositoryAspectJDBC(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + private void addNonRelevantAspects() { + SpringControllerAspect controllerAspect = new SpringControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringComponentAspect componentAspect = new SpringComponentAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringRestControllerAspect restControllerAspect = new SpringRestControllerAspect(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringRepositoryAspectJPA repositoryAspect = new SpringRepositoryAspectJPA(chaosMonkeyRequestScopeMock, metricsMock, watcherProperties); + SpringRepositoryAspectJDBC repositoryStereotypeAspect = new SpringRepositoryAspectJDBC(chaosMonkeyRequestScopeMock, metricsMock, + watcherProperties); - factory.addAspect(controllerAspect); - factory.addAspect(componentAspect); - factory.addAspect(restControllerAspect); - factory.addAspect(repositoryAspect); - factory.addAspect(repositoryStereotypeAspect); - } + factory.addAspect(controllerAspect); + factory.addAspect(componentAspect); + factory.addAspect(restControllerAspect); + factory.addAspect(repositoryAspect); + factory.addAspect(repositoryStereotypeAspect); + } - private void callTargetMethod() { - DemoService proxy = factory.getProxy(); - proxy.sayHello(); - } + private void callTargetMethod() { + DemoService proxy = factory.getProxy(); + proxy.sayHello(); + } - private void verifyDependenciesCalledXTimes(int i) { - verify(chaosMonkeyRequestScopeMock, times(i)).callChaosMonkey(ChaosTarget.SERVICE, simpleName); - verify(metricsMock, times(i)).publishMetricEvent(pointcutName, MetricType.SERVICE); - verifyNoMoreInteractions(chaosMonkeyRequestScopeMock, metricsMock); - } + private void verifyDependenciesCalledXTimes(int i) { + verify(chaosMonkeyRequestScopeMock, times(i)).callChaosMonkey(ChaosTarget.SERVICE, simpleName); + verify(metricsMock, times(i)).publishMetricEvent(pointcutName, MetricType.SERVICE); + verifyNoMoreInteractions(chaosMonkeyRequestScopeMock, metricsMock); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyRestTemplateWatcherIntegrationTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyRestTemplateWatcherIntegrationTest.java index a061a4dc..d067065c 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyRestTemplateWatcherIntegrationTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyRestTemplateWatcherIntegrationTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.watcher.outgoing; import static de.codecentric.spring.boot.chaos.monkey.watcher.outgoing.ChaosMonkeyRestTemplateWatcher.ErrorResponse.ERROR_BODY; @@ -20,65 +35,51 @@ class ChaosMonkeyRestTemplateWatcherIntegrationTest { - @SpringBootTest( - properties = {"chaos.monkey.watcher.rest-template=true"}, - classes = {ChaosDemoApplication.class}) - @ActiveProfiles("chaos-monkey") - @Nested - class WatcherIntegrationTest { + @SpringBootTest(properties = {"chaos.monkey.watcher.rest-template=true"}, classes = {ChaosDemoApplication.class}) + @ActiveProfiles("chaos-monkey") + @Nested + class WatcherIntegrationTest { - @Autowired private RestTemplate restTemplate; + @Autowired + private RestTemplate restTemplate; - @Test - public void testInterceptorIsPresent() { - Optional result = - this.restTemplate.getInterceptors().stream() - .filter(interceptor -> (interceptor instanceof ChaosMonkeyRestTemplateWatcher)) - .findFirst(); - assertThat(result).isPresent(); + @Test + public void testInterceptorIsPresent() { + Optional result = this.restTemplate.getInterceptors().stream() + .filter(interceptor -> (interceptor instanceof ChaosMonkeyRestTemplateWatcher)).findFirst(); + assertThat(result).isPresent(); + } } - } - @SpringBootTest( - properties = { - "chaos.monkey.enabled=true", - "chaos.monkey.watcher.rest-template=true", - "chaos.monkey.assaults.exceptions-active=true" - }, - classes = {ChaosDemoApplication.class}) - @ActiveProfiles("chaos-monkey") - @Nested - class ExceptionAssaultIntegrationTest { + @SpringBootTest(properties = {"chaos.monkey.enabled=true", "chaos.monkey.watcher.rest-template=true", + "chaos.monkey.assaults.exceptions-active=true"}, classes = {ChaosDemoApplication.class}) + @ActiveProfiles("chaos-monkey") + @Nested + class ExceptionAssaultIntegrationTest { - @Autowired private DemoRestTemplateService demoRestTemplateService; + @Autowired + private DemoRestTemplateService demoRestTemplateService; - @Test - public void testRestTemplateExceptionAssault() { - assertThatThrownBy(() -> this.demoRestTemplateService.callWithRestTemplate()) - .hasMessage(500 + " " + ERROR_TEXT + ": \"" + ERROR_BODY + '"'); + @Test + public void testRestTemplateExceptionAssault() { + assertThatThrownBy(() -> this.demoRestTemplateService.callWithRestTemplate()) + .hasMessage(500 + " " + ERROR_TEXT + ": \"" + ERROR_BODY + '"'); + } } - } - @Slf4j - @SpringBootTest( - properties = { - "chaos.monkey.enabled=true", - "chaos.monkey.watcher.rest-template=true", - "chaos.monkey.assaults.latency-active=true", - "chaos.monkey.test.rest-template.time-out=20" - }, - classes = {ChaosDemoApplication.class}) - @ActiveProfiles("chaos-monkey") - static class LatencyAssaultIntegrationTest { + @Slf4j + @SpringBootTest(properties = {"chaos.monkey.enabled=true", "chaos.monkey.watcher.rest-template=true", "chaos.monkey.assaults.latency-active=true", + "chaos.monkey.test.rest-template.time-out=20"}, classes = {ChaosDemoApplication.class}) + @ActiveProfiles("chaos-monkey") + static class LatencyAssaultIntegrationTest { - @Autowired private DemoRestTemplateService demoRestTemplateService; + @Autowired + private DemoRestTemplateService demoRestTemplateService; - @Test - public void testRestTemplateLatencyAssault() { - assertThatThrownBy(() -> this.demoRestTemplateService.callWithRestTemplate()) - .hasCauseInstanceOf(SSLException.class) - .hasMessage( - "I/O error on GET request for \"https://www.codecentric.de\": Read timed out; nested exception is javax.net.ssl.SSLException: Read timed out"); + @Test + public void testRestTemplateLatencyAssault() { + assertThatThrownBy(() -> this.demoRestTemplateService.callWithRestTemplate()).hasCauseInstanceOf(SSLException.class).hasMessage( + "I/O error on GET request for \"https://www.codecentric.de\": Read timed out; nested exception is javax.net.ssl.SSLException: Read timed out"); + } } - } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyWebClientWatcherIntegrationTest.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyWebClientWatcherIntegrationTest.java index 8d0ad21f..8b5406c0 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyWebClientWatcherIntegrationTest.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/chaos/monkey/watcher/outgoing/ChaosMonkeyWebClientWatcherIntegrationTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.chaos.monkey.watcher.outgoing; import static org.assertj.core.api.Assertions.assertThat; @@ -17,48 +32,38 @@ class ChaosMonkeyWebClientWatcherIntegrationTest { - @SpringBootTest( - properties = { - "chaos.monkey.watcher.web-client=true", - "chaos.monkey.enabled=true", - "chaos.monkey.assaults.exceptions-active=true" - }, - classes = {ChaosDemoApplication.class}) - @ActiveProfiles("chaos-monkey") - static class ExceptionAssaultIntegrationTest { + @SpringBootTest(properties = {"chaos.monkey.watcher.web-client=true", "chaos.monkey.enabled=true", + "chaos.monkey.assaults.exceptions-active=true"}, classes = {ChaosDemoApplication.class}) + @ActiveProfiles("chaos-monkey") + static class ExceptionAssaultIntegrationTest { - @Autowired private DemoWebClientService demoWebClientService; + @Autowired + private DemoWebClientService demoWebClientService; - @Test - public void testWebClientExceptionAssault() { - try { - this.demoWebClientService.callWithWebClient(); - fail("No WebClientResponseException occurred!"); - } catch (WebClientResponseException ex) { - String body = ex.getResponseBodyAsString(); - assertThat(body).isEqualTo(ErrorClientResponse.ERROR_BODY); - } + @Test + public void testWebClientExceptionAssault() { + try { + this.demoWebClientService.callWithWebClient(); + fail("No WebClientResponseException occurred!"); + } catch (WebClientResponseException ex) { + String body = ex.getResponseBodyAsString(); + assertThat(body).isEqualTo(ErrorClientResponse.ERROR_BODY); + } + } } - } - @Slf4j - @SpringBootTest( - properties = { - "chaos.monkey.enabled=true", - "chaos.monkey.watcher.web-client=true", - "chaos.monkey.assaults.latency-active=true", - "chaos.monkey.test.rest-template.time-out=20" - }, - classes = {ChaosDemoApplication.class}) - @ActiveProfiles("chaos-monkey") - static class LatencyAssaultIntegrationTest { + @Slf4j + @SpringBootTest(properties = {"chaos.monkey.enabled=true", "chaos.monkey.watcher.web-client=true", "chaos.monkey.assaults.latency-active=true", + "chaos.monkey.test.rest-template.time-out=20"}, classes = {ChaosDemoApplication.class}) + @ActiveProfiles("chaos-monkey") + static class LatencyAssaultIntegrationTest { - @Autowired private DemoWebClientService demoWebClientService; + @Autowired + private DemoWebClientService demoWebClientService; - @Test - public void testWebClientLatencyAssault() { - assertThatThrownBy(() -> this.demoWebClientService.callWithWebClient()) - .hasCauseInstanceOf(ReadTimeoutException.class); + @Test + public void testWebClientLatencyAssault() { + assertThatThrownBy(() -> this.demoWebClientService.callWithWebClient()).hasCauseInstanceOf(ReadTimeoutException.class); + } } - } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/ChaosDemoApplication.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/ChaosDemoApplication.java index 32d62623..8675f705 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/ChaosDemoApplication.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/ChaosDemoApplication.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.demo.chaos.monkey; import de.codecentric.spring.boot.demo.chaos.monkey.ChaosDemoApplication.TestOutgoingConfigurationProperties; @@ -37,30 +36,25 @@ @EnableConfigurationProperties(value = {TestOutgoingConfigurationProperties.class}) public class ChaosDemoApplication { - public static void main(String[] args) { - SpringApplication.run(ChaosDemoApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(ChaosDemoApplication.class, args); + } - @Bean - public RestTemplate restTemplateWithTimeout( - final TestOutgoingConfigurationProperties properties, - final RestTemplateBuilder restTemplateBuilder) { - return restTemplateBuilder - .setReadTimeout(Duration.of(properties.timeOut, ChronoUnit.MILLIS)) - .build(); - } + @Bean + public RestTemplate restTemplateWithTimeout(final TestOutgoingConfigurationProperties properties, final RestTemplateBuilder restTemplateBuilder) { + return restTemplateBuilder.setReadTimeout(Duration.of(properties.timeOut, ChronoUnit.MILLIS)).build(); + } - @Bean - public WebClient webClient( - final TestOutgoingConfigurationProperties properties, final Builder webClientBuilder) { - HttpClient client = HttpClient.create().responseTimeout(Duration.ofMillis(properties.timeOut)); - return webClientBuilder.clientConnector(new ReactorClientHttpConnector(client)).build(); - } + @Bean + public WebClient webClient(final TestOutgoingConfigurationProperties properties, final Builder webClientBuilder) { + HttpClient client = HttpClient.create().responseTimeout(Duration.ofMillis(properties.timeOut)); + return webClientBuilder.clientConnector(new ReactorClientHttpConnector(client)).build(); + } - @Data - @ConfigurationProperties(prefix = "chaos.monkey.test.rest-template") - static class TestOutgoingConfigurationProperties { + @Data + @ConfigurationProperties(prefix = "chaos.monkey.test.rest-template") + static class TestOutgoingConfigurationProperties { - private Long timeOut = 10000L; - } + private Long timeOut = 10000L; + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/bean/DemoBean.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/bean/DemoBean.java index 4acfc726..8f28527c 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/bean/DemoBean.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/bean/DemoBean.java @@ -1,7 +1,22 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.demo.chaos.monkey.bean; public class DemoBean { - public String sayHello() { - return "Hello!"; - } + public String sayHello() { + return "Hello!"; + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/ApplicationListenerComponent.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/ApplicationListenerComponent.java index 4c7ac22b..529742d3 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/ApplicationListenerComponent.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/ApplicationListenerComponent.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.demo.chaos.monkey.component; import org.springframework.context.ApplicationEvent; @@ -23,8 +22,8 @@ /** @author Alex Fincham */ @Component public class ApplicationListenerComponent implements ApplicationListener { - @Override - public void onApplicationEvent(ApplicationEvent applicationEvent) { - // this can be empty - } + @Override + public void onApplicationEvent(ApplicationEvent applicationEvent) { + // this can be empty + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/BeanPostProcessorComponent.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/BeanPostProcessorComponent.java index 64980055..65cc3dac 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/BeanPostProcessorComponent.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/BeanPostProcessorComponent.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.demo.chaos.monkey.component; import org.springframework.beans.BeansException; @@ -24,18 +23,17 @@ @Component public class BeanPostProcessorComponent implements BeanPostProcessor { - public String sayHello() { - return "Hello!"; - } + public String sayHello() { + return "Hello!"; + } - @Override - public Object postProcessBeforeInitialization(Object bean, String beanName) - throws BeansException { - return bean; - } + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + return bean; + } - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - return bean; - } + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + return bean; + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/DemoComponent.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/DemoComponent.java index abea93b3..cefa5a25 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/DemoComponent.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/DemoComponent.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.demo.chaos.monkey.component; import org.springframework.stereotype.Component; @@ -22,7 +21,7 @@ @Component public class DemoComponent { - public String sayHello() { - return "Hello!"; - } + public String sayHello() { + return "Hello!"; + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/FactoryBeanComponent.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/FactoryBeanComponent.java index 5b03dfea..0baedc4b 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/FactoryBeanComponent.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/FactoryBeanComponent.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.demo.chaos.monkey.component; import org.springframework.beans.factory.FactoryBean; @@ -22,18 +21,18 @@ @Component public class FactoryBeanComponent implements FactoryBean { - @Override - public Widget getObject() { - return new Widget(1); - } + @Override + public Widget getObject() { + return new Widget(1); + } - @Override - public Class getObjectType() { - return Widget.class; - } + @Override + public Class getObjectType() { + return Widget.class; + } - @Override - public boolean isSingleton() { - return true; - } + @Override + public boolean isSingleton() { + return true; + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/FinalDemoComponent.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/FinalDemoComponent.java index b194281e..62fb419d 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/FinalDemoComponent.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/FinalDemoComponent.java @@ -1,11 +1,11 @@ /* - * Copyright 2020 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.demo.chaos.monkey.component; import org.springframework.stereotype.Component; @@ -22,7 +21,7 @@ @Component public final class FinalDemoComponent { - public String sayHello() { - return "Hello!"; - } + public String sayHello() { + return "Hello!"; + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/Widget.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/Widget.java index af8694c8..339da0cf 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/Widget.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/component/Widget.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,21 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.demo.chaos.monkey.component; public class Widget { - int widget; + int widget; - public Widget(int widget) { - this.widget = widget; - } + public Widget(int widget) { + this.widget = widget; + } - public int getModel() { - return widget; - } + public int getModel() { + return widget; + } - public void setModel(int widget) { - this.widget = widget; - } + public void setModel(int widget) { + this.widget = widget; + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/controller/DemoController.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/controller/DemoController.java index 35f2eedc..c23438a1 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/controller/DemoController.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/controller/DemoController.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.demo.chaos.monkey.controller; import org.springframework.stereotype.Controller; @@ -23,8 +22,8 @@ @Controller public class DemoController { - @GetMapping("/hello") - public String sayHello() { - return "Hello!"; - } + @GetMapping("/hello") + public String sayHello() { + return "Hello!"; + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/CrudDemoRepository.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/CrudDemoRepository.java index d510ce77..fe240b15 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/CrudDemoRepository.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/CrudDemoRepository.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -19,4 +19,5 @@ import org.springframework.stereotype.Repository; @Repository -public interface CrudDemoRepository extends CrudRepository {} +public interface CrudDemoRepository extends CrudRepository { +} diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/DemoRepository.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/DemoRepository.java index 70050587..6cfbff6f 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/DemoRepository.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/DemoRepository.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.demo.chaos.monkey.repository; import org.springframework.data.repository.CrudRepository; @@ -23,5 +22,5 @@ @Repository public interface DemoRepository extends CrudRepository { - void dummyPublicSaveMethod(); + void dummyPublicSaveMethod(); } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/DemoRepositoryImpl.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/DemoRepositoryImpl.java index 3f2d2f37..c0f2b914 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/DemoRepositoryImpl.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/DemoRepositoryImpl.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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.spring.boot.demo.chaos.monkey.repository; import java.util.Optional; @@ -5,56 +20,62 @@ /** @author Benjamin Wilms */ public class DemoRepositoryImpl implements DemoRepository { - @Override - public void dummyPublicSaveMethod() {} + @Override + public void dummyPublicSaveMethod() { + } - @Override - public S save(S s) { - return null; - } + @Override + public S save(S s) { + return null; + } - @Override - public Iterable saveAll(Iterable iterable) { - return null; - } + @Override + public Iterable saveAll(Iterable iterable) { + return null; + } - @Override - public Optional findById(Long number) { - return Optional.empty(); - } + @Override + public Optional findById(Long number) { + return Optional.empty(); + } - @Override - public boolean existsById(Long number) { - return false; - } + @Override + public boolean existsById(Long number) { + return false; + } - @Override - public Iterable findAll() { - return null; - } + @Override + public Iterable findAll() { + return null; + } - @Override - public Iterable findAllById(Iterable iterable) { - return null; - } + @Override + public Iterable findAllById(Iterable iterable) { + return null; + } - @Override - public long count() { - return 0; - } + @Override + public long count() { + return 0; + } - @Override - public void deleteById(Long number) {} + @Override + public void deleteById(Long number) { + } - @Override - public void delete(Hello hello) {} + @Override + public void delete(Hello hello) { + } - @Override - public void deleteAllById(Iterable iterable) {} + @Override + public void deleteAllById(Iterable iterable) { + } - @Override - public void deleteAll(Iterable iterable) {} + @Override + public void deleteAll(Iterable iterable) { + } - @Override - public void deleteAll() {} + @Override + public void deleteAll() { + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/DemoRepositoryJDBC.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/DemoRepositoryJDBC.java index 9ad727fe..e701f29e 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/DemoRepositoryJDBC.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/DemoRepositoryJDBC.java @@ -1,11 +1,11 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.demo.chaos.monkey.repository; import org.springframework.stereotype.Repository; @@ -22,7 +21,7 @@ @Repository public class DemoRepositoryJDBC { - public String sayHello() { - return "Hello from Repository!"; - } + public String sayHello() { + return "Hello from Repository!"; + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/Hello.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/Hello.java index b42ff140..73d46224 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/Hello.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/repository/Hello.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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.spring.boot.demo.chaos.monkey.repository; import javax.persistence.Entity; @@ -9,30 +24,30 @@ @Entity public class Hello { - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private long id; + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; - private String message; + private String message; - public Hello(long id, String message) { - this.id = id; - this.message = message; - } + public Hello(long id, String message) { + this.id = id; + this.message = message; + } - public long getId() { - return id; - } + public long getId() { + return id; + } - public void setId(long id) { - this.id = id; - } + public void setId(long id) { + this.id = id; + } - public String getMessage() { - return message; - } + public String getMessage() { + return message; + } - public void setMessage(String message) { - this.message = message; - } + public void setMessage(String message) { + this.message = message; + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/restcontroller/DemoRestController.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/restcontroller/DemoRestController.java index fcbfa28c..304cd8b8 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/restcontroller/DemoRestController.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/restcontroller/DemoRestController.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.demo.chaos.monkey.restcontroller; import org.springframework.http.HttpStatus; @@ -24,8 +23,8 @@ @org.springframework.web.bind.annotation.RestController public class DemoRestController { - @GetMapping("/rest/hello") - public ResponseEntity sayHello() { - return new ResponseEntity("Hello", HttpStatus.OK); - } + @GetMapping("/rest/hello") + public ResponseEntity sayHello() { + return new ResponseEntity("Hello", HttpStatus.OK); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/service/DemoRestTemplateService.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/service/DemoRestTemplateService.java index 339c55fc..b317b377 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/service/DemoRestTemplateService.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/service/DemoRestTemplateService.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.demo.chaos.monkey.service; import org.springframework.http.ResponseEntity; @@ -7,13 +22,13 @@ @Service public class DemoRestTemplateService { - private final RestTemplate restTemplate; + private final RestTemplate restTemplate; - public DemoRestTemplateService(RestTemplate restTemplate) { - this.restTemplate = restTemplate; - } + public DemoRestTemplateService(RestTemplate restTemplate) { + this.restTemplate = restTemplate; + } - public ResponseEntity callWithRestTemplate() { - return this.restTemplate.getForEntity("https://www.codecentric.de", String.class); - } + public ResponseEntity callWithRestTemplate() { + return this.restTemplate.getForEntity("https://www.codecentric.de", String.class); + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/service/DemoService.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/service/DemoService.java index 9c54ffd2..59054d02 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/service/DemoService.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/service/DemoService.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package de.codecentric.spring.boot.demo.chaos.monkey.service; import org.springframework.stereotype.Service; @@ -22,7 +21,7 @@ @Service public class DemoService { - public String sayHello() { - return "Hello from Service!"; - } + public String sayHello() { + return "Hello from Service!"; + } } diff --git a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/service/DemoWebClientService.java b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/service/DemoWebClientService.java index 88b47bc7..50e9b810 100644 --- a/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/service/DemoWebClientService.java +++ b/chaos-monkey-spring-boot/src/test/java/de/codecentric/spring/boot/demo/chaos/monkey/service/DemoWebClientService.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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.spring.boot.demo.chaos.monkey.service; import lombok.extern.slf4j.Slf4j; @@ -9,18 +24,13 @@ @Service public class DemoWebClientService { - private final WebClient webClient; + private final WebClient webClient; - public DemoWebClientService(WebClient webClient) { - this.webClient = webClient; - } + public DemoWebClientService(WebClient webClient) { + this.webClient = webClient; + } - public String callWithWebClient() { - return this.webClient - .method(HttpMethod.GET) - .uri("https://www.codecentric.de") - .retrieve() - .bodyToMono(String.class) - .block(); - } + public String callWithWebClient() { + return this.webClient.method(HttpMethod.GET).uri("https://www.codecentric.de").retrieve().bodyToMono(String.class).block(); + } } diff --git a/code-style.xml b/code-style.xml new file mode 100644 index 00000000..91332920 --- /dev/null +++ b/code-style.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/demo-apps/chaos-monkey-demo-app-ext-jar/src/main/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplication.java b/demo-apps/chaos-monkey-demo-app-ext-jar/src/main/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplication.java index 82e5b7f6..0691252d 100644 --- a/demo-apps/chaos-monkey-demo-app-ext-jar/src/main/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplication.java +++ b/demo-apps/chaos-monkey-demo-app-ext-jar/src/main/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplication.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.example.chaos.monkey.chaosdemo; import org.springframework.boot.SpringApplication; @@ -22,7 +21,7 @@ @SpringBootApplication public class ChaosDemoApplication { - public static void main(String[] args) { - SpringApplication.run(ChaosDemoApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(ChaosDemoApplication.class, args); + } } diff --git a/demo-apps/chaos-monkey-demo-app-ext-jar/src/main/java/com/example/chaos/monkey/chaosdemo/controller/HelloController.java b/demo-apps/chaos-monkey-demo-app-ext-jar/src/main/java/com/example/chaos/monkey/chaosdemo/controller/HelloController.java index 06f5d664..7d802c78 100644 --- a/demo-apps/chaos-monkey-demo-app-ext-jar/src/main/java/com/example/chaos/monkey/chaosdemo/controller/HelloController.java +++ b/demo-apps/chaos-monkey-demo-app-ext-jar/src/main/java/com/example/chaos/monkey/chaosdemo/controller/HelloController.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.example.chaos.monkey.chaosdemo.controller; import org.springframework.http.ResponseEntity; @@ -24,17 +23,17 @@ @Controller public class HelloController { - @GetMapping("/hello") - public ResponseEntity sayHello() { - return ResponseEntity.ok(sayHelloPlease()); - } + @GetMapping("/hello") + public ResponseEntity sayHello() { + return ResponseEntity.ok(sayHelloPlease()); + } - @GetMapping("/goodbye") - public ResponseEntity sayGoodbye() { - return ResponseEntity.ok("Goodbye!"); - } + @GetMapping("/goodbye") + public ResponseEntity sayGoodbye() { + return ResponseEntity.ok("Goodbye!"); + } - private String sayHelloPlease() { - return "Hello!"; - } + private String sayHelloPlease() { + return "Hello!"; + } } diff --git a/demo-apps/chaos-monkey-demo-app-ext-jar/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationIntegrationTest.java b/demo-apps/chaos-monkey-demo-app-ext-jar/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationIntegrationTest.java index 1f4c8d7a..a341adbb 100644 --- a/demo-apps/chaos-monkey-demo-app-ext-jar/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationIntegrationTest.java +++ b/demo-apps/chaos-monkey-demo-app-ext-jar/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationIntegrationTest.java @@ -1,7 +1,23 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo; import org.springframework.boot.test.context.SpringBootTest; /** @author Benjamin Wilms */ @SpringBootTest -public class ChaosDemoApplicationIntegrationTest {} +public class ChaosDemoApplicationIntegrationTest { +} diff --git a/demo-apps/chaos-monkey-demo-app-ext-jar/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationTests.java b/demo-apps/chaos-monkey-demo-app-ext-jar/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationTests.java index 0f0a5c32..3562b9e4 100644 --- a/demo-apps/chaos-monkey-demo-app-ext-jar/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationTests.java +++ b/demo-apps/chaos-monkey-demo-app-ext-jar/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationTests.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.example.chaos.monkey.chaosdemo; import org.junit.jupiter.api.Test; @@ -21,6 +20,7 @@ @SpringBootTest public class ChaosDemoApplicationTests { - @Test - public void contextLoads() {} + @Test + public void contextLoads() { + } } diff --git a/demo-apps/chaos-monkey-demo-app-ext-jar/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerIntegrationTest.java b/demo-apps/chaos-monkey-demo-app-ext-jar/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerIntegrationTest.java index 9d479105..96873f9b 100644 --- a/demo-apps/chaos-monkey-demo-app-ext-jar/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerIntegrationTest.java +++ b/demo-apps/chaos-monkey-demo-app-ext-jar/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerIntegrationTest.java @@ -1,20 +1,18 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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 com.example.chaos.monkey.chaosdemo.controller; import static org.assertj.core.api.Assertions.assertThat; @@ -31,38 +29,35 @@ import org.springframework.test.context.TestPropertySource; /** @author Benjamin Wilms */ -@SpringBootTest( - classes = ChaosDemoApplication.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(classes = ChaosDemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestPropertySource("classpath:application-test.properties") public class HelloControllerIntegrationTest { - @LocalServerPort private int serverPort; - - @Autowired private TestRestTemplate testRestTemplate; - - @Autowired private HelloController helloController; - - @Test - public void contextLoads() { - assertThat(helloController).isNotNull(); - } - - @Test - public void checkHelloEndpoint() { - ResponseEntity response = - testRestTemplate.getForEntity( - "http://localhost:" + this.serverPort + "/hello", String.class); - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertEquals("Hello!", response.getBody()); - } - - @Test - public void checkGoodbyeEndpoint() { - ResponseEntity response = - testRestTemplate.getForEntity( - "http://localhost:" + this.serverPort + "/goodbye", String.class); - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertEquals("Goodbye!", response.getBody()); - } + @LocalServerPort + private int serverPort; + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private HelloController helloController; + + @Test + public void contextLoads() { + assertThat(helloController).isNotNull(); + } + + @Test + public void checkHelloEndpoint() { + ResponseEntity response = testRestTemplate.getForEntity("http://localhost:" + this.serverPort + "/hello", String.class); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertEquals("Hello!", response.getBody()); + } + + @Test + public void checkGoodbyeEndpoint() { + ResponseEntity response = testRestTemplate.getForEntity("http://localhost:" + this.serverPort + "/goodbye", String.class); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertEquals("Goodbye!", response.getBody()); + } } diff --git a/demo-apps/chaos-monkey-demo-app-ext-jar/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerTest.java b/demo-apps/chaos-monkey-demo-app-ext-jar/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerTest.java index a59f8feb..4ede8fe0 100644 --- a/demo-apps/chaos-monkey-demo-app-ext-jar/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerTest.java +++ b/demo-apps/chaos-monkey-demo-app-ext-jar/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.example.chaos.monkey.chaosdemo.controller; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -29,21 +28,16 @@ @WebMvcTest(HelloController.class) public class HelloControllerTest { - @Autowired private MockMvc mockMvc; + @Autowired + private MockMvc mockMvc; - @Test - public void shouldReturnHello() throws Exception { + @Test + public void shouldReturnHello() throws Exception { - this.mockMvc - .perform(get("/hello")) - .andExpect(status().isOk()) - .andExpect(content().string("Hello!")); - } + this.mockMvc.perform(get("/hello")).andExpect(status().isOk()).andExpect(content().string("Hello!")); + } - public void shouldReturnGoodbye() throws Exception { - this.mockMvc - .perform(get("/goodbye")) - .andExpect(status().isOk()) - .andExpect(content().string("Goodbye!")); - } + public void shouldReturnGoodbye() throws Exception { + this.mockMvc.perform(get("/goodbye")).andExpect(status().isOk()).andExpect(content().string("Goodbye!")); + } } diff --git a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplication.java b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplication.java index 82e5b7f6..0691252d 100644 --- a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplication.java +++ b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplication.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.example.chaos.monkey.chaosdemo; import org.springframework.boot.SpringApplication; @@ -22,7 +21,7 @@ @SpringBootApplication public class ChaosDemoApplication { - public static void main(String[] args) { - SpringApplication.run(ChaosDemoApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(ChaosDemoApplication.class, args); + } } diff --git a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/controller/GreetingController.java b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/controller/GreetingController.java index 70955da6..5b7f89f6 100644 --- a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/controller/GreetingController.java +++ b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/controller/GreetingController.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.controller; import org.springframework.http.ResponseEntity; @@ -8,8 +23,8 @@ @Controller public class GreetingController { - @GetMapping("/helloagain") - public ResponseEntity sayHello() { - return ResponseEntity.ok("Again hello!"); - } + @GetMapping("/helloagain") + public ResponseEntity sayHello() { + return ResponseEntity.ok("Again hello!"); + } } diff --git a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/controller/GreetingRestController.java b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/controller/GreetingRestController.java index 795ca5d4..d0e29273 100644 --- a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/controller/GreetingRestController.java +++ b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/controller/GreetingRestController.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.controller; import org.springframework.http.ResponseEntity; @@ -8,8 +23,8 @@ @RestController public class GreetingRestController { - @GetMapping("/rest/hello") - public ResponseEntity sayHello() { - return ResponseEntity.ok("REST hello!"); - } + @GetMapping("/rest/hello") + public ResponseEntity sayHello() { + return ResponseEntity.ok("REST hello!"); + } } diff --git a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/controller/HelloController.java b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/controller/HelloController.java index 3030a0cc..83fdd88d 100644 --- a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/controller/HelloController.java +++ b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/controller/HelloController.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.example.chaos.monkey.chaosdemo.controller; import com.example.chaos.monkey.chaosdemo.service.GreetingService; @@ -25,48 +24,48 @@ @Controller public class HelloController { - private final GreetingService greetingService; + private final GreetingService greetingService; - public HelloController(GreetingService greetingService) { - this.greetingService = greetingService; - } + public HelloController(GreetingService greetingService) { + this.greetingService = greetingService; + } - @GetMapping("/hello") - public ResponseEntity sayHello() { - return ResponseEntity.ok(sayHelloPlease()); - } + @GetMapping("/hello") + public ResponseEntity sayHello() { + return ResponseEntity.ok(sayHelloPlease()); + } - @GetMapping("/greet") - public ResponseEntity greet() { - return ResponseEntity.ok(greetingService.greet()); - } + @GetMapping("/greet") + public ResponseEntity greet() { + return ResponseEntity.ok(greetingService.greet()); + } - @GetMapping("/dbgreet") - public ResponseEntity greetFromDb() { - return ResponseEntity.ok(greetingService.greetFromRepo()); - } + @GetMapping("/dbgreet") + public ResponseEntity greetFromDb() { + return ResponseEntity.ok(greetingService.greetFromRepo()); + } - @GetMapping("/findbyid") - public ResponseEntity greetFromDbById() { - return ResponseEntity.ok(greetingService.greetFromRepoPagingSorting()); - } + @GetMapping("/findbyid") + public ResponseEntity greetFromDbById() { + return ResponseEntity.ok(greetingService.greetFromRepoPagingSorting()); + } - @GetMapping("/jpa/findbyid") - public ResponseEntity greetFromDbByIdJpa() { - return ResponseEntity.ok(greetingService.greetFromRepoJpa()); - } + @GetMapping("/jpa/findbyid") + public ResponseEntity greetFromDbByIdJpa() { + return ResponseEntity.ok(greetingService.greetFromRepoJpa()); + } - @GetMapping("/common/findbyid") - public ResponseEntity greetFromDbByIdAnnotation() { - return ResponseEntity.ok(greetingService.greetFromRepoAnnotation()); - } + @GetMapping("/common/findbyid") + public ResponseEntity greetFromDbByIdAnnotation() { + return ResponseEntity.ok(greetingService.greetFromRepoAnnotation()); + } - @GetMapping("/goodbye") - public ResponseEntity sayGoodbye() { - return ResponseEntity.ok("Goodbye!"); - } + @GetMapping("/goodbye") + public ResponseEntity sayGoodbye() { + return ResponseEntity.ok("Goodbye!"); + } - private String sayHelloPlease() { - return "Hello!"; - } + private String sayHelloPlease() { + return "Hello!"; + } } diff --git a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/Hello.java b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/Hello.java index a0681525..9fdfc8d3 100644 --- a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/Hello.java +++ b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/Hello.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.repo; import javax.persistence.Entity; @@ -9,30 +24,30 @@ @Entity public class Hello { - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private long id; + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; - private String message; + private String message; - public Hello(long id, String message) { - this.id = id; - this.message = message; - } + public Hello(long id, String message) { + this.id = id; + this.message = message; + } - public long getId() { - return id; - } + public long getId() { + return id; + } - public void setId(long id) { - this.id = id; - } + public void setId(long id) { + this.id = id; + } - public String getMessage() { - return message; - } + public String getMessage() { + return message; + } - public void setMessage(String message) { - this.message = message; - } + public void setMessage(String message) { + this.message = message; + } } diff --git a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepo.java b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepo.java index 06256075..5536f067 100644 --- a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepo.java +++ b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepo.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.repo; import org.springframework.data.repository.CrudRepository; @@ -5,4 +20,5 @@ /** @author Benjamin Wilms */ @Repository -public interface HelloRepo extends CrudRepository {} +public interface HelloRepo extends CrudRepository { +} diff --git a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoAnnotation.java b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoAnnotation.java index 71277277..754776f8 100644 --- a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoAnnotation.java +++ b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoAnnotation.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.repo; import java.util.Optional; @@ -6,7 +21,7 @@ @RepositoryDefinition(domainClass = Hello.class, idClass = Long.class) public interface HelloRepoAnnotation { - Hello save(Hello hello); + Hello save(Hello hello); - Optional findById(Long id); + Optional findById(Long id); } diff --git a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoJpa.java b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoJpa.java index bc6ddaaa..b4a717cb 100644 --- a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoJpa.java +++ b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoJpa.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.repo; import org.springframework.data.jpa.repository.JpaRepository; @@ -5,4 +20,5 @@ /** @author Benjamin Wilms */ @Repository -public interface HelloRepoJpa extends JpaRepository {} +public interface HelloRepoJpa extends JpaRepository { +} diff --git a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoSearchAndSorting.java b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoSearchAndSorting.java index ceb3099a..df3632aa 100644 --- a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoSearchAndSorting.java +++ b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoSearchAndSorting.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.repo; import org.springframework.data.repository.PagingAndSortingRepository; @@ -5,4 +20,5 @@ /** @author Benjamin Wilms */ @Repository -public interface HelloRepoSearchAndSorting extends PagingAndSortingRepository {} +public interface HelloRepoSearchAndSorting extends PagingAndSortingRepository { +} diff --git a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/service/GreetingService.java b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/service/GreetingService.java index ea73dc7b..bb983fa7 100644 --- a/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/service/GreetingService.java +++ b/demo-apps/chaos-monkey-demo-app-naked/src/main/java/com/example/chaos/monkey/chaosdemo/service/GreetingService.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.service; import com.example.chaos.monkey.chaosdemo.repo.Hello; @@ -12,54 +27,46 @@ @Service public class GreetingService { - private final HelloRepo helloRepo; + private final HelloRepo helloRepo; - private final HelloRepoSearchAndSorting repoSearchAndSorting; + private final HelloRepoSearchAndSorting repoSearchAndSorting; - private final HelloRepoJpa helloRepoJpa; + private final HelloRepoJpa helloRepoJpa; - private final HelloRepoAnnotation helloRepoAnnotation; + private final HelloRepoAnnotation helloRepoAnnotation; - public GreetingService( - HelloRepo helloRepo, - HelloRepoSearchAndSorting repoSearchAndSorting, - HelloRepoJpa helloRepoJpa, - HelloRepoAnnotation helloRepoAnnotation) { - this.helloRepo = helloRepo; - this.repoSearchAndSorting = repoSearchAndSorting; - this.helloRepoJpa = helloRepoJpa; - this.helloRepoAnnotation = helloRepoAnnotation; - } + public GreetingService(HelloRepo helloRepo, HelloRepoSearchAndSorting repoSearchAndSorting, HelloRepoJpa helloRepoJpa, + HelloRepoAnnotation helloRepoAnnotation) { + this.helloRepo = helloRepo; + this.repoSearchAndSorting = repoSearchAndSorting; + this.helloRepoJpa = helloRepoJpa; + this.helloRepoAnnotation = helloRepoAnnotation; + } - public String greet() { - return "Greetings from the server side!"; - } + public String greet() { + return "Greetings from the server side!"; + } - public String greetFromRepo() { - Hello databaseSide = helloRepo.save(new Hello(0, "Greetings from the database side")); - return databaseSide.getMessage(); - } + public String greetFromRepo() { + Hello databaseSide = helloRepo.save(new Hello(0, "Greetings from the database side")); + return databaseSide.getMessage(); + } - public String greetFromRepoPagingSorting() { - Hello databaseSide = - repoSearchAndSorting.save( - new Hello(0, "Greetings from the paging and sorting database side")); - Optional byId = repoSearchAndSorting.findById(databaseSide.getId()); - return byId.orElse(new Hello(-99, "not found")).getMessage(); - } + public String greetFromRepoPagingSorting() { + Hello databaseSide = repoSearchAndSorting.save(new Hello(0, "Greetings from the paging and sorting database side")); + Optional byId = repoSearchAndSorting.findById(databaseSide.getId()); + return byId.orElse(new Hello(-99, "not found")).getMessage(); + } - public String greetFromRepoJpa() { - Hello databaseSide = - helloRepoJpa.save(new Hello(0, "Greetings from the paging and sorting database side")); - Optional byId = helloRepoJpa.findById(databaseSide.getId()); - return byId.orElse(new Hello(-99, "not found")).getMessage(); - } + public String greetFromRepoJpa() { + Hello databaseSide = helloRepoJpa.save(new Hello(0, "Greetings from the paging and sorting database side")); + Optional byId = helloRepoJpa.findById(databaseSide.getId()); + return byId.orElse(new Hello(-99, "not found")).getMessage(); + } - public String greetFromRepoAnnotation() { - Hello databaseSide = - helloRepoAnnotation.save( - new Hello(0, "Greetings from the paging and sorting database side")); - Optional byId = helloRepoAnnotation.findById(databaseSide.getId()); - return byId.orElse(new Hello(-99, "not found")).getMessage(); - } + public String greetFromRepoAnnotation() { + Hello databaseSide = helloRepoAnnotation.save(new Hello(0, "Greetings from the paging and sorting database side")); + Optional byId = helloRepoAnnotation.findById(databaseSide.getId()); + return byId.orElse(new Hello(-99, "not found")).getMessage(); + } } diff --git a/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationTests.java b/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationTests.java index 5a057c05..21f332ec 100644 --- a/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationTests.java +++ b/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationTests.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.example.chaos.monkey.chaosdemo; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -27,16 +26,15 @@ @SpringBootTest public class ChaosDemoApplicationTests { - @Autowired private ApplicationContext ctx; + @Autowired + private ApplicationContext ctx; - @Test - public void contextLoads() {} + @Test + public void contextLoads() { + } - @Test - public void checkNotMetricsBean() { - assertThrows( - NoSuchBeanDefinitionException.class, - () -> ctx.getBean("metrics"), - "No bean named 'metrics' available"); - } + @Test + public void checkNotMetricsBean() { + assertThrows(NoSuchBeanDefinitionException.class, () -> ctx.getBean("metrics"), "No bean named 'metrics' available"); + } } diff --git a/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/controller/GreetingControllerTest.java b/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/controller/GreetingControllerTest.java index 1630cb5b..5e69d5b0 100644 --- a/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/controller/GreetingControllerTest.java +++ b/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/controller/GreetingControllerTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.controller; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -13,14 +28,12 @@ @WebMvcTest(GreetingController.class) public class GreetingControllerTest { - @Autowired private MockMvc mockMvc; + @Autowired + private MockMvc mockMvc; - @Test - public void shouldReturnHello() throws Exception { + @Test + public void shouldReturnHello() throws Exception { - this.mockMvc - .perform(get("/helloagain")) - .andExpect(status().isOk()) - .andExpect(content().string("Again hello!")); - } + this.mockMvc.perform(get("/helloagain")).andExpect(status().isOk()).andExpect(content().string("Again hello!")); + } } diff --git a/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/controller/GreetingRestControllerTest.java b/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/controller/GreetingRestControllerTest.java index 6321a0f4..8375196e 100644 --- a/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/controller/GreetingRestControllerTest.java +++ b/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/controller/GreetingRestControllerTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.controller; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -13,14 +28,12 @@ @WebMvcTest(GreetingRestController.class) public class GreetingRestControllerTest { - @Autowired private MockMvc mockMvc; + @Autowired + private MockMvc mockMvc; - @Test - public void shouldReturnHello() throws Exception { + @Test + public void shouldReturnHello() throws Exception { - this.mockMvc - .perform(get("/rest/hello")) - .andExpect(status().isOk()) - .andExpect(content().string("REST hello!")); - } + this.mockMvc.perform(get("/rest/hello")).andExpect(status().isOk()).andExpect(content().string("REST hello!")); + } } diff --git a/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerIntegrationTest.java b/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerIntegrationTest.java index 9d479105..96873f9b 100644 --- a/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerIntegrationTest.java +++ b/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerIntegrationTest.java @@ -1,20 +1,18 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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 com.example.chaos.monkey.chaosdemo.controller; import static org.assertj.core.api.Assertions.assertThat; @@ -31,38 +29,35 @@ import org.springframework.test.context.TestPropertySource; /** @author Benjamin Wilms */ -@SpringBootTest( - classes = ChaosDemoApplication.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(classes = ChaosDemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestPropertySource("classpath:application-test.properties") public class HelloControllerIntegrationTest { - @LocalServerPort private int serverPort; - - @Autowired private TestRestTemplate testRestTemplate; - - @Autowired private HelloController helloController; - - @Test - public void contextLoads() { - assertThat(helloController).isNotNull(); - } - - @Test - public void checkHelloEndpoint() { - ResponseEntity response = - testRestTemplate.getForEntity( - "http://localhost:" + this.serverPort + "/hello", String.class); - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertEquals("Hello!", response.getBody()); - } - - @Test - public void checkGoodbyeEndpoint() { - ResponseEntity response = - testRestTemplate.getForEntity( - "http://localhost:" + this.serverPort + "/goodbye", String.class); - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertEquals("Goodbye!", response.getBody()); - } + @LocalServerPort + private int serverPort; + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private HelloController helloController; + + @Test + public void contextLoads() { + assertThat(helloController).isNotNull(); + } + + @Test + public void checkHelloEndpoint() { + ResponseEntity response = testRestTemplate.getForEntity("http://localhost:" + this.serverPort + "/hello", String.class); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertEquals("Hello!", response.getBody()); + } + + @Test + public void checkGoodbyeEndpoint() { + ResponseEntity response = testRestTemplate.getForEntity("http://localhost:" + this.serverPort + "/goodbye", String.class); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertEquals("Goodbye!", response.getBody()); + } } diff --git a/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerTest.java b/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerTest.java index a4e57e0a..513a54c5 100644 --- a/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerTest.java +++ b/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.example.chaos.monkey.chaosdemo.controller; import static org.mockito.Mockito.when; @@ -33,53 +32,43 @@ @WebMvcTest(HelloController.class) public class HelloControllerTest { - @Autowired private MockMvc mockMvc; + @Autowired + private MockMvc mockMvc; - @MockBean private GreetingService greetingServiceMock; + @MockBean + private GreetingService greetingServiceMock; - private String responseService; + private String responseService; - private String responseRepo; + private String responseRepo; - @BeforeEach - public void setup() { - responseService = "Hello from service!"; - when(greetingServiceMock.greet()).thenReturn(responseService); - responseRepo = "Hello from repo!"; - when(greetingServiceMock.greetFromRepo()).thenReturn(responseRepo); - } + @BeforeEach + public void setup() { + responseService = "Hello from service!"; + when(greetingServiceMock.greet()).thenReturn(responseService); + responseRepo = "Hello from repo!"; + when(greetingServiceMock.greetFromRepo()).thenReturn(responseRepo); + } - @Test - public void shouldReturnHello() throws Exception { + @Test + public void shouldReturnHello() throws Exception { - this.mockMvc - .perform(get("/hello")) - .andExpect(status().isOk()) - .andExpect(content().string("Hello!")); - } + this.mockMvc.perform(get("/hello")).andExpect(status().isOk()).andExpect(content().string("Hello!")); + } - @Test - public void callMockServiceGreet() throws Exception { + @Test + public void callMockServiceGreet() throws Exception { - this.mockMvc - .perform(get("/greet")) - .andExpect(status().isOk()) - .andExpect(content().string(responseService)); - } + this.mockMvc.perform(get("/greet")).andExpect(status().isOk()).andExpect(content().string(responseService)); + } - @Test - public void callMockServiceDbGreet() throws Exception { + @Test + public void callMockServiceDbGreet() throws Exception { - this.mockMvc - .perform(get("/dbgreet")) - .andExpect(status().isOk()) - .andExpect(content().string(responseRepo)); - } + this.mockMvc.perform(get("/dbgreet")).andExpect(status().isOk()).andExpect(content().string(responseRepo)); + } - public void shouldReturnGoodbye() throws Exception { - this.mockMvc - .perform(get("/goodbye")) - .andExpect(status().isOk()) - .andExpect(content().string("Goodbye!")); - } + public void shouldReturnGoodbye() throws Exception { + this.mockMvc.perform(get("/goodbye")).andExpect(status().isOk()).andExpect(content().string("Goodbye!")); + } } diff --git a/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/repo/HelloTest.java b/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/repo/HelloTest.java index c55276b4..29e8cd03 100644 --- a/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/repo/HelloTest.java +++ b/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/repo/HelloTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.repo; import static org.assertj.core.api.Assertions.assertThat; @@ -7,25 +22,25 @@ /** @author Benjamin Wilms */ public class HelloTest { - @Test - public void checkConstructorGetter() { - String expectedValueMessage = "test"; - long id = 0; - Hello helloToTest = new Hello(id, expectedValueMessage); + @Test + public void checkConstructorGetter() { + String expectedValueMessage = "test"; + long id = 0; + Hello helloToTest = new Hello(id, expectedValueMessage); - assertThat(helloToTest.getMessage()).isEqualTo(expectedValueMessage); - assertThat(helloToTest.getId()).isEqualTo(id); - } + assertThat(helloToTest.getMessage()).isEqualTo(expectedValueMessage); + assertThat(helloToTest.getId()).isEqualTo(id); + } - @Test - public void checkSetterGetter() { - String expectedValueMessage = "test"; - long id = 0; - Hello helloToTest = new Hello(99, "empty"); - helloToTest.setId(id); - helloToTest.setMessage(expectedValueMessage); + @Test + public void checkSetterGetter() { + String expectedValueMessage = "test"; + long id = 0; + Hello helloToTest = new Hello(99, "empty"); + helloToTest.setId(id); + helloToTest.setMessage(expectedValueMessage); - assertThat(helloToTest.getMessage()).isEqualTo(expectedValueMessage); - assertThat(helloToTest.getId()).isEqualTo(id); - } + assertThat(helloToTest.getMessage()).isEqualTo(expectedValueMessage); + assertThat(helloToTest.getId()).isEqualTo(id); + } } diff --git a/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/service/GreetingServiceTest.java b/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/service/GreetingServiceTest.java index 3a8eb367..5cdeb4b7 100644 --- a/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/service/GreetingServiceTest.java +++ b/demo-apps/chaos-monkey-demo-app-naked/src/test/java/com/example/chaos/monkey/chaosdemo/service/GreetingServiceTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.service; import static org.assertj.core.api.Assertions.assertThat; @@ -23,85 +38,79 @@ @ExtendWith(MockitoExtension.class) public class GreetingServiceTest { - @Mock private HelloRepo helloRepoMock; - - @Mock private HelloRepoSearchAndSorting helloRepoSearchAndSortingMock; - - @Mock private HelloRepoJpa helloRepoJpaMock; - - @Mock private HelloRepoAnnotation helloRepoAnnotationMock; - - private GreetingService greetingService; - - @BeforeEach - public void setUp() { - greetingService = - new GreetingService( - helloRepoMock, - helloRepoSearchAndSortingMock, - helloRepoJpaMock, - helloRepoAnnotationMock); - } - - @Test - public void greet() { - assertThat(greetingService.greet()).isEqualTo("Greetings from the server side!"); - } - - @Test - public void greetFromRepo() { - String message = "message"; - Hello saveObject = new Hello(0, message); - when(helloRepoMock.save(any(Hello.class))).thenReturn(saveObject); - - assertThat(greetingService.greetFromRepo()).isEqualTo(message); - - verify(helloRepoMock, times(1)).save(any(Hello.class)); - verifyNoMoreInteractions( - helloRepoMock, helloRepoSearchAndSortingMock, helloRepoJpaMock, helloRepoAnnotationMock); - } - - @Test - public void testPagingAndSorting() { - String message = "message"; - Hello saveObject = new Hello(0, message); - when(helloRepoSearchAndSortingMock.save(any(Hello.class))).thenReturn(saveObject); - when(helloRepoSearchAndSortingMock.findById(saveObject.getId())) - .thenReturn(Optional.of(saveObject)); - - assertThat(greetingService.greetFromRepoPagingSorting()).isEqualTo(message); - - verify(helloRepoSearchAndSortingMock, times(1)).save(any(Hello.class)); - verify(helloRepoSearchAndSortingMock, times(1)).findById(saveObject.getId()); - verifyNoMoreInteractions( - helloRepoMock, helloRepoSearchAndSortingMock, helloRepoJpaMock, helloRepoAnnotationMock); - } - - @Test - public void testJpaRepo() { - String message = "message"; - Hello saveObject = new Hello(0, message); - when(helloRepoJpaMock.save(any(Hello.class))).thenReturn(saveObject); - when(helloRepoJpaMock.findById(saveObject.getId())).thenReturn(Optional.of(saveObject)); - - assertThat(greetingService.greetFromRepoJpa()).isEqualTo(message); - verify(helloRepoJpaMock, times(1)).save(any(Hello.class)); - verify(helloRepoJpaMock, times(1)).findById(saveObject.getId()); - verifyNoMoreInteractions( - helloRepoMock, helloRepoSearchAndSortingMock, helloRepoJpaMock, helloRepoAnnotationMock); - } - - @Test - public void testAnnotationRepo() { - String message = "message"; - Hello saveObject = new Hello(0, message); - when(helloRepoAnnotationMock.save(any(Hello.class))).thenReturn(saveObject); - when(helloRepoAnnotationMock.findById(saveObject.getId())).thenReturn(Optional.of(saveObject)); - - assertThat(greetingService.greetFromRepoAnnotation()).isEqualTo(message); - verify(helloRepoAnnotationMock, times(1)).save(any(Hello.class)); - verify(helloRepoAnnotationMock, times(1)).findById(saveObject.getId()); - verifyNoMoreInteractions( - helloRepoMock, helloRepoSearchAndSortingMock, helloRepoJpaMock, helloRepoAnnotationMock); - } + @Mock + private HelloRepo helloRepoMock; + + @Mock + private HelloRepoSearchAndSorting helloRepoSearchAndSortingMock; + + @Mock + private HelloRepoJpa helloRepoJpaMock; + + @Mock + private HelloRepoAnnotation helloRepoAnnotationMock; + + private GreetingService greetingService; + + @BeforeEach + public void setUp() { + greetingService = new GreetingService(helloRepoMock, helloRepoSearchAndSortingMock, helloRepoJpaMock, helloRepoAnnotationMock); + } + + @Test + public void greet() { + assertThat(greetingService.greet()).isEqualTo("Greetings from the server side!"); + } + + @Test + public void greetFromRepo() { + String message = "message"; + Hello saveObject = new Hello(0, message); + when(helloRepoMock.save(any(Hello.class))).thenReturn(saveObject); + + assertThat(greetingService.greetFromRepo()).isEqualTo(message); + + verify(helloRepoMock, times(1)).save(any(Hello.class)); + verifyNoMoreInteractions(helloRepoMock, helloRepoSearchAndSortingMock, helloRepoJpaMock, helloRepoAnnotationMock); + } + + @Test + public void testPagingAndSorting() { + String message = "message"; + Hello saveObject = new Hello(0, message); + when(helloRepoSearchAndSortingMock.save(any(Hello.class))).thenReturn(saveObject); + when(helloRepoSearchAndSortingMock.findById(saveObject.getId())).thenReturn(Optional.of(saveObject)); + + assertThat(greetingService.greetFromRepoPagingSorting()).isEqualTo(message); + + verify(helloRepoSearchAndSortingMock, times(1)).save(any(Hello.class)); + verify(helloRepoSearchAndSortingMock, times(1)).findById(saveObject.getId()); + verifyNoMoreInteractions(helloRepoMock, helloRepoSearchAndSortingMock, helloRepoJpaMock, helloRepoAnnotationMock); + } + + @Test + public void testJpaRepo() { + String message = "message"; + Hello saveObject = new Hello(0, message); + when(helloRepoJpaMock.save(any(Hello.class))).thenReturn(saveObject); + when(helloRepoJpaMock.findById(saveObject.getId())).thenReturn(Optional.of(saveObject)); + + assertThat(greetingService.greetFromRepoJpa()).isEqualTo(message); + verify(helloRepoJpaMock, times(1)).save(any(Hello.class)); + verify(helloRepoJpaMock, times(1)).findById(saveObject.getId()); + verifyNoMoreInteractions(helloRepoMock, helloRepoSearchAndSortingMock, helloRepoJpaMock, helloRepoAnnotationMock); + } + + @Test + public void testAnnotationRepo() { + String message = "message"; + Hello saveObject = new Hello(0, message); + when(helloRepoAnnotationMock.save(any(Hello.class))).thenReturn(saveObject); + when(helloRepoAnnotationMock.findById(saveObject.getId())).thenReturn(Optional.of(saveObject)); + + assertThat(greetingService.greetFromRepoAnnotation()).isEqualTo(message); + verify(helloRepoAnnotationMock, times(1)).save(any(Hello.class)); + verify(helloRepoAnnotationMock, times(1)).findById(saveObject.getId()); + verifyNoMoreInteractions(helloRepoMock, helloRepoSearchAndSortingMock, helloRepoJpaMock, helloRepoAnnotationMock); + } } diff --git a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/ChaosDemoApplication.java b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/ChaosDemoApplication.java index 11e542c6..b178b9dd 100644 --- a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/ChaosDemoApplication.java +++ b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/ChaosDemoApplication.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2021-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.example.chaos.monkey.toggledemo; import de.codecentric.spring.boot.chaos.monkey.configuration.ChaosMonkeyProperties; @@ -33,41 +32,42 @@ @SpringBootApplication public class ChaosDemoApplication { - public static void main(String[] args) { - SpringApplication.run(ChaosDemoApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(ChaosDemoApplication.class, args); + } - @Bean - public UnleashContextProvider unleashContextProvider() { - return () -> { - UnleashContext.Builder context = new UnleashContext.Builder(); + @Bean + public UnleashContextProvider unleashContextProvider() { + return () -> { + UnleashContext.Builder context = new UnleashContext.Builder(); - Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - if (auth != null && auth.getPrincipal() instanceof User) { - context.userId(((User) auth.getPrincipal()).getUsername()); - } + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + if (auth != null && auth.getPrincipal() instanceof User) { + context.userId(((User) auth.getPrincipal()).getUsername()); + } - return context.build(); - }; - } + return context.build(); + }; + } - @Bean - public Unleash unleash(UnleashContextProvider contextProvider) { - UserAwareFakeUnleash unleash = new UserAwareFakeUnleash(contextProvider); + @Bean + public Unleash unleash(UnleashContextProvider contextProvider) { + UserAwareFakeUnleash unleash = new UserAwareFakeUnleash(contextProvider); - // The following line is commented out, but demonstrates how you can enable a toggle with - // the demo app without running an actual Unleash server - // unleash.enable("chaos.monkey.controller"); - return unleash; - } + // The following line is commented out, but demonstrates how you can enable a + // toggle with + // the demo app without running an actual Unleash server + // unleash.enable("chaos.monkey.controller"); + return unleash; + } - @Bean - public ChaosToggleNameMapper myChaosToggles(ChaosMonkeyProperties chaosMonkeyProperties) { - return new MyAppToggleMapper(chaosMonkeyProperties.getTogglePrefix()); - } + @Bean + public ChaosToggleNameMapper myChaosToggles(ChaosMonkeyProperties chaosMonkeyProperties) { + return new MyAppToggleMapper(chaosMonkeyProperties.getTogglePrefix()); + } - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } } diff --git a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/MyAppToggleMapper.java b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/MyAppToggleMapper.java index 8d7d9a0b..5f635635 100644 --- a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/MyAppToggleMapper.java +++ b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/MyAppToggleMapper.java @@ -1,18 +1,33 @@ +/* + * Copyright 2021-2022 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 + * + * https://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 com.example.chaos.monkey.toggledemo; import de.codecentric.spring.boot.chaos.monkey.component.ChaosTarget; import de.codecentric.spring.boot.chaos.monkey.configuration.toggles.DefaultChaosToggleNameMapper; public class MyAppToggleMapper extends DefaultChaosToggleNameMapper { - public MyAppToggleMapper(String prefix) { - super(prefix); - } + public MyAppToggleMapper(String prefix) { + super(prefix); + } - @Override - public String mapName(ChaosTarget type, String name) { - if (type.equals(ChaosTarget.CONTROLLER) && name.toLowerCase().contains("hello")) { - return this.togglePrefix + ".howdy"; + @Override + public String mapName(ChaosTarget type, String name) { + if (type.equals(ChaosTarget.CONTROLLER) && name.toLowerCase().contains("hello")) { + return this.togglePrefix + ".howdy"; + } + return super.mapName(type, name); } - return super.mapName(type, name); - } } diff --git a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/UserAwareFakeUnleash.java b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/UserAwareFakeUnleash.java index fc769df8..aac44d14 100644 --- a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/UserAwareFakeUnleash.java +++ b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/UserAwareFakeUnleash.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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 com.example.chaos.monkey.toggledemo; import io.getunleash.FakeUnleash; @@ -9,66 +24,66 @@ import java.util.List; /** - * Note implementing your own Unleash isn't typically needed. But for the purpose of this demo I am - * creating one so we can use FakeUnleash but still demonstrate using a Context. + * Note implementing your own Unleash isn't typically needed. But for the + * purpose of this demo I am creating one so we can use FakeUnleash but still + * demonstrate using a Context. */ public class UserAwareFakeUnleash implements Unleash { - private final FakeUnleash fakeUnleash = new FakeUnleash(); - private final UnleashContextProvider contextProvider; + private final FakeUnleash fakeUnleash = new FakeUnleash(); + private final UnleashContextProvider contextProvider; + + public UserAwareFakeUnleash(UnleashContextProvider contextProvider) { + this.contextProvider = contextProvider; + } - public UserAwareFakeUnleash(UnleashContextProvider contextProvider) { - this.contextProvider = contextProvider; - } + public void enable(String featureName) { + fakeUnleash.enable(featureName); + } - public void enable(String featureName) { - fakeUnleash.enable(featureName); - } + @Override + public boolean isEnabled(String toggleName) { + UnleashContext context = this.contextProvider.getContext(); - @Override - public boolean isEnabled(String toggleName) { - UnleashContext context = this.contextProvider.getContext(); + if (toggleName.equals("chaos.monkey.howdy") && context.getUserId().orElse("").equals("chaosuser")) { + return true; + } - if (toggleName.equals("chaos.monkey.howdy") - && context.getUserId().orElse("").equals("chaosuser")) { - return true; + return fakeUnleash.isEnabled(toggleName, context); } - return fakeUnleash.isEnabled(toggleName, context); - } - - @Override - public boolean isEnabled(String s, boolean b) { - return fakeUnleash.isEnabled(s, b); - } + @Override + public boolean isEnabled(String s, boolean b) { + return fakeUnleash.isEnabled(s, b); + } - @Override - public Variant getVariant(String s, UnleashContext unleashContext) { - return fakeUnleash.getVariant(s, unleashContext); - } + @Override + public Variant getVariant(String s, UnleashContext unleashContext) { + return fakeUnleash.getVariant(s, unleashContext); + } - @Override - public Variant getVariant(String s, UnleashContext unleashContext, Variant variant) { - return fakeUnleash.getVariant(s, unleashContext); - } + @Override + public Variant getVariant(String s, UnleashContext unleashContext, Variant variant) { + return fakeUnleash.getVariant(s, unleashContext); + } - @Override - public Variant getVariant(String s) { - return fakeUnleash.getVariant(s); - } + @Override + public Variant getVariant(String s) { + return fakeUnleash.getVariant(s); + } - @Override - public Variant getVariant(String s, Variant variant) { - return fakeUnleash.getVariant(s, variant); - } + @Override + public Variant getVariant(String s, Variant variant) { + return fakeUnleash.getVariant(s, variant); + } - @Override - public List getFeatureToggleNames() { - return null; - } + @Override + public List getFeatureToggleNames() { + return null; + } - @Override - public MoreOperations more() { - return null; - } + @Override + public MoreOperations more() { + return null; + } } diff --git a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/WebSecurityConfig.java b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/WebSecurityConfig.java index 1d556a3f..b3b91abf 100644 --- a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/WebSecurityConfig.java +++ b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/WebSecurityConfig.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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 com.example.chaos.monkey.toggledemo; import org.springframework.context.annotation.Bean; @@ -15,41 +30,24 @@ @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { - private final PasswordEncoder passwordEncoder; - - public WebSecurityConfig(PasswordEncoder passwordEncoder) { - this.passwordEncoder = passwordEncoder; - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.authorizeRequests() - .antMatchers("/", "/home") - .permitAll() - .anyRequest() - .authenticated() - .and() - .httpBasic() - .and() - .logout() - .permitAll(); - } - - @Bean - @Override - public UserDetailsService userDetailsService() { - UserDetails user = - User.withUsername("user") - .password(passwordEncoder.encode("password")) - .roles("USER") - .build(); - - UserDetails chaosuser = - User.withUsername("chaosuser") - .password(passwordEncoder.encode("password")) - .roles("USER") - .build(); - - return new InMemoryUserDetailsManager(user, chaosuser); - } + private final PasswordEncoder passwordEncoder; + + public WebSecurityConfig(PasswordEncoder passwordEncoder) { + this.passwordEncoder = passwordEncoder; + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests().antMatchers("/", "/home").permitAll().anyRequest().authenticated().and().httpBasic().and().logout().permitAll(); + } + + @Bean + @Override + public UserDetailsService userDetailsService() { + UserDetails user = User.withUsername("user").password(passwordEncoder.encode("password")).roles("USER").build(); + + UserDetails chaosuser = User.withUsername("chaosuser").password(passwordEncoder.encode("password")).roles("USER").build(); + + return new InMemoryUserDetailsManager(user, chaosuser); + } } diff --git a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/component/HelloComponent.java b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/component/HelloComponent.java index 521501d9..cc00d75c 100644 --- a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/component/HelloComponent.java +++ b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/component/HelloComponent.java @@ -1,3 +1,18 @@ +/* + * Copyright 2019-2022 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 + * + * https://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 com.example.chaos.monkey.toggledemo.component; import org.springframework.stereotype.Component; @@ -6,8 +21,8 @@ @Component public class HelloComponent { - public String sayHello() { + public String sayHello() { - return "Hello from Component"; - } + return "Hello from Component"; + } } diff --git a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/controller/GreetingController.java b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/controller/GreetingController.java index 66893508..6f1bf537 100644 --- a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/controller/GreetingController.java +++ b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/controller/GreetingController.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.toggledemo.controller; import com.example.chaos.monkey.toggledemo.component.HelloComponent; @@ -10,15 +25,16 @@ @Controller public class GreetingController { - @Autowired private HelloComponent helloComponent; + @Autowired + private HelloComponent helloComponent; - @GetMapping("/helloagain") - public ResponseEntity sayHello() { - return ResponseEntity.ok("Again hello!"); - } + @GetMapping("/helloagain") + public ResponseEntity sayHello() { + return ResponseEntity.ok("Again hello!"); + } - @GetMapping("/hellocomponent") - public ResponseEntity sayHelloFromComponent() { - return ResponseEntity.ok(helloComponent.sayHello()); - } + @GetMapping("/hellocomponent") + public ResponseEntity sayHelloFromComponent() { + return ResponseEntity.ok(helloComponent.sayHello()); + } } diff --git a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/controller/GreetingRestController.java b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/controller/GreetingRestController.java index ce422259..89bcfeee 100644 --- a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/controller/GreetingRestController.java +++ b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/controller/GreetingRestController.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.toggledemo.controller; import org.springframework.http.ResponseEntity; @@ -12,8 +27,8 @@ @RestController public class GreetingRestController { - @GetMapping("/rest/hello") - public ResponseEntity sayHello() { - return ResponseEntity.ok("REST hello!"); - } + @GetMapping("/rest/hello") + public ResponseEntity sayHello() { + return ResponseEntity.ok("REST hello!"); + } } diff --git a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/controller/HelloController.java b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/controller/HelloController.java index 14583349..11f5d2a7 100644 --- a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/controller/HelloController.java +++ b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/controller/HelloController.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.example.chaos.monkey.toggledemo.controller; import com.example.chaos.monkey.toggledemo.service.GreetingService; @@ -25,33 +24,33 @@ @Controller public class HelloController { - private final GreetingService greetingService; + private final GreetingService greetingService; - public HelloController(GreetingService greetingService) { - this.greetingService = greetingService; - } + public HelloController(GreetingService greetingService) { + this.greetingService = greetingService; + } - @GetMapping("/hello") - public ResponseEntity sayHello() { - return ResponseEntity.ok(sayHelloPlease()); - } + @GetMapping("/hello") + public ResponseEntity sayHello() { + return ResponseEntity.ok(sayHelloPlease()); + } - @GetMapping("/greet") - public ResponseEntity greet() { - return ResponseEntity.ok(greetingService.greet()); - } + @GetMapping("/greet") + public ResponseEntity greet() { + return ResponseEntity.ok(greetingService.greet()); + } - @GetMapping("/dbgreet") - public ResponseEntity greetFromDb() { - return ResponseEntity.ok(greetingService.greetFromRepo()); - } + @GetMapping("/dbgreet") + public ResponseEntity greetFromDb() { + return ResponseEntity.ok(greetingService.greetFromRepo()); + } - @GetMapping("/goodbye") - public ResponseEntity sayGoodbye() { - return ResponseEntity.ok("Goodbye!"); - } + @GetMapping("/goodbye") + public ResponseEntity sayGoodbye() { + return ResponseEntity.ok("Goodbye!"); + } - private String sayHelloPlease() { - return "Hello!"; - } + private String sayHelloPlease() { + return "Hello!"; + } } diff --git a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/repo/SimpleRepository.java b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/repo/SimpleRepository.java index 7bf6e477..6af65ef6 100644 --- a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/repo/SimpleRepository.java +++ b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/repo/SimpleRepository.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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 com.example.chaos.monkey.toggledemo.repo; import org.springframework.stereotype.Repository; @@ -5,7 +20,7 @@ @Repository public class SimpleRepository { - public String getGreeting() { - return "Hello"; - } + public String getGreeting() { + return "Hello"; + } } diff --git a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/service/GreetingService.java b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/service/GreetingService.java index a8dd0263..fe6e9f43 100644 --- a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/service/GreetingService.java +++ b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/main/java/com/example/chaos/monkey/toggledemo/service/GreetingService.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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 com.example.chaos.monkey.toggledemo.service; import com.example.chaos.monkey.toggledemo.repo.SimpleRepository; @@ -7,17 +22,17 @@ @Service public class GreetingService { - private final SimpleRepository simpleRepository; + private final SimpleRepository simpleRepository; - public GreetingService(SimpleRepository simpleRepository) { - this.simpleRepository = simpleRepository; - } + public GreetingService(SimpleRepository simpleRepository) { + this.simpleRepository = simpleRepository; + } - public String greet() { - return "Greetings from the server side!"; - } + public String greet() { + return "Greetings from the server side!"; + } - public String greetFromRepo() { - return simpleRepository.getGreeting(); - } + public String greetFromRepo() { + return simpleRepository.getGreeting(); + } } diff --git a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/test/java/com/example/chaos/monkey/toggledemo/ChaosDemoApplicationTests.java b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/test/java/com/example/chaos/monkey/toggledemo/ChaosDemoApplicationTests.java index 5db22b43..e14126bf 100644 --- a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/test/java/com/example/chaos/monkey/toggledemo/ChaosDemoApplicationTests.java +++ b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/test/java/com/example/chaos/monkey/toggledemo/ChaosDemoApplicationTests.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.example.chaos.monkey.toggledemo; import static org.assertj.core.api.Assertions.assertThat; @@ -26,13 +25,15 @@ @SpringBootTest public class ChaosDemoApplicationTests { - @Autowired private ApplicationContext ctx; + @Autowired + private ApplicationContext ctx; - @Test - public void contextLoads() {} + @Test + public void contextLoads() { + } - @Test - public void checkMetricsBean() { - assertThat(ctx.getBean("metrics")).isNotNull(); - } + @Test + public void checkMetricsBean() { + assertThat(ctx.getBean("metrics")).isNotNull(); + } } diff --git a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/test/java/com/example/chaos/monkey/toggledemo/controller/HelloControllerIntegrationTest.java b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/test/java/com/example/chaos/monkey/toggledemo/controller/HelloControllerIntegrationTest.java index 5ae54136..71a8c336 100644 --- a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/test/java/com/example/chaos/monkey/toggledemo/controller/HelloControllerIntegrationTest.java +++ b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/test/java/com/example/chaos/monkey/toggledemo/controller/HelloControllerIntegrationTest.java @@ -1,20 +1,18 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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 com.example.chaos.monkey.toggledemo.controller; import static org.assertj.core.api.Assertions.assertThat; @@ -31,56 +29,49 @@ import org.springframework.test.context.TestPropertySource; /** @author Benjamin Wilms */ -@SpringBootTest( - classes = ChaosDemoApplication.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(classes = ChaosDemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestPropertySource("classpath:application-test.properties") public class HelloControllerIntegrationTest { - @LocalServerPort private int serverPort; + @LocalServerPort + private int serverPort; - @Autowired private TestRestTemplate testRestTemplate; + @Autowired + private TestRestTemplate testRestTemplate; - @Autowired private HelloController helloController; + @Autowired + private HelloController helloController; - @Test - public void contextLoads() { - assertThat(helloController).isNotNull(); - } + @Test + public void contextLoads() { + assertThat(helloController).isNotNull(); + } - @Test - public void checkHelloEndpoint() { - ResponseEntity response = - testRestTemplate.getForEntity( - "http://localhost:" + this.serverPort + "/hello", String.class); - assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); - } + @Test + public void checkHelloEndpoint() { + ResponseEntity response = testRestTemplate.getForEntity("http://localhost:" + this.serverPort + "/hello", String.class); + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + } - @Test - public void checkHelloEndpointChaosUser() { - ResponseEntity response = - testRestTemplate - .withBasicAuth("chaosuser", "password") - .getForEntity("http://localhost:" + this.serverPort + "/hello", String.class); + @Test + public void checkHelloEndpointChaosUser() { + ResponseEntity response = testRestTemplate.withBasicAuth("chaosuser", "password") + .getForEntity("http://localhost:" + this.serverPort + "/hello", String.class); - assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); - } + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + } - @Test - public void checkHelloEndpointNormalUser() { - ResponseEntity response = - testRestTemplate - .withBasicAuth("user", "password") - .getForEntity("http://localhost:" + this.serverPort + "/hello", String.class); + @Test + public void checkHelloEndpointNormalUser() { + ResponseEntity response = testRestTemplate.withBasicAuth("user", "password") + .getForEntity("http://localhost:" + this.serverPort + "/hello", String.class); - assertEquals(HttpStatus.OK, response.getStatusCode()); - } + assertEquals(HttpStatus.OK, response.getStatusCode()); + } - @Test - public void checkGoodbyeEndpoint() { - ResponseEntity response = - testRestTemplate.getForEntity( - "http://localhost:" + this.serverPort + "/goodbye", String.class); - assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); - } + @Test + public void checkGoodbyeEndpoint() { + ResponseEntity response = testRestTemplate.getForEntity("http://localhost:" + this.serverPort + "/goodbye", String.class); + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + } } diff --git a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/test/java/com/example/chaos/monkey/toggledemo/service/GreetingServiceTest.java b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/test/java/com/example/chaos/monkey/toggledemo/service/GreetingServiceTest.java index a0b6ba51..cc82b4a7 100644 --- a/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/test/java/com/example/chaos/monkey/toggledemo/service/GreetingServiceTest.java +++ b/demo-apps/chaos-monkey-demo-app-unleash-toggles/src/test/java/com/example/chaos/monkey/toggledemo/service/GreetingServiceTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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 com.example.chaos.monkey.toggledemo.service; import static org.assertj.core.api.Assertions.assertThat; @@ -17,28 +32,29 @@ @ExtendWith(MockitoExtension.class) public class GreetingServiceTest { - @Mock private SimpleRepository helloRepoMock; + @Mock + private SimpleRepository helloRepoMock; - private GreetingService greetingService; + private GreetingService greetingService; - @BeforeEach - public void setUp() { - greetingService = new GreetingService(helloRepoMock); - } + @BeforeEach + public void setUp() { + greetingService = new GreetingService(helloRepoMock); + } - @Test - public void greet() { - assertThat(greetingService.greet()).isEqualTo("Greetings from the server side!"); - } + @Test + public void greet() { + assertThat(greetingService.greet()).isEqualTo("Greetings from the server side!"); + } - @Test - public void greetFromRepo() { - String message = "message"; - when(helloRepoMock.getGreeting()).thenReturn(message); + @Test + public void greetFromRepo() { + String message = "message"; + when(helloRepoMock.getGreeting()).thenReturn(message); - assertThat(greetingService.greetFromRepo()).isEqualTo(message); + assertThat(greetingService.greetFromRepo()).isEqualTo(message); - verify(helloRepoMock, times(1)).getGreeting(); - verifyNoMoreInteractions(helloRepoMock); - } + verify(helloRepoMock, times(1)).getGreeting(); + verifyNoMoreInteractions(helloRepoMock); + } } diff --git a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplication.java b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplication.java index 82e5b7f6..0691252d 100644 --- a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplication.java +++ b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplication.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.example.chaos.monkey.chaosdemo; import org.springframework.boot.SpringApplication; @@ -22,7 +21,7 @@ @SpringBootApplication public class ChaosDemoApplication { - public static void main(String[] args) { - SpringApplication.run(ChaosDemoApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(ChaosDemoApplication.class, args); + } } diff --git a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/bean/HelloBean.java b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/bean/HelloBean.java index a55ef09b..def38996 100644 --- a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/bean/HelloBean.java +++ b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/bean/HelloBean.java @@ -1,8 +1,23 @@ +/* + * Copyright 2021-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.bean; public class HelloBean { - public String sayHello() { - return "Hello from Bean"; - } + public String sayHello() { + return "Hello from Bean"; + } } diff --git a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/bean/HelloConfiguration.java b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/bean/HelloConfiguration.java index 8d569dac..dc52111a 100644 --- a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/bean/HelloConfiguration.java +++ b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/bean/HelloConfiguration.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.bean; import org.springframework.context.annotation.Bean; @@ -6,8 +21,8 @@ @Configuration public class HelloConfiguration { - @Bean - public HelloBean helloBean() { - return new HelloBean(); - } + @Bean + public HelloBean helloBean() { + return new HelloBean(); + } } diff --git a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/component/HelloComponent.java b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/component/HelloComponent.java index c80bccb0..a9ac800e 100644 --- a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/component/HelloComponent.java +++ b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/component/HelloComponent.java @@ -1,3 +1,18 @@ +/* + * Copyright 2019-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.component; import org.springframework.stereotype.Component; @@ -6,8 +21,8 @@ @Component public class HelloComponent { - public String sayHello() { + public String sayHello() { - return "Hello from Component"; - } + return "Hello from Component"; + } } diff --git a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/controller/GreetingController.java b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/controller/GreetingController.java index 00ecd057..030895b2 100644 --- a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/controller/GreetingController.java +++ b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/controller/GreetingController.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.controller; import com.example.chaos.monkey.chaosdemo.bean.HelloBean; @@ -11,22 +26,24 @@ @Controller public class GreetingController { - @Autowired private HelloComponent helloComponent; + @Autowired + private HelloComponent helloComponent; - @Autowired private HelloBean helloBean; + @Autowired + private HelloBean helloBean; - @GetMapping("/helloagain") - public ResponseEntity sayHello() { - return ResponseEntity.ok("Again hello!"); - } + @GetMapping("/helloagain") + public ResponseEntity sayHello() { + return ResponseEntity.ok("Again hello!"); + } - @GetMapping("/hellocomponent") - public ResponseEntity sayHelloFromComponent() { - return ResponseEntity.ok(helloComponent.sayHello()); - } + @GetMapping("/hellocomponent") + public ResponseEntity sayHelloFromComponent() { + return ResponseEntity.ok(helloComponent.sayHello()); + } - @GetMapping("/hellobean") - public ResponseEntity sayHelloFromBean() { - return ResponseEntity.ok(helloBean.sayHello()); - } + @GetMapping("/hellobean") + public ResponseEntity sayHelloFromBean() { + return ResponseEntity.ok(helloBean.sayHello()); + } } diff --git a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/controller/GreetingRestController.java b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/controller/GreetingRestController.java index 76e3f019..2db7af01 100644 --- a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/controller/GreetingRestController.java +++ b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/controller/GreetingRestController.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.controller; import org.springframework.http.ResponseEntity; @@ -12,8 +27,8 @@ @RestController public class GreetingRestController { - @GetMapping("/rest/hello") - public ResponseEntity sayHello() { - return ResponseEntity.ok("REST hello!"); - } + @GetMapping("/rest/hello") + public ResponseEntity sayHello() { + return ResponseEntity.ok("REST hello!"); + } } diff --git a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/controller/HelloController.java b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/controller/HelloController.java index 3030a0cc..83fdd88d 100644 --- a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/controller/HelloController.java +++ b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/controller/HelloController.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.example.chaos.monkey.chaosdemo.controller; import com.example.chaos.monkey.chaosdemo.service.GreetingService; @@ -25,48 +24,48 @@ @Controller public class HelloController { - private final GreetingService greetingService; + private final GreetingService greetingService; - public HelloController(GreetingService greetingService) { - this.greetingService = greetingService; - } + public HelloController(GreetingService greetingService) { + this.greetingService = greetingService; + } - @GetMapping("/hello") - public ResponseEntity sayHello() { - return ResponseEntity.ok(sayHelloPlease()); - } + @GetMapping("/hello") + public ResponseEntity sayHello() { + return ResponseEntity.ok(sayHelloPlease()); + } - @GetMapping("/greet") - public ResponseEntity greet() { - return ResponseEntity.ok(greetingService.greet()); - } + @GetMapping("/greet") + public ResponseEntity greet() { + return ResponseEntity.ok(greetingService.greet()); + } - @GetMapping("/dbgreet") - public ResponseEntity greetFromDb() { - return ResponseEntity.ok(greetingService.greetFromRepo()); - } + @GetMapping("/dbgreet") + public ResponseEntity greetFromDb() { + return ResponseEntity.ok(greetingService.greetFromRepo()); + } - @GetMapping("/findbyid") - public ResponseEntity greetFromDbById() { - return ResponseEntity.ok(greetingService.greetFromRepoPagingSorting()); - } + @GetMapping("/findbyid") + public ResponseEntity greetFromDbById() { + return ResponseEntity.ok(greetingService.greetFromRepoPagingSorting()); + } - @GetMapping("/jpa/findbyid") - public ResponseEntity greetFromDbByIdJpa() { - return ResponseEntity.ok(greetingService.greetFromRepoJpa()); - } + @GetMapping("/jpa/findbyid") + public ResponseEntity greetFromDbByIdJpa() { + return ResponseEntity.ok(greetingService.greetFromRepoJpa()); + } - @GetMapping("/common/findbyid") - public ResponseEntity greetFromDbByIdAnnotation() { - return ResponseEntity.ok(greetingService.greetFromRepoAnnotation()); - } + @GetMapping("/common/findbyid") + public ResponseEntity greetFromDbByIdAnnotation() { + return ResponseEntity.ok(greetingService.greetFromRepoAnnotation()); + } - @GetMapping("/goodbye") - public ResponseEntity sayGoodbye() { - return ResponseEntity.ok("Goodbye!"); - } + @GetMapping("/goodbye") + public ResponseEntity sayGoodbye() { + return ResponseEntity.ok("Goodbye!"); + } - private String sayHelloPlease() { - return "Hello!"; - } + private String sayHelloPlease() { + return "Hello!"; + } } diff --git a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/Hello.java b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/Hello.java index a0681525..9fdfc8d3 100644 --- a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/Hello.java +++ b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/Hello.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.repo; import javax.persistence.Entity; @@ -9,30 +24,30 @@ @Entity public class Hello { - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private long id; + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; - private String message; + private String message; - public Hello(long id, String message) { - this.id = id; - this.message = message; - } + public Hello(long id, String message) { + this.id = id; + this.message = message; + } - public long getId() { - return id; - } + public long getId() { + return id; + } - public void setId(long id) { - this.id = id; - } + public void setId(long id) { + this.id = id; + } - public String getMessage() { - return message; - } + public String getMessage() { + return message; + } - public void setMessage(String message) { - this.message = message; - } + public void setMessage(String message) { + this.message = message; + } } diff --git a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepo.java b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepo.java index 06256075..5536f067 100644 --- a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepo.java +++ b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepo.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.repo; import org.springframework.data.repository.CrudRepository; @@ -5,4 +20,5 @@ /** @author Benjamin Wilms */ @Repository -public interface HelloRepo extends CrudRepository {} +public interface HelloRepo extends CrudRepository { +} diff --git a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoAnnotation.java b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoAnnotation.java index 71277277..754776f8 100644 --- a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoAnnotation.java +++ b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoAnnotation.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.repo; import java.util.Optional; @@ -6,7 +21,7 @@ @RepositoryDefinition(domainClass = Hello.class, idClass = Long.class) public interface HelloRepoAnnotation { - Hello save(Hello hello); + Hello save(Hello hello); - Optional findById(Long id); + Optional findById(Long id); } diff --git a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoJpa.java b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoJpa.java index bc6ddaaa..b4a717cb 100644 --- a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoJpa.java +++ b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoJpa.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.repo; import org.springframework.data.jpa.repository.JpaRepository; @@ -5,4 +20,5 @@ /** @author Benjamin Wilms */ @Repository -public interface HelloRepoJpa extends JpaRepository {} +public interface HelloRepoJpa extends JpaRepository { +} diff --git a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoSearchAndSorting.java b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoSearchAndSorting.java index ceb3099a..df3632aa 100644 --- a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoSearchAndSorting.java +++ b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/repo/HelloRepoSearchAndSorting.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.repo; import org.springframework.data.repository.PagingAndSortingRepository; @@ -5,4 +20,5 @@ /** @author Benjamin Wilms */ @Repository -public interface HelloRepoSearchAndSorting extends PagingAndSortingRepository {} +public interface HelloRepoSearchAndSorting extends PagingAndSortingRepository { +} diff --git a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/service/GreetingService.java b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/service/GreetingService.java index ea73dc7b..bb983fa7 100644 --- a/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/service/GreetingService.java +++ b/demo-apps/chaos-monkey-demo-app/src/main/java/com/example/chaos/monkey/chaosdemo/service/GreetingService.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.service; import com.example.chaos.monkey.chaosdemo.repo.Hello; @@ -12,54 +27,46 @@ @Service public class GreetingService { - private final HelloRepo helloRepo; + private final HelloRepo helloRepo; - private final HelloRepoSearchAndSorting repoSearchAndSorting; + private final HelloRepoSearchAndSorting repoSearchAndSorting; - private final HelloRepoJpa helloRepoJpa; + private final HelloRepoJpa helloRepoJpa; - private final HelloRepoAnnotation helloRepoAnnotation; + private final HelloRepoAnnotation helloRepoAnnotation; - public GreetingService( - HelloRepo helloRepo, - HelloRepoSearchAndSorting repoSearchAndSorting, - HelloRepoJpa helloRepoJpa, - HelloRepoAnnotation helloRepoAnnotation) { - this.helloRepo = helloRepo; - this.repoSearchAndSorting = repoSearchAndSorting; - this.helloRepoJpa = helloRepoJpa; - this.helloRepoAnnotation = helloRepoAnnotation; - } + public GreetingService(HelloRepo helloRepo, HelloRepoSearchAndSorting repoSearchAndSorting, HelloRepoJpa helloRepoJpa, + HelloRepoAnnotation helloRepoAnnotation) { + this.helloRepo = helloRepo; + this.repoSearchAndSorting = repoSearchAndSorting; + this.helloRepoJpa = helloRepoJpa; + this.helloRepoAnnotation = helloRepoAnnotation; + } - public String greet() { - return "Greetings from the server side!"; - } + public String greet() { + return "Greetings from the server side!"; + } - public String greetFromRepo() { - Hello databaseSide = helloRepo.save(new Hello(0, "Greetings from the database side")); - return databaseSide.getMessage(); - } + public String greetFromRepo() { + Hello databaseSide = helloRepo.save(new Hello(0, "Greetings from the database side")); + return databaseSide.getMessage(); + } - public String greetFromRepoPagingSorting() { - Hello databaseSide = - repoSearchAndSorting.save( - new Hello(0, "Greetings from the paging and sorting database side")); - Optional byId = repoSearchAndSorting.findById(databaseSide.getId()); - return byId.orElse(new Hello(-99, "not found")).getMessage(); - } + public String greetFromRepoPagingSorting() { + Hello databaseSide = repoSearchAndSorting.save(new Hello(0, "Greetings from the paging and sorting database side")); + Optional byId = repoSearchAndSorting.findById(databaseSide.getId()); + return byId.orElse(new Hello(-99, "not found")).getMessage(); + } - public String greetFromRepoJpa() { - Hello databaseSide = - helloRepoJpa.save(new Hello(0, "Greetings from the paging and sorting database side")); - Optional byId = helloRepoJpa.findById(databaseSide.getId()); - return byId.orElse(new Hello(-99, "not found")).getMessage(); - } + public String greetFromRepoJpa() { + Hello databaseSide = helloRepoJpa.save(new Hello(0, "Greetings from the paging and sorting database side")); + Optional byId = helloRepoJpa.findById(databaseSide.getId()); + return byId.orElse(new Hello(-99, "not found")).getMessage(); + } - public String greetFromRepoAnnotation() { - Hello databaseSide = - helloRepoAnnotation.save( - new Hello(0, "Greetings from the paging and sorting database side")); - Optional byId = helloRepoAnnotation.findById(databaseSide.getId()); - return byId.orElse(new Hello(-99, "not found")).getMessage(); - } + public String greetFromRepoAnnotation() { + Hello databaseSide = helloRepoAnnotation.save(new Hello(0, "Greetings from the paging and sorting database side")); + Optional byId = helloRepoAnnotation.findById(databaseSide.getId()); + return byId.orElse(new Hello(-99, "not found")).getMessage(); + } } diff --git a/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationTests.java b/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationTests.java index 979bb313..4d1b398d 100644 --- a/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationTests.java +++ b/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationTests.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.example.chaos.monkey.chaosdemo; import static org.assertj.core.api.Assertions.assertThat; @@ -26,13 +25,15 @@ @SpringBootTest public class ChaosDemoApplicationTests { - @Autowired private ApplicationContext ctx; + @Autowired + private ApplicationContext ctx; - @Test - public void contextLoads() {} + @Test + public void contextLoads() { + } - @Test - public void checkMetricsBean() { - assertThat(ctx.getBean("metrics")).isNotNull(); - } + @Test + public void checkMetricsBean() { + assertThat(ctx.getBean("metrics")).isNotNull(); + } } diff --git a/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/GreetingControllerTest.java b/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/GreetingControllerTest.java index 232068b2..4f1cac53 100644 --- a/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/GreetingControllerTest.java +++ b/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/GreetingControllerTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.controller; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -15,32 +30,24 @@ @WebMvcTest({GreetingController.class, HelloComponent.class, HelloConfiguration.class}) public class GreetingControllerTest { - @Autowired private MockMvc mockMvc; + @Autowired + private MockMvc mockMvc; - @Test - public void shouldReturnHello() throws Exception { + @Test + public void shouldReturnHello() throws Exception { - this.mockMvc - .perform(get("/helloagain")) - .andExpect(status().isOk()) - .andExpect(content().string("Again hello!")); - } + this.mockMvc.perform(get("/helloagain")).andExpect(status().isOk()).andExpect(content().string("Again hello!")); + } - @Test - public void shouldReturnHelloFromComponent() throws Exception { + @Test + public void shouldReturnHelloFromComponent() throws Exception { - this.mockMvc - .perform(get("/hellocomponent")) - .andExpect(status().isOk()) - .andExpect(content().string("Hello from Component")); - } + this.mockMvc.perform(get("/hellocomponent")).andExpect(status().isOk()).andExpect(content().string("Hello from Component")); + } - @Test - public void shouldReturnHelloFromBean() throws Exception { + @Test + public void shouldReturnHelloFromBean() throws Exception { - this.mockMvc - .perform(get("/hellobean")) - .andExpect(status().isOk()) - .andExpect(content().string("Hello from Bean")); - } + this.mockMvc.perform(get("/hellobean")).andExpect(status().isOk()).andExpect(content().string("Hello from Bean")); + } } diff --git a/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/GreetingRestControllerTest.java b/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/GreetingRestControllerTest.java index 6321a0f4..8375196e 100644 --- a/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/GreetingRestControllerTest.java +++ b/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/GreetingRestControllerTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.controller; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -13,14 +28,12 @@ @WebMvcTest(GreetingRestController.class) public class GreetingRestControllerTest { - @Autowired private MockMvc mockMvc; + @Autowired + private MockMvc mockMvc; - @Test - public void shouldReturnHello() throws Exception { + @Test + public void shouldReturnHello() throws Exception { - this.mockMvc - .perform(get("/rest/hello")) - .andExpect(status().isOk()) - .andExpect(content().string("REST hello!")); - } + this.mockMvc.perform(get("/rest/hello")).andExpect(status().isOk()).andExpect(content().string("REST hello!")); + } } diff --git a/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloComponentIntegrationTest.java b/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloComponentIntegrationTest.java index 32434982..48ee031a 100644 --- a/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloComponentIntegrationTest.java +++ b/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloComponentIntegrationTest.java @@ -1,20 +1,18 @@ /* - * Copyright 2020 the original author or authors. + * Copyright 2018-2022 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 + * https://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 com.example.chaos.monkey.chaosdemo.controller; import static org.assertj.core.api.Assertions.assertThat; @@ -29,25 +27,25 @@ import org.springframework.test.context.TestPropertySource; /** @author Benjamin Wilms */ -@SpringBootTest( - classes = ChaosDemoApplication.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(classes = ChaosDemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestPropertySource("classpath:application-component-test.properties") public class HelloComponentIntegrationTest { - @Autowired private HelloComponent helloComponent; + @Autowired + private HelloComponent helloComponent; - @Autowired private ChaosMonkeyConfiguration chaosMonkeyConfiguration; + @Autowired + private ChaosMonkeyConfiguration chaosMonkeyConfiguration; - @Test - public void contextLoads() { - assertThat(helloComponent).isNotNull(); - } + @Test + public void contextLoads() { + assertThat(helloComponent).isNotNull(); + } - @Test - public void callingPublicMethodOnComponent() { - assertTrue(chaosMonkeyConfiguration.settings().getWatcherProperties().isComponent()); + @Test + public void callingPublicMethodOnComponent() { + assertTrue(chaosMonkeyConfiguration.settings().getWatcherProperties().isComponent()); - helloComponent.sayHello(); - } + helloComponent.sayHello(); + } } diff --git a/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerIntegrationTest.java b/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerIntegrationTest.java index 6fc9e784..0dc06156 100644 --- a/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerIntegrationTest.java +++ b/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerIntegrationTest.java @@ -1,20 +1,18 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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 com.example.chaos.monkey.chaosdemo.controller; import static org.assertj.core.api.Assertions.assertThat; @@ -32,52 +30,50 @@ import org.springframework.test.context.TestPropertySource; /** @author Benjamin Wilms */ -@SpringBootTest( - classes = ChaosDemoApplication.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(classes = ChaosDemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestPropertySource("classpath:application-test.properties") public class HelloControllerIntegrationTest { - @Autowired private TestRestTemplate testRestTemplate; + @Autowired + private TestRestTemplate testRestTemplate; - @Autowired private HelloController helloController; + @Autowired + private HelloController helloController; - @LocalManagementPort private int managementPort; + @LocalManagementPort + private int managementPort; - @Test - public void contextLoads() { - assertThat(helloController).isNotNull(); - } + @Test + public void contextLoads() { + assertThat(helloController).isNotNull(); + } - @Test - public void checkHelloEndpoint() { - ResponseEntity response = testRestTemplate.getForEntity("/hello", String.class); - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertEquals("Hello!", response.getBody()); - } + @Test + public void checkHelloEndpoint() { + ResponseEntity response = testRestTemplate.getForEntity("/hello", String.class); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertEquals("Hello!", response.getBody()); + } - @Test - public void checkGoodbyeEndpoint() { - ResponseEntity response = testRestTemplate.getForEntity("/goodbye", String.class); - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertEquals("Goodbye!", response.getBody()); - } + @Test + public void checkGoodbyeEndpoint() { + ResponseEntity response = testRestTemplate.getForEntity("/goodbye", String.class); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertEquals("Goodbye!", response.getBody()); + } - @Test - public void whenExceptionAssaultIsActivatedExpectExceptionIsThrown() { - AssaultPropertiesUpdate assault = new AssaultPropertiesUpdate(); - assault.setLevel(1); - assault.setExceptionsActive(true); - assault.setLatencyActive(false); + @Test + public void whenExceptionAssaultIsActivatedExpectExceptionIsThrown() { + AssaultPropertiesUpdate assault = new AssaultPropertiesUpdate(); + assault.setLevel(1); + assault.setExceptionsActive(true); + assault.setLatencyActive(false); - ResponseEntity assaultResponse = - testRestTemplate.postForEntity( - "http://localhost:" + managementPort + "/actuator/chaosmonkey/assaults", - assault, - String.class); - assertEquals(HttpStatus.OK, assaultResponse.getStatusCode()); + ResponseEntity assaultResponse = testRestTemplate + .postForEntity("http://localhost:" + managementPort + "/actuator/chaosmonkey/assaults", assault, String.class); + assertEquals(HttpStatus.OK, assaultResponse.getStatusCode()); - ResponseEntity response = testRestTemplate.getForEntity("/goodbye", String.class); - assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); - } + ResponseEntity response = testRestTemplate.getForEntity("/goodbye", String.class); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + } } diff --git a/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerTest.java b/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerTest.java index a4e57e0a..513a54c5 100644 --- a/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerTest.java +++ b/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/controller/HelloControllerTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.example.chaos.monkey.chaosdemo.controller; import static org.mockito.Mockito.when; @@ -33,53 +32,43 @@ @WebMvcTest(HelloController.class) public class HelloControllerTest { - @Autowired private MockMvc mockMvc; + @Autowired + private MockMvc mockMvc; - @MockBean private GreetingService greetingServiceMock; + @MockBean + private GreetingService greetingServiceMock; - private String responseService; + private String responseService; - private String responseRepo; + private String responseRepo; - @BeforeEach - public void setup() { - responseService = "Hello from service!"; - when(greetingServiceMock.greet()).thenReturn(responseService); - responseRepo = "Hello from repo!"; - when(greetingServiceMock.greetFromRepo()).thenReturn(responseRepo); - } + @BeforeEach + public void setup() { + responseService = "Hello from service!"; + when(greetingServiceMock.greet()).thenReturn(responseService); + responseRepo = "Hello from repo!"; + when(greetingServiceMock.greetFromRepo()).thenReturn(responseRepo); + } - @Test - public void shouldReturnHello() throws Exception { + @Test + public void shouldReturnHello() throws Exception { - this.mockMvc - .perform(get("/hello")) - .andExpect(status().isOk()) - .andExpect(content().string("Hello!")); - } + this.mockMvc.perform(get("/hello")).andExpect(status().isOk()).andExpect(content().string("Hello!")); + } - @Test - public void callMockServiceGreet() throws Exception { + @Test + public void callMockServiceGreet() throws Exception { - this.mockMvc - .perform(get("/greet")) - .andExpect(status().isOk()) - .andExpect(content().string(responseService)); - } + this.mockMvc.perform(get("/greet")).andExpect(status().isOk()).andExpect(content().string(responseService)); + } - @Test - public void callMockServiceDbGreet() throws Exception { + @Test + public void callMockServiceDbGreet() throws Exception { - this.mockMvc - .perform(get("/dbgreet")) - .andExpect(status().isOk()) - .andExpect(content().string(responseRepo)); - } + this.mockMvc.perform(get("/dbgreet")).andExpect(status().isOk()).andExpect(content().string(responseRepo)); + } - public void shouldReturnGoodbye() throws Exception { - this.mockMvc - .perform(get("/goodbye")) - .andExpect(status().isOk()) - .andExpect(content().string("Goodbye!")); - } + public void shouldReturnGoodbye() throws Exception { + this.mockMvc.perform(get("/goodbye")).andExpect(status().isOk()).andExpect(content().string("Goodbye!")); + } } diff --git a/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/repo/HelloTest.java b/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/repo/HelloTest.java index c55276b4..29e8cd03 100644 --- a/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/repo/HelloTest.java +++ b/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/repo/HelloTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.repo; import static org.assertj.core.api.Assertions.assertThat; @@ -7,25 +22,25 @@ /** @author Benjamin Wilms */ public class HelloTest { - @Test - public void checkConstructorGetter() { - String expectedValueMessage = "test"; - long id = 0; - Hello helloToTest = new Hello(id, expectedValueMessage); + @Test + public void checkConstructorGetter() { + String expectedValueMessage = "test"; + long id = 0; + Hello helloToTest = new Hello(id, expectedValueMessage); - assertThat(helloToTest.getMessage()).isEqualTo(expectedValueMessage); - assertThat(helloToTest.getId()).isEqualTo(id); - } + assertThat(helloToTest.getMessage()).isEqualTo(expectedValueMessage); + assertThat(helloToTest.getId()).isEqualTo(id); + } - @Test - public void checkSetterGetter() { - String expectedValueMessage = "test"; - long id = 0; - Hello helloToTest = new Hello(99, "empty"); - helloToTest.setId(id); - helloToTest.setMessage(expectedValueMessage); + @Test + public void checkSetterGetter() { + String expectedValueMessage = "test"; + long id = 0; + Hello helloToTest = new Hello(99, "empty"); + helloToTest.setId(id); + helloToTest.setMessage(expectedValueMessage); - assertThat(helloToTest.getMessage()).isEqualTo(expectedValueMessage); - assertThat(helloToTest.getId()).isEqualTo(id); - } + assertThat(helloToTest.getMessage()).isEqualTo(expectedValueMessage); + assertThat(helloToTest.getId()).isEqualTo(id); + } } diff --git a/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/service/GreetingServiceTest.java b/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/service/GreetingServiceTest.java index 3a8eb367..5cdeb4b7 100644 --- a/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/service/GreetingServiceTest.java +++ b/demo-apps/chaos-monkey-demo-app/src/test/java/com/example/chaos/monkey/chaosdemo/service/GreetingServiceTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2018-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.service; import static org.assertj.core.api.Assertions.assertThat; @@ -23,85 +38,79 @@ @ExtendWith(MockitoExtension.class) public class GreetingServiceTest { - @Mock private HelloRepo helloRepoMock; - - @Mock private HelloRepoSearchAndSorting helloRepoSearchAndSortingMock; - - @Mock private HelloRepoJpa helloRepoJpaMock; - - @Mock private HelloRepoAnnotation helloRepoAnnotationMock; - - private GreetingService greetingService; - - @BeforeEach - public void setUp() { - greetingService = - new GreetingService( - helloRepoMock, - helloRepoSearchAndSortingMock, - helloRepoJpaMock, - helloRepoAnnotationMock); - } - - @Test - public void greet() { - assertThat(greetingService.greet()).isEqualTo("Greetings from the server side!"); - } - - @Test - public void greetFromRepo() { - String message = "message"; - Hello saveObject = new Hello(0, message); - when(helloRepoMock.save(any(Hello.class))).thenReturn(saveObject); - - assertThat(greetingService.greetFromRepo()).isEqualTo(message); - - verify(helloRepoMock, times(1)).save(any(Hello.class)); - verifyNoMoreInteractions( - helloRepoMock, helloRepoSearchAndSortingMock, helloRepoJpaMock, helloRepoAnnotationMock); - } - - @Test - public void testPagingAndSorting() { - String message = "message"; - Hello saveObject = new Hello(0, message); - when(helloRepoSearchAndSortingMock.save(any(Hello.class))).thenReturn(saveObject); - when(helloRepoSearchAndSortingMock.findById(saveObject.getId())) - .thenReturn(Optional.of(saveObject)); - - assertThat(greetingService.greetFromRepoPagingSorting()).isEqualTo(message); - - verify(helloRepoSearchAndSortingMock, times(1)).save(any(Hello.class)); - verify(helloRepoSearchAndSortingMock, times(1)).findById(saveObject.getId()); - verifyNoMoreInteractions( - helloRepoMock, helloRepoSearchAndSortingMock, helloRepoJpaMock, helloRepoAnnotationMock); - } - - @Test - public void testJpaRepo() { - String message = "message"; - Hello saveObject = new Hello(0, message); - when(helloRepoJpaMock.save(any(Hello.class))).thenReturn(saveObject); - when(helloRepoJpaMock.findById(saveObject.getId())).thenReturn(Optional.of(saveObject)); - - assertThat(greetingService.greetFromRepoJpa()).isEqualTo(message); - verify(helloRepoJpaMock, times(1)).save(any(Hello.class)); - verify(helloRepoJpaMock, times(1)).findById(saveObject.getId()); - verifyNoMoreInteractions( - helloRepoMock, helloRepoSearchAndSortingMock, helloRepoJpaMock, helloRepoAnnotationMock); - } - - @Test - public void testAnnotationRepo() { - String message = "message"; - Hello saveObject = new Hello(0, message); - when(helloRepoAnnotationMock.save(any(Hello.class))).thenReturn(saveObject); - when(helloRepoAnnotationMock.findById(saveObject.getId())).thenReturn(Optional.of(saveObject)); - - assertThat(greetingService.greetFromRepoAnnotation()).isEqualTo(message); - verify(helloRepoAnnotationMock, times(1)).save(any(Hello.class)); - verify(helloRepoAnnotationMock, times(1)).findById(saveObject.getId()); - verifyNoMoreInteractions( - helloRepoMock, helloRepoSearchAndSortingMock, helloRepoJpaMock, helloRepoAnnotationMock); - } + @Mock + private HelloRepo helloRepoMock; + + @Mock + private HelloRepoSearchAndSorting helloRepoSearchAndSortingMock; + + @Mock + private HelloRepoJpa helloRepoJpaMock; + + @Mock + private HelloRepoAnnotation helloRepoAnnotationMock; + + private GreetingService greetingService; + + @BeforeEach + public void setUp() { + greetingService = new GreetingService(helloRepoMock, helloRepoSearchAndSortingMock, helloRepoJpaMock, helloRepoAnnotationMock); + } + + @Test + public void greet() { + assertThat(greetingService.greet()).isEqualTo("Greetings from the server side!"); + } + + @Test + public void greetFromRepo() { + String message = "message"; + Hello saveObject = new Hello(0, message); + when(helloRepoMock.save(any(Hello.class))).thenReturn(saveObject); + + assertThat(greetingService.greetFromRepo()).isEqualTo(message); + + verify(helloRepoMock, times(1)).save(any(Hello.class)); + verifyNoMoreInteractions(helloRepoMock, helloRepoSearchAndSortingMock, helloRepoJpaMock, helloRepoAnnotationMock); + } + + @Test + public void testPagingAndSorting() { + String message = "message"; + Hello saveObject = new Hello(0, message); + when(helloRepoSearchAndSortingMock.save(any(Hello.class))).thenReturn(saveObject); + when(helloRepoSearchAndSortingMock.findById(saveObject.getId())).thenReturn(Optional.of(saveObject)); + + assertThat(greetingService.greetFromRepoPagingSorting()).isEqualTo(message); + + verify(helloRepoSearchAndSortingMock, times(1)).save(any(Hello.class)); + verify(helloRepoSearchAndSortingMock, times(1)).findById(saveObject.getId()); + verifyNoMoreInteractions(helloRepoMock, helloRepoSearchAndSortingMock, helloRepoJpaMock, helloRepoAnnotationMock); + } + + @Test + public void testJpaRepo() { + String message = "message"; + Hello saveObject = new Hello(0, message); + when(helloRepoJpaMock.save(any(Hello.class))).thenReturn(saveObject); + when(helloRepoJpaMock.findById(saveObject.getId())).thenReturn(Optional.of(saveObject)); + + assertThat(greetingService.greetFromRepoJpa()).isEqualTo(message); + verify(helloRepoJpaMock, times(1)).save(any(Hello.class)); + verify(helloRepoJpaMock, times(1)).findById(saveObject.getId()); + verifyNoMoreInteractions(helloRepoMock, helloRepoSearchAndSortingMock, helloRepoJpaMock, helloRepoAnnotationMock); + } + + @Test + public void testAnnotationRepo() { + String message = "message"; + Hello saveObject = new Hello(0, message); + when(helloRepoAnnotationMock.save(any(Hello.class))).thenReturn(saveObject); + when(helloRepoAnnotationMock.findById(saveObject.getId())).thenReturn(Optional.of(saveObject)); + + assertThat(greetingService.greetFromRepoAnnotation()).isEqualTo(message); + verify(helloRepoAnnotationMock, times(1)).save(any(Hello.class)); + verify(helloRepoAnnotationMock, times(1)).findById(saveObject.getId()); + verifyNoMoreInteractions(helloRepoMock, helloRepoSearchAndSortingMock, helloRepoJpaMock, helloRepoAnnotationMock); + } } diff --git a/demo-apps/chaos-monkey-web-reactive-app/src/main/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplication.java b/demo-apps/chaos-monkey-web-reactive-app/src/main/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplication.java index 82e5b7f6..0691252d 100644 --- a/demo-apps/chaos-monkey-web-reactive-app/src/main/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplication.java +++ b/demo-apps/chaos-monkey-web-reactive-app/src/main/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplication.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.example.chaos.monkey.chaosdemo; import org.springframework.boot.SpringApplication; @@ -22,7 +21,7 @@ @SpringBootApplication public class ChaosDemoApplication { - public static void main(String[] args) { - SpringApplication.run(ChaosDemoApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(ChaosDemoApplication.class, args); + } } diff --git a/demo-apps/chaos-monkey-web-reactive-app/src/main/java/com/example/chaos/monkey/chaosdemo/RouterConfiguration.java b/demo-apps/chaos-monkey-web-reactive-app/src/main/java/com/example/chaos/monkey/chaosdemo/RouterConfiguration.java index 51a333c5..73e1af47 100644 --- a/demo-apps/chaos-monkey-web-reactive-app/src/main/java/com/example/chaos/monkey/chaosdemo/RouterConfiguration.java +++ b/demo-apps/chaos-monkey-web-reactive-app/src/main/java/com/example/chaos/monkey/chaosdemo/RouterConfiguration.java @@ -1,3 +1,18 @@ +/* + * Copyright 2019-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo; import com.example.chaos.monkey.chaosdemo.component.HelloComponent; @@ -13,11 +28,9 @@ @Configuration public class RouterConfiguration { - @Bean - public RouterFunction route(HelloComponent greetingHandler) { + @Bean + public RouterFunction route(HelloComponent greetingHandler) { - return RouterFunctions.route( - RequestPredicates.GET("/hello").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), - greetingHandler::hello); - } + return RouterFunctions.route(RequestPredicates.GET("/hello").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), greetingHandler::hello); + } } diff --git a/demo-apps/chaos-monkey-web-reactive-app/src/main/java/com/example/chaos/monkey/chaosdemo/component/HelloComponent.java b/demo-apps/chaos-monkey-web-reactive-app/src/main/java/com/example/chaos/monkey/chaosdemo/component/HelloComponent.java index 4f8f8786..2aa5f9a1 100644 --- a/demo-apps/chaos-monkey-web-reactive-app/src/main/java/com/example/chaos/monkey/chaosdemo/component/HelloComponent.java +++ b/demo-apps/chaos-monkey-web-reactive-app/src/main/java/com/example/chaos/monkey/chaosdemo/component/HelloComponent.java @@ -1,3 +1,18 @@ +/* + * Copyright 2019-2022 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 + * + * https://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 com.example.chaos.monkey.chaosdemo.component; import org.springframework.http.MediaType; @@ -11,9 +26,7 @@ @Component public class HelloComponent { - public Mono hello(ServerRequest request) { - return ServerResponse.ok() - .contentType(MediaType.TEXT_PLAIN) - .body(BodyInserters.fromObject("Hello, from Component!")); - } + public Mono hello(ServerRequest request) { + return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN).body(BodyInserters.fromObject("Hello, from Component!")); + } } diff --git a/demo-apps/chaos-monkey-web-reactive-app/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationTests.java b/demo-apps/chaos-monkey-web-reactive-app/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationTests.java index 979bb313..4d1b398d 100644 --- a/demo-apps/chaos-monkey-web-reactive-app/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationTests.java +++ b/demo-apps/chaos-monkey-web-reactive-app/src/test/java/com/example/chaos/monkey/chaosdemo/ChaosDemoApplicationTests.java @@ -1,11 +1,11 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2022 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 + * https://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, @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.example.chaos.monkey.chaosdemo; import static org.assertj.core.api.Assertions.assertThat; @@ -26,13 +25,15 @@ @SpringBootTest public class ChaosDemoApplicationTests { - @Autowired private ApplicationContext ctx; + @Autowired + private ApplicationContext ctx; - @Test - public void contextLoads() {} + @Test + public void contextLoads() { + } - @Test - public void checkMetricsBean() { - assertThat(ctx.getBean("metrics")).isNotNull(); - } + @Test + public void checkMetricsBean() { + assertThat(ctx.getBean("metrics")).isNotNull(); + } } diff --git a/license.template.txt b/license.template.txt new file mode 100644 index 00000000..3e25a79b --- /dev/null +++ b/license.template.txt @@ -0,0 +1,15 @@ +/* + * Copyright $YEAR 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 + * + * https://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. + */ diff --git a/pom.xml b/pom.xml index 338df6eb..1327b75e 100644 --- a/pom.xml +++ b/pom.xml @@ -88,7 +88,7 @@ chaos-monkey-spring-boot-parent codecentric AG - http://www.codecentric.de + https://www.codecentric.de pom @@ -199,12 +199,14 @@ spotless-maven-plugin ${spotless-plugin.version} + origin/main - - ${google-java-format.version} - - + + code-style.xml + + + license.template.txt + @@ -287,7 +289,7 @@ Apache License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0 + https://www.apache.org/licenses/LICENSE-2.0 4.0.0