feat(gateway-vertx) Async initialisation features for better startup and error handling.
ADD
gateway/platforms/vertx3/vertx3-common/src/main/java/io/apiman/gateway/platforms/vertx3/common/AsyncInitialize.java
+/*
+ * Copyright 2017 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.apiman.gateway.platforms.vertx3.common;
+
+import io.apiman.gateway.engine.async.IAsyncResultHandler;
+
+/**
+* @author Marc Savy {@literal <marc@rhymewithgravy.com>}
+*/
+public interface AsyncInitialize {
+
+ /**
+ * Initialise something, and indicate when it's completed via resultHandler.
+ * @param resultHandler called when initialisation is complete, or with an error.
+ */
+ void initialize(IAsyncResultHandler<Void> resultHandler);
+}

MODIFY
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/engine/VertxConfigDrivenEngineFactory.java
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/engine/VertxConfigDrivenEngineFactory.java
@@ -19,7 +19,11 @@ import io.apiman.gateway.engine.IComponentRegistry;
import io.apiman.gateway.engine.IConnectorFactory;
import io.apiman.gateway.engine.IEngineConfig;
import io.apiman.gateway.engine.IPluginRegistry;
+import io.apiman.gateway.engine.async.AsyncResultImpl;
+import io.apiman.gateway.engine.async.IAsyncResultHandler;
+import io.apiman.gateway.engine.impl.AbstractEngineFactory;
import io.apiman.gateway.engine.impl.ConfigDrivenEngineFactory;
+import io.apiman.gateway.platforms.vertx3.common.AsyncInitialize;
import io.apiman.gateway.platforms.vertx3.common.config.VertxEngineConfig;
import io.apiman.gateway.platforms.vertx3.connector.ConnectorFactory;
import io.vertx.core.Vertx;
@@ -35,9 +39,12 @@ import java.util.Map;
* @author Marc Savy {@literal <msavy@redhat.com>}
*/
public class VertxConfigDrivenEngineFactory extends ConfigDrivenEngineFactory {
-
private Vertx vertx;
private VertxEngineConfig vxConfig;
+ private IAsyncResultHandler<Void> handler;
+ private int started = 0;
+ private static final int ELEMENTS_TO_START = 6;
+
public VertxConfigDrivenEngineFactory(Vertx vertx, VertxEngineConfig config) {
super(config);
@@ -56,8 +63,24 @@ public class VertxConfigDrivenEngineFactory extends ConfigDrivenEngineFactory {
}
@Override
- @SuppressWarnings("nls")
protected <T> T create(Class<T> type, Map<String, String> mapConfig) {
+ started +=1;
+ T instance = getInstance(type, mapConfig);
+ if (instance instanceof AsyncInitialize) {
+ ((AsyncInitialize) instance).initialize(initResult -> {
+ if (initResult.isError()) {
+ handler.handle(initResult);
+ }
+ });
+ }
+ if (started == ELEMENTS_TO_START) {
+ handler.handle(AsyncResultImpl.create((Void) null));
+ }
+ return instance;
+ }
+
+ @SuppressWarnings("nls")
+ private <T> T getInstance(Class<T> type, Map<String, String> mapConfig) {
try {
Constructor<T> constructor = type.getConstructor(Vertx.class, VertxEngineConfig.class, Map.class);
return constructor.newInstance(vertx, vxConfig, mapConfig);
@@ -85,4 +108,9 @@ public class VertxConfigDrivenEngineFactory extends ConfigDrivenEngineFactory {
e.getMessage()), e);
}
}
+
+ public AbstractEngineFactory setHandler(IAsyncResultHandler<Void> handler) {
+ this.handler = handler;
+ return this;
+ }
}

MODIFY
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/verticles/ApiVerticle.java
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/verticles/ApiVerticle.java
@@ -45,8 +45,8 @@ public class ApiVerticle extends ApimanVerticleWithEngine {
public static final VerticleType VERTICLE_TYPE = VerticleType.API;
@Override
- public void start() {
- super.start();
+ public void start(Future<Void> startFuture) {
+ super.start(startFuture);
IRouteBuilder clientResource = new ClientResourceImpl(apimanConfig, engine);
IRouteBuilder apiResource = new ApiResourceImpl(apimanConfig, engine);
IRouteBuilder systemResource = new SystemResourceImpl(apimanConfig, engine);

MODIFY
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/verticles/ApimanVerticleBase.java
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/verticles/ApimanVerticleBase.java
*/
package io.apiman.gateway.platforms.vertx3.verticles;
-import java.util.UUID;
-
import io.apiman.common.util.SimpleStringUtils;
import io.apiman.gateway.platforms.vertx3.common.config.VertxEngineConfig;
import io.apiman.gateway.platforms.vertx3.common.verticles.VerticleType;
import io.apiman.gateway.platforms.vertx3.i18n.Messages;
import io.vertx.core.AbstractVerticle;
+import io.vertx.core.Future;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;
+
+import java.util.UUID;
/**
* Standard base for all apiman verticles.
*
@@ -37,7 +38,7 @@ public abstract class ApimanVerticleBase extends AbstractVerticle {
protected Logger log = LoggerFactory.getLogger(this.getClass());
@Override
- public void start() {
+ public void start(Future<Void> startFuture) {
apimanConfig = getEngineConfig();
log.info(Messages.getString("ApimanVerticleBase.starting_verticle") + this.getClass().getName() + "\n" +

MODIFY
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/verticles/ApimanVerticleWithEngine.java
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/verticles/ApimanVerticleWithEngine.java
@@ -17,6 +17,7 @@ package io.apiman.gateway.platforms.vertx3.verticles;
import io.apiman.gateway.engine.IEngine;
import io.apiman.gateway.platforms.vertx3.engine.VertxConfigDrivenEngineFactory;
+import io.vertx.core.Future;
/**
* A base for those verticles that require an instantiated engine.
@@ -26,16 +27,20 @@ import io.apiman.gateway.platforms.vertx3.engine.VertxConfigDrivenEngineFactory;
public abstract class ApimanVerticleWithEngine extends ApimanVerticleBase {
protected IEngine engine;
- //protected ApiListener apiListener;
@Override
- public void start() {
- super.start();
-
- engine = new VertxConfigDrivenEngineFactory(vertx, getEngineConfig()).createEngine();
+ public void start(Future<Void> startFuture) {
+ super.start(startFuture);
+ engine = new VertxConfigDrivenEngineFactory(vertx, getEngineConfig())
+ .setHandler(result -> {
+ if (result.isSuccess()) {
+ startFuture.complete();
+ } else {
+ startFuture.fail(result.getError());
+ }
+ })
+ .createEngine();
engine.getRegistry(); // this should help avoid slow first-time loads.
- //apiListener = new ApiListener(eb, uuid);
- //apiListener.listen(engine);
}
protected IEngine engine() {

MODIFY
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/verticles/HttpGatewayVerticle.java
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/verticles/HttpGatewayVerticle.java
@@ -17,6 +17,7 @@ package io.apiman.gateway.platforms.vertx3.verticles;
import io.apiman.gateway.platforms.vertx3.common.verticles.VerticleType;
import io.apiman.gateway.platforms.vertx3.http.HttpPolicyAdapter;
+import io.vertx.core.Future;
import io.vertx.core.http.HttpServerOptions;
import io.vertx.core.http.HttpServerRequest;
@@ -29,8 +30,8 @@ public class HttpGatewayVerticle extends ApimanVerticleWithEngine {
static final VerticleType VERTICLE_TYPE = VerticleType.HTTP;
@Override
- public void start() {
- super.start();
+ public void start(Future<Void> startFuture) {
+ super.start(startFuture);
HttpServerOptions standardOptions = new HttpServerOptions()
.setHost(apimanConfig.getHostname());

MODIFY
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/verticles/HttpsGatewayVerticle.java
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/verticles/HttpsGatewayVerticle.java
@@ -17,6 +17,7 @@ package io.apiman.gateway.platforms.vertx3.verticles;
import io.apiman.gateway.platforms.vertx3.common.verticles.VerticleType;
import io.apiman.gateway.platforms.vertx3.http.HttpPolicyAdapter;
+import io.vertx.core.Future;
import io.vertx.core.http.HttpServerOptions;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.net.JksOptions;
@@ -30,8 +31,8 @@ public class HttpsGatewayVerticle extends ApimanVerticleWithEngine {
static final VerticleType VERTICLE_TYPE = VerticleType.HTTPS;
@Override
- public void start() {
- super.start();
+ public void start(Future<Void> startFuture) {
+ super.start(startFuture);
HttpServerOptions sslOptions = new HttpServerOptions()
.setHost(apimanConfig.getHostname())

MODIFY
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/verticles/InitVerticle.java
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/verticles/InitVerticle.java
@@ -36,7 +36,7 @@ public class InitVerticle extends ApimanVerticleBase {
@Override
public void start(Future<Void> start) {
- super.start();
+ super.start(start);
base = new DeploymentOptions().setConfig(config());
@SuppressWarnings({ "rawtypes" }) // CompositeFuture doesn't accept generic type

feat(gateway-vertx) Async initialisation features for better startup and error handling.