You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2021/04/22 07:00:55 UTC
[camel] 01/04: CAMEL-16494: After VetoCamelContextStartException
CamelContext instance broken forever
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
commit ac64622f8d934648379543e6c773cebcafd76b6a
Author: Акинцев Валерий Андреевич <ak...@gazprom-neft.ru>
AuthorDate: Wed Apr 21 22:28:03 2021 +0300
CAMEL-16494: After VetoCamelContextStartException CamelContext instance broken forever
---
.../apache/camel/support/service/BaseService.java | 4 +
.../camel/impl/engine/AbstractCamelContext.java | 50 +++++---
.../engine/VetoCamelContextStartExceptionTest.java | 139 +++++++++++++++++++++
3 files changed, 176 insertions(+), 17 deletions(-)
diff --git a/core/camel-api/src/main/java/org/apache/camel/support/service/BaseService.java b/core/camel-api/src/main/java/org/apache/camel/support/service/BaseService.java
index 8cfc17d..6ee434c 100644
--- a/core/camel-api/src/main/java/org/apache/camel/support/service/BaseService.java
+++ b/core/camel-api/src/main/java/org/apache/camel/support/service/BaseService.java
@@ -109,6 +109,10 @@ public abstract class BaseService {
return;
}
init();
+ if (status == FAILED) {
+ LOG.trace("Init failed");
+ return;
+ }
try (AutoCloseable ignored = doLifecycleChange()) {
status = STARTING;
LOG.trace("Starting service: {}", this);
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index b73bb94..6f35049 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -2476,18 +2476,21 @@ public abstract class AbstractCamelContext extends BaseService
@Override
public void init() {
- super.init();
+ try {
+ super.init();
+ } catch (RuntimeCamelException e) {
+ if (e.getCause() != null && e.getCause() instanceof VetoCamelContextStartException) {
+ vetoed = (VetoCamelContextStartException) e.getCause();
+ } else {
+ throw e;
+ }
+ }
// was the initialization vetoed?
if (vetoed != null) {
- if (vetoed.isRethrowException()) {
- throw RuntimeCamelException.wrapRuntimeException(vetoed);
- } else {
- LOG.info("CamelContext ({}) vetoed to not initialize due to {}", getName(), vetoed.getMessage());
- // swallow exception and change state of this camel context to stopped
- fail(vetoed);
- return;
- }
+ LOG.info("CamelContext ({}) vetoed to not initialize due to {}", getName(), vetoed.getMessage());
+ failOnStartup(vetoed);
+ return;
}
}
@@ -2502,14 +2505,10 @@ public abstract class AbstractCamelContext extends BaseService
// did the start veto?
if (vetoed != null) {
- if (vetoed.isRethrowException()) {
- throw RuntimeCamelException.wrapRuntimeException(vetoed);
- } else {
- LOG.info("CamelContext ({}) vetoed to not start due to {}", getName(), vetoed.getMessage());
- // swallow exception and change state of this camel context to stopped
- stop();
- return;
- }
+ LOG.info("CamelContext ({}) vetoed to not start due to {}", getName(), vetoed.getMessage());
+ failOnStartup(vetoed);
+ stop();
+ return;
}
for (LifecycleStrategy strategy : lifecycleStrategies) {
@@ -2624,6 +2623,8 @@ public abstract class AbstractCamelContext extends BaseService
public void doInit() throws Exception {
StopWatch watch = new StopWatch();
+ vetoed = null;
+
StartupStep step = startupStepRecorder.beginStep(CamelContext.class, null, "Init CamelContext");
// init the route controller
@@ -4847,6 +4848,21 @@ public abstract class AbstractCamelContext extends BaseService
return "CamelContext(" + getName() + ")";
}
+
+ protected void failOnStartup(Exception e) {
+ if (e instanceof VetoCamelContextStartException) {
+ VetoCamelContextStartException vetoException = (VetoCamelContextStartException) e;
+ if (vetoException.isRethrowException()) {
+ fail(e);
+ } else {
+ // swallow exception and change state of this camel context to stopped
+ status = FAILED;
+ }
+ } else {
+ fail(e);
+ }
+ }
+
protected abstract ExchangeFactory createExchangeFactory();
protected abstract ExchangeFactoryManager createExchangeFactoryManager();
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/engine/VetoCamelContextStartExceptionTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/engine/VetoCamelContextStartExceptionTest.java
new file mode 100644
index 0000000..9b27033
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/engine/VetoCamelContextStartExceptionTest.java
@@ -0,0 +1,139 @@
+package org.apache.camel.impl.engine;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ServiceStatus;
+import org.apache.camel.VetoCamelContextStartException;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.support.LifecycleStrategySupport;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class VetoCamelContextStartExceptionTest {
+
+ @Test
+ public void testVetoOnStarting() {
+ CamelContext context = new DefaultCamelContext();
+ context.addLifecycleStrategy(
+ new LifecycleStrategySupport() {
+ @Override
+ public void onContextStarting(CamelContext context) throws VetoCamelContextStartException {
+ throw new VetoCamelContextStartException("Veto on starting", context, true);
+ }
+ });
+
+ Throwable throwable = assertThrows(Throwable.class, context::start);
+
+ assertTrue(context.isVetoStarted());
+ assertEquals(ServiceStatus.Stopped, context.getStatus());
+ assertEquals("org.apache.camel.VetoCamelContextStartException: Veto on starting", throwable.getMessage());
+ }
+
+ @Test
+ public void testVetoOnStartingWithoutRethrow() {
+ CamelContext context = new DefaultCamelContext();
+ context.addLifecycleStrategy(
+ new LifecycleStrategySupport() {
+ @Override
+ public void onContextStarting(CamelContext context) throws VetoCamelContextStartException {
+ throw new VetoCamelContextStartException("Veto on starting", context, false);
+ }
+ });
+ context.start();
+ assertTrue(context.isVetoStarted());
+ assertEquals(ServiceStatus.Stopped, context.getStatus());
+ }
+
+ @Test
+ public void testVetoOnInitializing() {
+ CamelContext context = new DefaultCamelContext();
+ context.addLifecycleStrategy(
+ new LifecycleStrategySupport() {
+ @Override
+ public void onContextInitializing(CamelContext context) throws VetoCamelContextStartException {
+ throw new VetoCamelContextStartException("Veto on initializing", context, true);
+ }
+ });
+
+ Throwable throwable = assertThrows(Throwable.class, context::start);
+ assertTrue(context.isVetoStarted());
+ assertEquals(ServiceStatus.Stopped, context.getStatus());
+ assertEquals("org.apache.camel.VetoCamelContextStartException: Veto on initializing", throwable.getMessage());
+ }
+
+ @Test
+ public void testVetoOnInitializingWithoutRethrow() {
+ CamelContext context = new DefaultCamelContext();
+ context.addLifecycleStrategy(
+ new LifecycleStrategySupport() {
+ @Override
+ public void onContextInitializing(CamelContext context) throws VetoCamelContextStartException {
+ throw new VetoCamelContextStartException("Veto on initializing", context, false);
+ }
+ });
+ context.start();
+ assertTrue(context.isVetoStarted());
+ assertEquals(ServiceStatus.Stopped, context.getStatus());
+ }
+
+ @Test
+ public void testVetoOnInitialized() {
+ CamelContext context = new DefaultCamelContext();
+ context.addLifecycleStrategy(
+ new LifecycleStrategySupport() {
+ @Override
+ public void onContextInitialized(CamelContext context) throws VetoCamelContextStartException {
+ throw new VetoCamelContextStartException("Veto on initialized", context, true);
+ }
+ });
+
+ Throwable throwable = assertThrows(Throwable.class, context::start);
+ assertTrue(context.isVetoStarted());
+ assertEquals(ServiceStatus.Stopped, context.getStatus());
+ assertEquals("org.apache.camel.VetoCamelContextStartException: Veto on initialized", throwable.getMessage());
+ }
+
+ @Test
+ public void testVetoOnInitializedWithoutRethrow() {
+ CamelContext context = new DefaultCamelContext();
+ context.addLifecycleStrategy(
+ new LifecycleStrategySupport() {
+ @Override
+ public void onContextInitialized(CamelContext context) throws VetoCamelContextStartException {
+ throw new VetoCamelContextStartException("Veto on initialized", context, false);
+ }
+ });
+ context.start();
+ assertTrue(context.isVetoStarted());
+ assertEquals(ServiceStatus.Stopped, context.getStatus());
+ }
+
+ @Test
+ public void testVetoReset() throws Exception {
+ try (CamelContext context = new DefaultCamelContext()) {
+ boolean[] needThrowVeto = new boolean[] { true };
+ context.addLifecycleStrategy(
+ new LifecycleStrategySupport() {
+ @Override
+ public void onContextInitialized(CamelContext context) throws VetoCamelContextStartException {
+ if (needThrowVeto[0]) {
+ needThrowVeto[0] = false;
+ throw new VetoCamelContextStartException("Veto on initialized", context, false);
+ }
+ }
+ });
+
+ context.start();
+ assertTrue(context.isVetoStarted());
+ assertEquals(ServiceStatus.Stopped, context.getStatus());
+
+ context.start();
+ assertFalse(context.isVetoStarted());
+ assertEquals(ServiceStatus.Started, context.getStatus());
+ }
+
+ }
+}