@Override
    protected void downloadArtifactTo(final URL artifactUrl, final File pluginFile,
        final IAsyncResultHandler<File> handler) {

        URI artifactUri;
        try {
            artifactUri = artifactUrl.toURI();
        } catch (URISyntaxException e) {
            throw new IllegalArgumentException(e.getMessage(), e);
        }
        int port = artifactUrl.getPort();
        boolean isTls = false;

        // Configure http client options following artifact url
        if (artifactUrl.getProtocol().equalsIgnoreCase("https")) {
            // If port is not defined, set to https default port 443
            if (port == -1) port = 443;
            isTls = true;
        } else {
            // If port is not defined, set to http default port 80
            if (port == -1) port = 80;
        }

        HttpClientOptions options = createVertxClientOptions(artifactUri, isTls);

        LOG.trace("Will attempt to download artifact {0} using options {1} to {2}",
            artifactUrl, options, pluginFile);

        HttpClient client = vertx.createHttpClient(options);

        CircuitBreaker breaker = CircuitBreaker.create(
            "download-plugin-circuit-breaker", vertx,
            new CircuitBreakerOptions()
                .setMaxFailures(2) // number of failure before opening the circuit
                .setTimeout(20000) // consider a failure if the operation does not succeed in time
                .setResetTimeout(10000) // time spent in open state before attempting to re-try
        )
        .retryPolicy(retryCount -> retryCount * 10L); // Increase backoff on each retry

        int finalPort = port;
        breaker.<File>execute(promise -> {
            LOG.info("Will attempt to download plugin from: {0}", artifactUrl);
            tryDownloadingArtifact(client, finalPort, artifactUrl, pluginFile, promise);
        })
        .onSuccess(file -> {
            LOG.debug("Successfully downloaded plugin artifact: {0}", artifactUrl);
            handler.handle(AsyncResultImpl.create(pluginFile));
        })
        .onFailure(failure -> {
            LOG.error("Failed to downloaded plugin artifact", failure);
            handler.handle(AsyncResultImpl.create(failure));
        });
    }
@see io.apiman.gateway.engine.impl.DefaultPluginRegistry#downloadArtifactTo(java.net.URL, java.io.File,
     io.apiman.gateway.engine.async.IAsyncResultHandler)
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/engine/VertxPluginRegistry.java