From b56b66badbd06293bbc6c32dfc4f1035294f6d26 Mon Sep 17 00:00:00 2001 From: stephane brossier Date: Fri, 1 Dec 2023 14:08:35 -0800 Subject: [PATCH] lifecycle: Introduce a LifecycleConfig. See killbill/killbill#1911 We have a first use case to configure our lifecycle to decide whether system should exit when some plugins fail to start. --- lifecycle/pom.xml | 4 +++ .../billing/lifecycle/DefaultLifecycle.java | 18 +++++------ .../lifecycle/config/LifecycleConfig.java | 32 +++++++++++++++++++ .../lifecycle/glue/LifecycleModule.java | 17 +++++++++- .../billing/lifecycle/TestLifecycle.java | 2 +- .../modules/KillbillPlatformModule.java | 2 +- 6 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 lifecycle/src/main/java/org/killbill/billing/lifecycle/config/LifecycleConfig.java diff --git a/lifecycle/pom.xml b/lifecycle/pom.xml index f3b7d9d1..988a6431 100644 --- a/lifecycle/pom.xml +++ b/lifecycle/pom.xml @@ -59,6 +59,10 @@ org.kill-bill.billing killbill-platform-api + + org.kill-bill.billing + killbill-platform-base + org.kill-bill.commons killbill-clock diff --git a/lifecycle/src/main/java/org/killbill/billing/lifecycle/DefaultLifecycle.java b/lifecycle/src/main/java/org/killbill/billing/lifecycle/DefaultLifecycle.java index 5b2a8496..333a0639 100644 --- a/lifecycle/src/main/java/org/killbill/billing/lifecycle/DefaultLifecycle.java +++ b/lifecycle/src/main/java/org/killbill/billing/lifecycle/DefaultLifecycle.java @@ -35,6 +35,7 @@ import javax.inject.Inject; import org.killbill.billing.lifecycle.api.Lifecycle; +import org.killbill.billing.lifecycle.config.LifecycleConfig; import org.killbill.billing.platform.api.KillbillService; import org.killbill.billing.platform.api.LifecycleHandlerType; import org.killbill.billing.platform.api.LifecycleHandlerType.LifecycleLevel; @@ -52,26 +53,25 @@ public class DefaultLifecycle implements Lifecycle { // See https://github.com/killbill/killbill-commons/issues/143 private final Map>> handlersByLevel; - private static final String EXIT_ON_LIFECYCLE_ERROR_PROPERTY = "org.killbill.server.exit.on.lifecycle.error"; - private boolean exitOnError; + private final LifecycleConfig config; @Inject - public DefaultLifecycle(final Injector injector) { - this(); + public DefaultLifecycle(final Injector injector, final LifecycleConfig config) { + this(config); final ServiceFinder serviceFinder = new ServiceFinder<>(DefaultLifecycle.class.getClassLoader(), KillbillService.class.getName()); - exitOnError = System.getProperty(EXIT_ON_LIFECYCLE_ERROR_PROPERTY) != null && Boolean.parseBoolean(System.getProperty(EXIT_ON_LIFECYCLE_ERROR_PROPERTY)); init(serviceFinder, injector); } // For testing public DefaultLifecycle(final Iterable services) { - this(); + this((LifecycleConfig) null); init(services); } - private DefaultLifecycle() { + private DefaultLifecycle(final LifecycleConfig config) { this.handlersByLevel = new ConcurrentHashMap<>(); + this.config = config; } @Override @@ -158,8 +158,8 @@ private void doFireStage(final LifecycleHandlerType.LifecycleLevel level) { method.invoke(target); } catch (final Exception e) { logWarn("Killbill lifecycle failed to invoke lifecycle handler", e); - if (exitOnError) { - log.info("{} is set, so exiting..", EXIT_ON_LIFECYCLE_ERROR_PROPERTY); + if (config.isServerExitOnLifecycleError()) { + log.warn("Existing as system was configured to exist on lifecycle error "); System.exit(1); } } diff --git a/lifecycle/src/main/java/org/killbill/billing/lifecycle/config/LifecycleConfig.java b/lifecycle/src/main/java/org/killbill/billing/lifecycle/config/LifecycleConfig.java new file mode 100644 index 00000000..9622a2a9 --- /dev/null +++ b/lifecycle/src/main/java/org/killbill/billing/lifecycle/config/LifecycleConfig.java @@ -0,0 +1,32 @@ +/* + * Copyright 2020-2023 Equinix, Inc + * Copyright 2014-2023 The Billing Project, LLC + * + * The Billing Project licenses this file to you under the Apache License, version 2.0 + * (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package org.killbill.billing.lifecycle.config; + +import org.killbill.billing.platform.api.KillbillPlatformConfig; +import org.skife.config.Config; +import org.skife.config.Default; +import org.skife.config.Description; + +public interface LifecycleConfig extends KillbillPlatformConfig { + + @Config(KILL_BILL_NAMESPACE + "server.exit.on.lifecycle.error") + @Default("false") + @Description("Exit on lifecycle error") + public boolean isServerExitOnLifecycleError(); + +} diff --git a/lifecycle/src/main/java/org/killbill/billing/lifecycle/glue/LifecycleModule.java b/lifecycle/src/main/java/org/killbill/billing/lifecycle/glue/LifecycleModule.java index 9d163735..12e08dc0 100644 --- a/lifecycle/src/main/java/org/killbill/billing/lifecycle/glue/LifecycleModule.java +++ b/lifecycle/src/main/java/org/killbill/billing/lifecycle/glue/LifecycleModule.java @@ -21,17 +21,32 @@ import org.killbill.billing.lifecycle.DefaultLifecycle; import org.killbill.billing.lifecycle.api.Lifecycle; +import org.killbill.billing.lifecycle.config.LifecycleConfig; +import org.killbill.billing.platform.api.KillbillConfigSource; +import org.killbill.billing.platform.glue.KillBillPlatformModuleBase; +import org.skife.config.ConfigSource; +import org.skife.config.ConfigurationObjectFactory; import com.google.inject.AbstractModule; -public class LifecycleModule extends AbstractModule { +public class LifecycleModule extends KillBillPlatformModuleBase { + + public LifecycleModule(final KillbillConfigSource configSource) { + super(configSource); + } @Override protected void configure() { installLifecycle(); } + protected void configureConfig() { + final LifecycleConfig lifecycleConfig = new ConfigurationObjectFactory(skifeConfigSource).build(LifecycleConfig.class); + bind(LifecycleConfig.class).toInstance(lifecycleConfig); + } + protected void installLifecycle() { + configureConfig(); bind(Lifecycle.class).to(DefaultLifecycle.class).asEagerSingleton(); } } diff --git a/lifecycle/src/test/java/org/killbill/billing/lifecycle/TestLifecycle.java b/lifecycle/src/test/java/org/killbill/billing/lifecycle/TestLifecycle.java index 472862d6..ddb8f1ee 100644 --- a/lifecycle/src/test/java/org/killbill/billing/lifecycle/TestLifecycle.java +++ b/lifecycle/src/test/java/org/killbill/billing/lifecycle/TestLifecycle.java @@ -224,7 +224,7 @@ public static class LifecycleNoWarn extends DefaultLifecycle { @Inject public LifecycleNoWarn(final Injector injector) { - super(injector); + super(injector, null); } @Override diff --git a/server/src/main/java/org/killbill/billing/server/modules/KillbillPlatformModule.java b/server/src/main/java/org/killbill/billing/server/modules/KillbillPlatformModule.java index f6a1476d..fe20a210 100644 --- a/server/src/main/java/org/killbill/billing/server/modules/KillbillPlatformModule.java +++ b/server/src/main/java/org/killbill/billing/server/modules/KillbillPlatformModule.java @@ -204,7 +204,7 @@ protected void configureEmbeddedDBs() { } protected void configureLifecycle() { - install(new LifecycleModule()); + install(new LifecycleModule(configSource)); } protected void configureBuses() {