From 6180040137d717b8d2be66acd236e5867a397f82 Mon Sep 17 00:00:00 2001 From: Kristian Kraljic Date: Mon, 12 Apr 2021 22:47:28 +0200 Subject: [PATCH] refactor!: refactor NeonBee class --- src/main/java/io/neonbee/Launcher.java | 11 +- src/main/java/io/neonbee/NeonBee.java | 208 +++++++++--------- src/main/java/io/neonbee/NeonBeeConfig.java | 14 +- .../java/io/neonbee/data/DataVerticle.java | 8 +- .../io/neonbee/entity/EntityModelManager.java | 2 +- .../io/neonbee/entity/EntityVerticle.java | 6 +- .../hook/internal/DefaultHookRegistry.java | 6 +- .../internal/deploy/NeonBeeModule.java | 5 +- .../internal/handler/HooksHandler.java | 2 +- .../internal/handler/InstanceInfoHandler.java | 2 +- .../neonbee/internal/helper/ConfigHelper.java | 41 +--- .../internal/helper/FileSystemHelper.java | 38 ---- .../internal/verticle/ServerVerticle.java | 2 +- src/main/java/io/neonbee/job/JobVerticle.java | 2 +- .../java/io/neonbee/NeonBeeExtension.java | 2 +- src/test/java/io/neonbee/NeonBeeTest.java | 30 +-- .../handler/InstanceInfoHandlerTest.java | 2 +- .../verticle/ReadmeVerticlesTest.java | 2 +- .../io/neonbee/test/base/NeonBeeTestBase.java | 16 +- 19 files changed, 148 insertions(+), 251 deletions(-) diff --git a/src/main/java/io/neonbee/Launcher.java b/src/main/java/io/neonbee/Launcher.java index c3b4ebdc..2730d147 100644 --- a/src/main/java/io/neonbee/Launcher.java +++ b/src/main/java/io/neonbee/Launcher.java @@ -105,13 +105,10 @@ public static void main(String[] args) { List preProcessors = loader.stream().map(ServiceLoader.Provider::get).collect(Collectors.toList()); executePreProcessors(preProcessors, options); - NeonBee.instance(options, asyncNeonBee -> { - if (asyncNeonBee.failed()) { - System.err.println("Failed to start NeonBee '" + asyncNeonBee.cause().getMessage() + "'"); // NOPMD - return; - } - - neonBee = asyncNeonBee.result(); + NeonBee.create(options).onSuccess(neonBee -> { + Launcher.neonBee = neonBee; + }).onFailure(cause -> { + System.err.println("Failed to start NeonBee '" + cause.getMessage() + "'"); // NOPMD }); } catch (Exception e) { System.err.println("Error occurred during launcher pre-processing. " + e.getMessage()); // NOPMD diff --git a/src/main/java/io/neonbee/NeonBee.java b/src/main/java/io/neonbee/NeonBee.java index eb57cbbd..413ddbac 100644 --- a/src/main/java/io/neonbee/NeonBee.java +++ b/src/main/java/io/neonbee/NeonBee.java @@ -2,7 +2,10 @@ import static ch.qos.logback.classic.util.ContextInitializer.CONFIG_FILE_PROPERTY; import static io.neonbee.internal.helper.AsyncHelper.allComposite; +import static io.neonbee.internal.helper.ConfigHelper.readConfig; +import static io.neonbee.internal.helper.HostHelper.getHostIp; import static io.neonbee.internal.scanner.DeployableScanner.scanForDeployableClasses; +import static io.vertx.core.CompositeFuture.all; import static io.vertx.core.Future.failedFuture; import static io.vertx.core.Future.succeededFuture; import static java.lang.System.setProperty; @@ -15,9 +18,11 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.TimeZone; import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -25,7 +30,6 @@ import org.slf4j.LoggerFactory; import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Strings; import com.hazelcast.core.Hazelcast; import com.hazelcast.core.HazelcastInstance; @@ -57,12 +61,9 @@ import io.neonbee.internal.verticle.ServerVerticle; import io.netty.util.internal.logging.InternalLoggerFactory; import io.netty.util.internal.logging.Slf4JLoggerFactory; -import io.vertx.core.AsyncResult; import io.vertx.core.Closeable; import io.vertx.core.Context; import io.vertx.core.Future; -import io.vertx.core.Handler; -import io.vertx.core.Promise; import io.vertx.core.Verticle; import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; @@ -138,12 +139,13 @@ public class NeonBee { private static final int NUMBER_DEFAULT_INSTANCES = 16; + @VisibleForTesting + NeonBeeConfig config; + private final Vertx vertx; private final NeonBeeOptions options; - private final NeonBeeConfig config; - private final HookRegistry hookRegistry; private LocalMap sharedLocalMap; @@ -152,47 +154,18 @@ public class NeonBee { private final Set localConsumers = new ConcurrentHashSet<>(); - @VisibleForTesting - static Future initVertx(NeonBeeOptions options) { - VertxOptions vertxOptions = new VertxOptions().setEventLoopPoolSize(options.getEventLoopPoolSize()) - .setWorkerPoolSize(options.getWorkerPoolSize()).setMetricsOptions(new MicrometerMetricsOptions() - .setPrometheusOptions(new VertxPrometheusOptions().setEnabled(true)).setEnabled(true)); - - Promise promise = Promise.promise(); - if (options.isClustered()) { - HazelcastInstance hzInstance = Hazelcast.newHazelcastInstance(options.getClusterConfig()); - vertxOptions.setClusterManager(new HazelcastClusterManager(hzInstance)).getEventBusOptions() - .setPort(options.getClusterPort()); - String currentIp = System.getenv("CF_INSTANCE_INTERNAL_IP"); - if (!Strings.isNullOrEmpty(currentIp)) { - vertxOptions.getEventBusOptions().setHost(currentIp); - } - Vertx.clusteredVertx(vertxOptions, result -> { - if (result.failed()) { - logger.error("Failed to start Vertx cluster", result.cause()); // NOPMD slf4j - promise.fail(result.cause()); - } else { - promise.complete(result.result()); - } - }); - } else { - promise.complete(Vertx.vertx(vertxOptions)); - } - return promise.future(); - } - /** * Convenience method for returning the current NeonBee instance. *

* Important: Will only return a value in case a Vert.x context is available, otherwise returns null. Attention: * This method is NOT signature compliant to {@link Vertx#vertx()}! It will NOT create a new NeonBee instance, - * please use {@link NeonBee#instance(Handler)} or {@link NeonBee#instance(NeonBeeOptions, Handler)} instead. + * please use {@link NeonBee#create(NeonBeeOptions)} or {@link NeonBee#create(Supplier, NeonBeeOptions)} instead. * * @return A NeonBee instance or null */ - public static NeonBee instance() { + public static NeonBee get() { Context context = Vertx.currentContext(); - return context != null ? instance(context.owner()) : null; + return context != null ? get(context.owner()) : null; } /** @@ -201,18 +174,17 @@ public static NeonBee instance() { * @param vertx The Vert.x instance to get the NeonBee instance from * @return A NeonBee instance or null */ - public static NeonBee instance(Vertx vertx) { + public static NeonBee get(Vertx vertx) { return NEONBEE_INSTANCES.get(vertx); } /** * Create a new NeonBee instance, with default options. Similar to the static {@link Vertx#vertx()} method. * - * @param resultHandler the result handler which is called as soon as the NeonBee instance has been created or the - * creation failed + * @return the future to a new NeonBee instance initialized with default options and a new Vert.x instance */ - public static void instance(Handler> resultHandler) { - instance(new NeonBeeOptions.Mutable(), resultHandler); + public static Future create() { + return create(new NeonBeeOptions.Mutable()); } /** @@ -220,28 +192,25 @@ public static void instance(Handler> resultHandler) { *

* Note: This method is NOT a static method like {@link Vertx#vertx(VertxOptions)}, as no factory method is needed. * - * @param options the NeonBee command line options - * @param resultHandler the result handler which is called as soon as the NeonBee instance has been created or the - * creation failed + * @param options the NeonBee command line options + * @return the future to a new NeonBee instance initialized with default options and a new Vert.x instance */ - public static void instance(NeonBeeOptions options, Handler> resultHandler) { - instance(() -> initVertx(options), options, resultHandler); + public static Future create(NeonBeeOptions options) { + return create(() -> newVertx(options), options); } @VisibleForTesting @SuppressWarnings("PMD.EmptyCatchBlock") - static void instance(Supplier> vertxFutureSupplier, NeonBeeOptions options, - Handler> resultHandler) { - + static Future create(Supplier> vertxFutureSupplier, NeonBeeOptions options) { try { - // Create the NeonBee working and logging directory (as the only mandatory directory for NeonBee) + // create the NeonBee working and logging directory (as the only mandatory directory for NeonBee) Files.createDirectories(options.getLogDirectory()); } catch (IOException e) { // nothing to do here, we can also (at least try) to work w/o a working directory // we should discuss if NeonBee can run in general without a working dir or not } - // Switch to the SLF4J logging facade (using Logback as a logging backend). It is required to set the logging + // switch to the SLF4J logging facade (using Logback as a logging backend). It is required to set the logging // system properties before the first logger is initialized, so do it before the Vert.x initialization. setProperty(CONFIG_FILE_PROPERTY, options.getConfigDirectory().resolve("logback.xml").toString()); setProperty(HAZELCAST_LOGGING_TYPE, "slf4j"); @@ -249,39 +218,53 @@ static void instance(Supplier> vertxFutureSupplier, NeonBeeOptions InternalLoggerFactory.setDefaultFactory(Slf4JLoggerFactory.INSTANCE); logger = LoggerFactory.getLogger(NeonBee.class); - // Create a Vert.x instance (clustered or unclustered) - vertxFutureSupplier.get().compose(vertx -> bootstrap(options, vertx)).onComplete(resultHandler); + // create a Vert.x instance (clustered or unclustered) + return vertxFutureSupplier.get().compose(vertx -> { + // create a NeonBee instance, load the configuration and boot it up + NeonBee neonBee = new NeonBee(vertx, options); + + return neonBee.loadConfig().compose(config -> neonBee.boot()).map(neonBee); + }); } - private static Future bootstrap(NeonBeeOptions options, Vertx vertx) { - return succeededFuture(new NeonBee(vertx, options)).compose(neonBee -> neonBee.registerHooks() - .compose(v -> neonBee.getHookRegistry().executeHooks(HookType.BEFORE_BOOTSTRAP).mapEmpty()) - .compose(v -> succeededFuture(decorateEventBus(neonBee))) - .compose(v -> initializeSharedDataAccessor(neonBee)).compose(v -> neonBee.registerCodecs()) - .compose(v -> { - // Set the default TimeZone for date operations. This overwrites any configured - // user.timezone properties. - TimeZone.setDefault(TimeZone.getTimeZone(options.getTimeZoneId())); - return succeededFuture(); - }).compose(v -> neonBee.deployVerticles()).recover(throwable -> { - // the instance has been created, but after initialization some post-initialization - // tasks went wrong, stop Vert.x again. This will also call the close hook and clean up - vertx.close(); - - return failedFuture(throwable); // propagate the failure - }).compose(v -> neonBee.getHookRegistry().executeHooks(HookType.AFTER_STARTUP).mapEmpty()) - .map(neonBee)); + @VisibleForTesting + static Future newVertx(NeonBeeOptions options) { + VertxOptions vertxOptions = new VertxOptions().setEventLoopPoolSize(options.getEventLoopPoolSize()) + .setWorkerPoolSize(options.getWorkerPoolSize()).setMetricsOptions(new MicrometerMetricsOptions() + .setPrometheusOptions(new VertxPrometheusOptions().setEnabled(true)).setEnabled(true)); + + if (!options.isClustered()) { + return succeededFuture(Vertx.vertx(vertxOptions)); + } else { + HazelcastInstance hzInstance = Hazelcast.newHazelcastInstance(options.getClusterConfig()); + vertxOptions.setClusterManager(new HazelcastClusterManager(hzInstance)).getEventBusOptions() + .setPort(options.getClusterPort()); + Optional.ofNullable(getHostIp()).filter(Predicate.not(String::isEmpty)) + .ifPresent(currentIp -> vertxOptions.getEventBusOptions().setHost(currentIp)); + return Vertx.clusteredVertx(vertxOptions).onFailure(throwable -> { + logger.error("Failed to start Vertx cluster", throwable); // NOPMD slf4j + }); + } } - private static Future initializeSharedDataAccessor(NeonBee neonBee) { - return succeededFuture(new SharedDataAccessor(neonBee.getVertx(), NeonBee.class)) - .compose(sharedData -> AsyncHelper.executeBlocking(neonBee.getVertx(), promise -> { - neonBee.sharedLocalMap = sharedData.getLocalMap(SHARED_MAP_NAME); - sharedData.getAsyncMap(SHARED_MAP_NAME, asyncResult -> { - neonBee.sharedAsyncMap = asyncResult.result(); - promise.handle(asyncResult.mapEmpty()); - }); - })); + private Future boot() { + return registerHooks().compose(nothing -> hookRegistry.executeHooks(HookType.BEFORE_BOOTSTRAP)) + .compose(anything -> { + // set the default timezone and overwrite any configured user.timezone property + TimeZone.setDefault(TimeZone.getTimeZone(options.getTimeZoneId())); + + // decorate the event bus with in- & outbound interceptors for tracking + decorateEventBus(); + + return all(initializeSharedDataAccessor(), registerCodecs()).compose(nothing -> deployVerticles()) + .onFailure(throwable -> { + // the instance has been created, but after initialization some post-initialization + // tasks went wrong, stop Vert.x again. This will also call the close hook and clean up + logger.error("Failure during bootstrap phase. Shutting down Vert.x instance.", + throwable); + vertx.close(); + }).compose(nothing -> hookRegistry.executeHooks(HookType.AFTER_STARTUP)); + }).mapEmpty(); } private Future registerHooks() { @@ -295,20 +278,31 @@ private Future registerHooks() { } @VisibleForTesting - static Void decorateEventBus(NeonBee neonBee) { + void decorateEventBus() { TrackingDataHandlingStrategy strategy; + try { - strategy = (TrackingDataHandlingStrategy) Class - .forName(neonBee.getConfig().getTrackingDataHandlingStrategy()).getConstructor().newInstance(); + strategy = (TrackingDataHandlingStrategy) Class.forName(config.getTrackingDataHandlingStrategy()) + .getConstructor().newInstance(); } catch (Exception e) { logger.warn("Failed to load configured tracking handling strategy {}. Use default.", - neonBee.getConfig().getTrackingDataHandlingStrategy(), e); + config.getTrackingDataHandlingStrategy(), e); strategy = new TrackingDataLoggingStrategy(); } - neonBee.getVertx().eventBus().addInboundInterceptor(new TrackingInterceptor(MessageDirection.INBOUND, strategy)) + + vertx.eventBus().addInboundInterceptor(new TrackingInterceptor(MessageDirection.INBOUND, strategy)) .addOutboundInterceptor(new TrackingInterceptor(MessageDirection.OUTBOUND, strategy)); + } - return null; + private Future initializeSharedDataAccessor() { + return succeededFuture(new SharedDataAccessor(vertx, NeonBee.class)) + .compose(sharedData -> AsyncHelper.executeBlocking(vertx, promise -> { + sharedLocalMap = sharedData.getLocalMap(SHARED_MAP_NAME); + sharedData.getAsyncMap(SHARED_MAP_NAME, asyncResult -> { + sharedAsyncMap = asyncResult.result(); + promise.handle(asyncResult.mapEmpty()); + }); + })); } /** @@ -358,7 +352,7 @@ private Future deployVerticles() { List> deployFutures = new ArrayList<>(deploySystemVerticles()); if (NeonBeeProfile.WEB.isActive(activeProfiles)) { - deployFutures.addAll(deployWebVerticles()); + deployFutures.add(deployServerVerticle()); } deployFutures.addAll(deployClassPathVerticles()); @@ -366,18 +360,18 @@ private Future deployVerticles() { } /** - * Deploy any web verticle (bundled w/ NeonBee). + * Deploy the server verticle handling the endpoints. * - * @return a list of futures deploying verticle + * @return the future deploying the server verticle */ - private List> deployWebVerticles() { - logger.info("Deploy web verticle."); + private Future deployServerVerticle() { + logger.info("Deploy server verticle"); - return List.of(Deployable + return Deployable .fromClass(vertx, ServerVerticle.class, CORRELATION_ID, new JsonObject().put("instances", NUMBER_DEFAULT_INSTANCES)) .compose(deployable -> deployable.deploy(vertx, CORRELATION_ID).future()) - .map(Deployment::getDeploymentId)); + .map(Deployment::getDeploymentId); } /** @@ -459,16 +453,20 @@ static boolean filterByAutoDeployAndProfiles(Class verticleC @VisibleForTesting NeonBee(Vertx vertx, NeonBeeOptions options) { - this.options = options; this.vertx = vertx; + this.options = options; // to be able to retrieve the NeonBee instance from any point you have a Vert.x instance add it to a global map NEONBEE_INSTANCES.put(vertx, this); this.hookRegistry = new DefaultHookRegistry(vertx); - this.config = new NeonBeeConfig(vertx); registerCloseHandler(vertx); } + private Future loadConfig() { + return readConfig(getVertx(), NeonBee.class.getName(), new JsonObject()) + .map(config -> this.config = new NeonBeeConfig(config)); + } + @SuppressWarnings("rawtypes") private void registerCloseHandler(Vertx vertx) { try { @@ -478,8 +476,8 @@ private void registerCloseHandler(Vertx vertx) { /* * Called when Vert.x instance is closed, perform shut-down operations here */ - handler.handle(getHookRegistry().executeHooks(HookType.BEFORE_SHUTDOWN) - .compose(shutdownHooksExecutionOutcomes -> { + handler.handle( + hookRegistry.executeHooks(HookType.BEFORE_SHUTDOWN).compose(shutdownHooksExecutionOutcomes -> { if (shutdownHooksExecutionOutcomes.failed()) { shutdownHooksExecutionOutcomes.list().stream().filter(Future::failed).forEach( future -> logger.error("Shutdown hook execution failed", future.cause())); // NOPMD @@ -560,18 +558,18 @@ public boolean isLocalConsumerAvailable(String targetVerticle) { /** * Registers a verticle as local consumer. * - * @param verticleAdresss verticle address + * @param verticleAddress verticle address */ - public void registerLocalConsumer(String verticleAdresss) { - localConsumers.add(verticleAdresss); + public void registerLocalConsumer(String verticleAddress) { + localConsumers.add(verticleAddress); } /** * Unregisters a verticle as local consumer. * - * @param verticleAdresss verticle address + * @param verticleAddress verticle address */ - public void unregisterLocalConsumer(String verticleAdresss) { - localConsumers.remove(verticleAdresss); + public void unregisterLocalConsumer(String verticleAddress) { + localConsumers.remove(verticleAddress); } } diff --git a/src/main/java/io/neonbee/NeonBeeConfig.java b/src/main/java/io/neonbee/NeonBeeConfig.java index 05e15e31..36774a52 100644 --- a/src/main/java/io/neonbee/NeonBeeConfig.java +++ b/src/main/java/io/neonbee/NeonBeeConfig.java @@ -1,7 +1,5 @@ package io.neonbee; -import static io.neonbee.internal.helper.ConfigHelper.readConfigBlocking; - import java.util.List; import java.util.Map; import java.util.Objects; @@ -12,7 +10,6 @@ import io.neonbee.internal.tracking.TrackingDataLoggingStrategy; import io.neonbee.logging.LoggingFacade; -import io.vertx.core.Vertx; import io.vertx.core.json.JsonObject; public class NeonBeeConfig { @@ -28,7 +25,7 @@ public class NeonBeeConfig { private static final String DEFAULT_TRACKING_DATA_HANDLING_STRATEGY = TrackingDataLoggingStrategy.class.getName(); - private int eventBusTimeout = DEFAULT_EVENT_BUS_TIMEOUT; + private final int eventBusTimeout; private final List platformClasses; @@ -36,15 +33,6 @@ public class NeonBeeConfig { private final Map eventBusCodecs; - /** - * Package scoped default constructor. - *

- * Should never be initialized by anyone, but only retrieved via neonbee.getConfig() - */ - NeonBeeConfig(Vertx vertx) { - this(readConfigBlocking(vertx, NeonBee.class.getName(), new JsonObject())); - } - /** * Create a NeonBee config from JSON. * diff --git a/src/main/java/io/neonbee/data/DataVerticle.java b/src/main/java/io/neonbee/data/DataVerticle.java index 27fb2889..7923168c 100644 --- a/src/main/java/io/neonbee/data/DataVerticle.java +++ b/src/main/java/io/neonbee/data/DataVerticle.java @@ -200,7 +200,7 @@ public void start(Promise promise) { registerDataVerticlePromise.future().compose(v -> { try { start(); - NeonBee.instance(vertx).registerLocalConsumer(address); + NeonBee.get(vertx).registerLocalConsumer(address); return succeededFuture((Void) null); } catch (Exception e) { return failedFuture(e); @@ -210,7 +210,7 @@ public void start(Promise promise) { @Override public void stop() throws Exception { - NeonBee neonBee = NeonBee.instance(vertx); + NeonBee neonBee = NeonBee.get(vertx); if (neonBee != null) { // NeonBee can be null, when the close hook has removed NeonBee - Vert.x mapping before neonBee.unregisterLocalConsumer(getAddress()); } @@ -387,7 +387,7 @@ private static DeliveryOptions requestDeliveryOptions(Vertx vertx, DataRequest r // adapt further delivery options based on the request boolean localOnly = request.isLocalOnly() - || (request.isLocalPreferred() && NeonBee.instance(vertx).isLocalConsumerAvailable(address)); + || (request.isLocalPreferred() && NeonBee.get(vertx).isLocalConsumerAvailable(address)); deliveryOptions.setLocalOnly(localOnly); if (request.getSendTimeout() > 0) { deliveryOptions.setSendTimeout(request.getSendTimeout()); @@ -409,7 +409,7 @@ private static DeliveryOptions requestDeliveryOptions(Vertx vertx, DataRequest r */ private static DeliveryOptions deliveryOptions(Vertx vertx, MessageCodec codec, DataContext context) { DeliveryOptions deliveryOptions = new DeliveryOptions(); - deliveryOptions.setSendTimeout(SECONDS.toMillis(NeonBee.instance(vertx).getConfig().getEventBusTimeout())) + deliveryOptions.setSendTimeout(SECONDS.toMillis(NeonBee.get(vertx).getConfig().getEventBusTimeout())) .setCodecName(Optional.ofNullable(codec).map(MessageCodec::name).orElse(null)); Optional.ofNullable(context).map(DataContextImpl::encodeContextToString) .ifPresent(value -> deliveryOptions.addHeader(CONTEXT_HEADER, value)); diff --git a/src/main/java/io/neonbee/entity/EntityModelManager.java b/src/main/java/io/neonbee/entity/EntityModelManager.java index 05ad1780..2ca9bb54 100644 --- a/src/main/java/io/neonbee/entity/EntityModelManager.java +++ b/src/main/java/io/neonbee/entity/EntityModelManager.java @@ -361,7 +361,7 @@ private Future> loadModelsFromModule(Map> loadModelsFromModelDirectoryAndClasspath() { - NeonBeeOptions options = NeonBee.instance(vertx).getOptions(); + NeonBeeOptions options = NeonBee.get(vertx).getOptions(); return CompositeFuture.all(loadDir(options.getModelsDirectory()), !options.shouldIgnoreClassPath() ? scanClassPath() : succeededFuture()).map(models); } diff --git a/src/main/java/io/neonbee/entity/EntityVerticle.java b/src/main/java/io/neonbee/entity/EntityVerticle.java index bbba10c7..f96c3ff1 100644 --- a/src/main/java/io/neonbee/entity/EntityVerticle.java +++ b/src/main/java/io/neonbee/entity/EntityVerticle.java @@ -187,8 +187,8 @@ protected static Future parseUriInfo(Vertx vertx, DataQuery query) { * @return A list of all (entity) verticle names as qualified names */ public static Future> getVerticlesForEntityType(Vertx vertx, FullQualifiedName entityTypeName) { - return Future.future( - asyncGet -> NeonBee.instance(vertx).getAsyncMap().get(sharedEntityMapName(entityTypeName), asyncGet)) + return Future + .future(asyncGet -> NeonBee.get(vertx).getAsyncMap().get(sharedEntityMapName(entityTypeName), asyncGet)) .map(qualifiedNames -> ((List) Optional.ofNullable((JsonArray) qualifiedNames) .orElse(new JsonArray()).getList()).stream().map(Object::toString).distinct() .collect(Collectors.toList())); @@ -248,7 +248,7 @@ private void announceEntityVerticle(Vertx vertx, Handler> done entityTypeNames().compose(fqns -> succeededFuture(Optional.ofNullable(fqns).orElse(Set.of()))); entityTypeNames.compose(asyncEntityTypeNames -> { - AsyncMap asyncSharedMap = NeonBee.instance(vertx).getAsyncMap(); + AsyncMap asyncSharedMap = NeonBee.get(vertx).getAsyncMap(); return CompositeFuture.all( asyncEntityTypeNames.stream().map(EntityVerticle::sharedEntityMapName).map(sharedEntityMapName -> { Promise promise = Promise.promise(); diff --git a/src/main/java/io/neonbee/hook/internal/DefaultHookRegistry.java b/src/main/java/io/neonbee/hook/internal/DefaultHookRegistry.java index d59e44a9..98f82ccb 100644 --- a/src/main/java/io/neonbee/hook/internal/DefaultHookRegistry.java +++ b/src/main/java/io/neonbee/hook/internal/DefaultHookRegistry.java @@ -67,7 +67,7 @@ public Future> registerInstanceHooks(Object instanc @Override public CompositeFuture executeHooks(HookType type, Map parameters) { List> hookExecutions = hookRegistry.getOrDefault(type, List.of()).stream() - .map(DefaultHookRegistration.class::cast).map(registration -> executeHook(NeonBee.instance(vertx), + .map(DefaultHookRegistration.class::cast).map(registration -> executeHook(NeonBee.get(vertx), registration, DefaultHookContext.of(type, parameters))) .collect(Collectors.toList()); @@ -76,8 +76,8 @@ public CompositeFuture executeHooks(HookType type, Map parameter @Override public Future> getHookRegistrations() { - Collection registrations = hookRegistry.entrySet().stream().map(Map.Entry::getValue) - .flatMap(List::stream).collect(Collectors.toList()); + Collection registrations = + hookRegistry.values().stream().flatMap(List::stream).collect(Collectors.toList()); return Future.succeededFuture(registrations); } diff --git a/src/main/java/io/neonbee/internal/deploy/NeonBeeModule.java b/src/main/java/io/neonbee/internal/deploy/NeonBeeModule.java index c10a29cb..7ec31928 100644 --- a/src/main/java/io/neonbee/internal/deploy/NeonBeeModule.java +++ b/src/main/java/io/neonbee/internal/deploy/NeonBeeModule.java @@ -274,9 +274,8 @@ public static Future fromJar(Vertx vertx, Path pathOfJar, String Map models = loadModelPayloads(classLoader, cps.scanManifestFiles(NEONBEE_MODELS)); Map extensionModels = loadModelPayloads(classLoader, cps.scanManifestFiles(NEONBEE_MODEL_EXTENSIONS)); - SelfFirstClassLoader moduleClassLoader = - new SelfFirstClassLoader(jarUrl, ClassLoader.getSystemClassLoader(), - NeonBee.instance(vertx).getConfig().getPlatformClasses()); + SelfFirstClassLoader moduleClassLoader = new SelfFirstClassLoader(jarUrl, + ClassLoader.getSystemClassLoader(), NeonBee.get(vertx).getConfig().getPlatformClasses()); verticleClasses.addAll(loadClassesToDeploy(cps, moduleClassLoader)); promise.complete(new NeonBeeModule(vertx, moduleName, correlationId, pathOfJar, verticleClasses, models, extensionModels)); diff --git a/src/main/java/io/neonbee/internal/handler/HooksHandler.java b/src/main/java/io/neonbee/internal/handler/HooksHandler.java index 91b9f847..205fb9b2 100644 --- a/src/main/java/io/neonbee/internal/handler/HooksHandler.java +++ b/src/main/java/io/neonbee/internal/handler/HooksHandler.java @@ -29,7 +29,7 @@ public static Handler create() { @Override public void handle(RoutingContext routingContext) { - NeonBee neonBee = NeonBee.instance(routingContext.vertx()); + NeonBee neonBee = NeonBee.get(routingContext.vertx()); neonBee.getHookRegistry() .executeHooks(HookType.ONCE_PER_REQUEST, Map.of(ONCE_PER_REQUEST_ROUTING_CONTEXT, routingContext)) .onComplete(asyncResult -> { diff --git a/src/main/java/io/neonbee/internal/handler/InstanceInfoHandler.java b/src/main/java/io/neonbee/internal/handler/InstanceInfoHandler.java index 391c0468..154ea53d 100644 --- a/src/main/java/io/neonbee/internal/handler/InstanceInfoHandler.java +++ b/src/main/java/io/neonbee/internal/handler/InstanceInfoHandler.java @@ -26,7 +26,7 @@ public void handle(RoutingContext routingContext) { } // Sets the NeonBee instance name as default - String instanceName = NeonBee.instance(routingContext.vertx()).getOptions().getInstanceName(); + String instanceName = NeonBee.get(routingContext.vertx()).getOptions().getInstanceName(); if (instanceName != null && !instanceName.isBlank()) { headers.set(X_INSTANCE_INFO_HEADER, instanceName); } diff --git a/src/main/java/io/neonbee/internal/helper/ConfigHelper.java b/src/main/java/io/neonbee/internal/helper/ConfigHelper.java index 83d68009..f0bdfa50 100644 --- a/src/main/java/io/neonbee/internal/helper/ConfigHelper.java +++ b/src/main/java/io/neonbee/internal/helper/ConfigHelper.java @@ -1,9 +1,7 @@ package io.neonbee.internal.helper; import static io.neonbee.internal.helper.FileSystemHelper.readJSON; -import static io.neonbee.internal.helper.FileSystemHelper.readJSONBlocking; import static io.neonbee.internal.helper.FileSystemHelper.readYAML; -import static io.neonbee.internal.helper.FileSystemHelper.readYAMLBlocking; import static io.vertx.core.Future.failedFuture; import static io.vertx.core.Future.succeededFuture; @@ -15,7 +13,6 @@ import io.neonbee.NeonBee; import io.vertx.core.Future; import io.vertx.core.Vertx; -import io.vertx.core.file.FileSystemException; import io.vertx.core.json.JsonObject; public final class ConfigHelper { @@ -36,7 +33,7 @@ private ConfigHelper() {} * @return a future to a JsonObject or a failed future in case reading failed or the config file was not found */ public static Future readConfig(Vertx vertx, String identifier) { - Path configDirPath = NeonBee.instance(vertx).getOptions().getConfigDirectory(); + Path configDirPath = NeonBee.get(vertx).getOptions().getConfigDirectory(); return readYAML(vertx, configDirPath.resolve(identifier + ".yaml")) .recover(notFound(() -> readYAML(vertx, configDirPath.resolve(identifier + ".yml")))) @@ -59,42 +56,6 @@ public static Future readConfig(Vertx vertx, String identifier, Json return readConfig(vertx, identifier).recover(notFound(() -> succeededFuture(fallback))); } - /** - * Will be deleted in an upcoming commit, therefore no javadoc. TODO - * - * @param vertx vertx - * @param identifier identifier - * @return config - */ - public static JsonObject readConfigBlocking(Vertx vertx, String identifier) { - Path configDirPath = NeonBee.instance(vertx).getOptions().getConfigDirectory(); - try { - return readYAMLBlocking(vertx, configDirPath.resolve(identifier + ".yaml").toAbsolutePath().toString()); - } catch (FileSystemException e) { - if (e.getCause() instanceof NoSuchFileException) { - return readJSONBlocking(vertx, configDirPath.resolve(identifier + ".json").toAbsolutePath().toString()); - } else { - throw e; - } - } - } - - /** - * Will be deleted in an upcoming commit, therefore no javadoc. TODO - * - * @param vertx vertx - * @param identifier identifier - * @param fallback fallback - * @return config - */ - public static JsonObject readConfigBlocking(Vertx vertx, String identifier, JsonObject fallback) { - try { - return readConfigBlocking(vertx, identifier); - } catch (FileSystemException e) { - return fallback; - } - } - private static Function> notFound(Supplier> whenNotFound) { return throwable -> throwable.getCause() instanceof NoSuchFileException ? whenNotFound.get() : failedFuture(throwable); diff --git a/src/main/java/io/neonbee/internal/helper/FileSystemHelper.java b/src/main/java/io/neonbee/internal/helper/FileSystemHelper.java index 63308d50..691063b6 100644 --- a/src/main/java/io/neonbee/internal/helper/FileSystemHelper.java +++ b/src/main/java/io/neonbee/internal/helper/FileSystemHelper.java @@ -1,6 +1,5 @@ package io.neonbee.internal.helper; -import java.io.IOException; import java.nio.file.Path; import java.util.List; import java.util.stream.Collectors; @@ -177,41 +176,4 @@ public static Future createDirs(Vertx vertx, Path path) { public static Future getProperties(Vertx vertx, Path path) { return Future.future(promise -> vertx.fileSystem().props(path.toString(), promise)); } - - /** - * Will be deleted in an upcoming commit, therefore no javadoc. TODO - * - * @param vertx vertx - * @param path path - * @return json - */ - public static JsonObject readJSONBlocking(Vertx vertx, String path) { - return vertx.fileSystem().readFileBlocking(path).toJsonObject(); - } - - /** - * Will be deleted in an upcoming commit, therefore no javadoc. TODO - * - * @param buffer buffer - * @return json - */ - public static JsonObject parseYAMLBlocking(Buffer buffer) { - try { - JsonNode node = YAML_MAPPER.readTree(buffer.getBytes()); - return new JsonObject(node.toString()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - /** - * Will be deleted in an upcoming commit, therefore no javadoc. TODO - * - * @param vertx vertx - * @param path path - * @return json - */ - public static JsonObject readYAMLBlocking(Vertx vertx, String path) { - return parseYAMLBlocking(vertx.fileSystem().readFileBlocking(path)); - } } diff --git a/src/main/java/io/neonbee/internal/verticle/ServerVerticle.java b/src/main/java/io/neonbee/internal/verticle/ServerVerticle.java index 1a25b2da..149550c2 100644 --- a/src/main/java/io/neonbee/internal/verticle/ServerVerticle.java +++ b/src/main/java/io/neonbee/internal/verticle/ServerVerticle.java @@ -202,7 +202,7 @@ public void start(Promise startPromise) { endpointConfig) -> PrometheusScrapingHandler.create(endpointConfig.getString("registryName"))); router.route().handler(NotFoundHandler.create()); - NeonBeeOptions options = NeonBee.instance(vertx).getOptions(); + NeonBeeOptions options = NeonBee.get(vertx).getOptions(); int port = Optional.ofNullable(options.getServerVerticlePort()) .orElse(config.getInteger(CONFIG_PROPERTY_PORT_KEY, DEFAULT_PORT)); diff --git a/src/main/java/io/neonbee/job/JobVerticle.java b/src/main/java/io/neonbee/job/JobVerticle.java index ad42dcae..91da8bdc 100644 --- a/src/main/java/io/neonbee/job/JobVerticle.java +++ b/src/main/java/io/neonbee/job/JobVerticle.java @@ -73,7 +73,7 @@ public String getName() { @Override public void start() { - if (!NeonBee.instance(getVertx()).getOptions().shouldDisableJobScheduling()) { + if (!NeonBee.get(getVertx()).getOptions().shouldDisableJobScheduling()) { scheduleJob(); } else { finalizeJob(); diff --git a/src/test/java/io/neonbee/NeonBeeExtension.java b/src/test/java/io/neonbee/NeonBeeExtension.java index ef09ba1f..7d1b135f 100644 --- a/src/test/java/io/neonbee/NeonBeeExtension.java +++ b/src/test/java/io/neonbee/NeonBeeExtension.java @@ -247,7 +247,7 @@ private NeonBee createNeonBee(NeonBeeOptions neonBeeOptions) { CountDownLatch latch = new CountDownLatch(1); AtomicReference neonBeeHolder = new AtomicReference<>(); LOGGER.info("Before NeonBee init."); - NeonBee.instance(neonBeeOptions, ar -> { + NeonBee.create(neonBeeOptions).onComplete(ar -> { LOGGER.info("NeonBee AsyncResult Handler. {}", ar.succeeded()); if (ar.succeeded()) { neonBeeHolder.set(ar.result()); diff --git a/src/test/java/io/neonbee/NeonBeeTest.java b/src/test/java/io/neonbee/NeonBeeTest.java index c31e2b2c..928ea11b 100644 --- a/src/test/java/io/neonbee/NeonBeeTest.java +++ b/src/test/java/io/neonbee/NeonBeeTest.java @@ -55,7 +55,7 @@ protected WorkingDirectoryBuilder provideWorkingDirectoryBuilder(TestInfo testIn @DisplayName("NeonBee should start with default options / default working directory") void testStart(Vertx vertx) { assertThat(getNeonBee()).isNotNull(); - assertThat(NeonBee.instance(vertx)).isNotNull(); + assertThat(NeonBee.get(vertx)).isNotNull(); } @Test @@ -78,7 +78,7 @@ void testStartWithEmptyWorkingDirectory() { @Timeout(value = 2, timeUnit = TimeUnit.SECONDS) @DisplayName("Vert.x should start in non-clustered mode. ") void testStandaloneInitialization(VertxTestContext testContext) { - NeonBee.initVertx(new NeonBeeOptions.Mutable()).onComplete(testContext.succeeding(vertx -> { + NeonBee.newVertx(new NeonBeeOptions.Mutable()).onComplete(testContext.succeeding(vertx -> { assertThat(vertx.isClustered()).isFalse(); testContext.completeNow(); })); @@ -88,7 +88,7 @@ void testStandaloneInitialization(VertxTestContext testContext) { @Timeout(value = 10, timeUnit = TimeUnit.SECONDS) @DisplayName("Vert.x should start in clustered mode.") void testClusterInitialization(VertxTestContext testContext) { - NeonBee.initVertx( + NeonBee.newVertx( new NeonBeeOptions.Mutable().setClustered(true).setClusterConfigResource("hazelcast-local.xml")) .onComplete(testContext.succeeding(vertx -> { assertThat(vertx.isClustered()).isTrue(); @@ -120,7 +120,7 @@ void testDecorateEventbus() throws Exception { when(eventBus.addOutboundInterceptor(Mockito.any(Handler.class))).thenReturn(eventBus); ArgumentCaptor>> inboundHandlerCaptor = ArgumentCaptor.forClass(Handler.class); ArgumentCaptor>> outboundHandlerCaptor = ArgumentCaptor.forClass(Handler.class); - NeonBee.decorateEventBus(neonBee); + neonBee.decorateEventBus(); verify(eventBus).addInboundInterceptor(inboundHandlerCaptor.capture()); verify(eventBus).addOutboundInterceptor(outboundHandlerCaptor.capture()); TrackingInterceptor inboundHandler = (TrackingInterceptor) inboundHandlerCaptor.getValue(); @@ -133,20 +133,14 @@ void testDecorateEventbus() throws Exception { @Test void testFilterByProfile() { - assertThat(NeonBee.filterByAutoDeployAndProfiles(CoreVerticle.class, List.of(CORE))).isTrue(); - assertThat(NeonBee.filterByAutoDeployAndProfiles(CoreVerticle.class, List.of(CORE, STABLE))) - .isTrue(); - assertThat(NeonBee.filterByAutoDeployAndProfiles(CoreVerticle.class, List.of(STABLE))) - .isFalse(); - assertThat(NeonBee.filterByAutoDeployAndProfiles(StableVerticle.class, List.of(STABLE))) - .isTrue(); - assertThat(NeonBee.filterByAutoDeployAndProfiles(StableVerticle.class, List.of(STABLE, CORE))) - .isTrue(); - assertThat(NeonBee.filterByAutoDeployAndProfiles(IncubatorVerticle.class, List.of(INCUBATOR))) - .isTrue(); - assertThat(NeonBee.filterByAutoDeployAndProfiles(SystemVerticle.class, List.of(CORE))) - .isFalse(); - assertThat(NeonBee.filterByAutoDeployAndProfiles(SystemVerticle.class, List.of(ALL))).isFalse(); + assertThat(NeonBee.filterByAutoDeployAndProfiles(CoreVerticle.class, List.of(CORE))).isTrue(); + assertThat(NeonBee.filterByAutoDeployAndProfiles(CoreVerticle.class, List.of(CORE, STABLE))).isTrue(); + assertThat(NeonBee.filterByAutoDeployAndProfiles(CoreVerticle.class, List.of(STABLE))).isFalse(); + assertThat(NeonBee.filterByAutoDeployAndProfiles(StableVerticle.class, List.of(STABLE))).isTrue(); + assertThat(NeonBee.filterByAutoDeployAndProfiles(StableVerticle.class, List.of(STABLE, CORE))).isTrue(); + assertThat(NeonBee.filterByAutoDeployAndProfiles(IncubatorVerticle.class, List.of(INCUBATOR))).isTrue(); + assertThat(NeonBee.filterByAutoDeployAndProfiles(SystemVerticle.class, List.of(CORE))).isFalse(); + assertThat(NeonBee.filterByAutoDeployAndProfiles(SystemVerticle.class, List.of(ALL))).isFalse(); } @NeonBeeDeployable(profile = CORE) diff --git a/src/test/java/io/neonbee/internal/handler/InstanceInfoHandlerTest.java b/src/test/java/io/neonbee/internal/handler/InstanceInfoHandlerTest.java index e0c3c798..3769e6a0 100644 --- a/src/test/java/io/neonbee/internal/handler/InstanceInfoHandlerTest.java +++ b/src/test/java/io/neonbee/internal/handler/InstanceInfoHandlerTest.java @@ -27,7 +27,7 @@ void testXInstanceName(Vertx vertx) { // We expect that the configured instance name (NeonBeeOptions), is added to the response header by the // InstanceInfoHandler assertThat(response.getHeader(X_INSTANCE_INFO_HEADER)) - .isEqualTo(NeonBee.instance(vertx).getOptions().getInstanceName()); + .isEqualTo(NeonBee.get(vertx).getOptions().getInstanceName()); } }); } diff --git a/src/test/java/io/neonbee/internal/verticle/ReadmeVerticlesTest.java b/src/test/java/io/neonbee/internal/verticle/ReadmeVerticlesTest.java index 70c9bb82..8198a0c9 100644 --- a/src/test/java/io/neonbee/internal/verticle/ReadmeVerticlesTest.java +++ b/src/test/java/io/neonbee/internal/verticle/ReadmeVerticlesTest.java @@ -112,7 +112,7 @@ public void loggingExample() { @SuppressWarnings("unused") public void neonbeeExamples() { - NeonBee neonbee = NeonBee.instance(vertx); + NeonBee neonbee = NeonBee.get(vertx); neonbee.getOptions(); diff --git a/src/test/java/io/neonbee/test/base/NeonBeeTestBase.java b/src/test/java/io/neonbee/test/base/NeonBeeTestBase.java index a96b3a9c..516aac64 100644 --- a/src/test/java/io/neonbee/test/base/NeonBeeTestBase.java +++ b/src/test/java/io/neonbee/test/base/NeonBeeTestBase.java @@ -1,6 +1,5 @@ package io.neonbee.test.base; -import static io.neonbee.internal.helper.ConfigHelper.readConfigBlocking; import static io.neonbee.internal.verticle.ServerVerticle.CONFIG_PROPERTY_PORT_KEY; import static io.vertx.core.Future.failedFuture; import static io.vertx.core.Future.succeededFuture; @@ -41,7 +40,6 @@ import io.vertx.core.DeploymentOptions; import io.vertx.core.Future; import io.vertx.core.Handler; -import io.vertx.core.Promise; import io.vertx.core.Verticle; import io.vertx.core.Vertx; import io.vertx.core.buffer.Buffer; @@ -68,6 +66,7 @@ public class NeonBeeTestBase { private boolean isDummyServerVerticleDeployed; @BeforeEach + @SuppressWarnings("unchecked") public void setUp(TestInfo testInfo, Vertx vertx, VertxTestContext testContext) throws Exception { // Build working directory workingDirPath = FileSystemHelper.createTempDirectory(); @@ -80,15 +79,15 @@ public void setUp(TestInfo testInfo, Vertx vertx, VertxTestContext testContext) } // make required NeonBee method accessible, because TestBase is not in same package - Promise startPromise = Promise.promise(); - Method m = NeonBee.class.getDeclaredMethod("instance", Supplier.class, NeonBeeOptions.class, Handler.class); + Method m = NeonBee.class.getDeclaredMethod("create", Supplier.class, NeonBeeOptions.class); m.setAccessible(true); - m.invoke(null, (Supplier>) () -> succeededFuture(vertx), opts, startPromise); + Future future = + (Future) m.invoke(null, (Supplier>) () -> succeededFuture(vertx), opts); // For some reason the BeforeEach method in the subclass is called before testContext of this class // is completed. Therefore this CountDownLatch is needed. CountDownLatch latch = new CountDownLatch(1); - startPromise.future().onComplete(asyncNeonBee -> { + future.onComplete(asyncNeonBee -> { if (asyncNeonBee.failed()) { testContext.failNow(asyncNeonBee.cause()); latch.countDown(); @@ -239,9 +238,8 @@ public Future undeployVerticles(Class verticleClass) { * @return a pre-configured HTTP request which points to the NeonBee HTTP interface. */ public HttpRequest createRequest(HttpMethod method, String path) { - DeploymentOptions deploymentOptions = - new DeploymentOptions(readConfigBlocking(getNeonBee().getVertx(), ServerVerticle.class.getName())); - int port = deploymentOptions.getConfig().getInteger(CONFIG_PROPERTY_PORT_KEY, -1); + int port = WorkingDirectoryBuilder.readDeploymentOptions(ServerVerticle.class, workingDirPath).getConfig() + .getInteger(CONFIG_PROPERTY_PORT_KEY, -1); WebClientOptions opts = new WebClientOptions().setDefaultHost("localhost").setDefaultPort(port); HttpRequest request = WebClient.create(getNeonBee().getVertx(), opts).request(method, path);