mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Yannick Lecaillez
05.51.2016 5487deb6febc8f8432d82fbecfdea369110d0bab
OPENDJ-3204: Unable to stop Rest2Ldap Gateway container.

HttClientHandler were not closed during HttpApplicationStop.
ScheduledThreadPoolExecutor was kept alive because of eviction cache
task.
The fix allows Closeable resources to be registered in a list which will
be closed when the HttpApplication is stopped.
1 files modified
38 ■■■■ changed files
opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LdapHttpApplication.java 38 ●●●● patch | view | raw | blame | history
opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LdapHttpApplication.java
@@ -38,18 +38,20 @@
import static org.forgerock.util.Utils.closeSilently;
import static org.forgerock.util.Utils.joinAsString;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import javax.net.ssl.KeyManager;
import javax.net.ssl.TrustManager;
@@ -121,6 +123,9 @@
    /** Used for token caching. */
    private ScheduledExecutorService executorService;
    /** Resources which have to be closed when this application is stopped. */
    private final Collection<Closeable> closeableResources = new ArrayList<>();
    private TrustManager trustManager;
    private X509KeyManager keyManager;
@@ -193,7 +198,16 @@
        try {
            logger.info(INFO_REST2LDAP_STARTING.get(configDirectory));
            executorService = Executors.newSingleThreadScheduledExecutor();
            final ScheduledThreadPoolExecutor scheduledExecutor = new ScheduledThreadPoolExecutor(1);
            scheduledExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
            scheduledExecutor.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
            closeOnStop(new Closeable() {
                @Override
                public void close() throws IOException {
                    scheduledExecutor.shutdown();
                }
            });
            executorService = scheduledExecutor;
            final JsonValue config = readJson(new File(configDirectory, "config.json"));
            configureSecurity(config.get("security"));
@@ -225,10 +239,16 @@
    private void configureConnectionFactories(final JsonValue config) {
        connectionFactories.clear();
        for (String name : config.keys()) {
            connectionFactories.put(name, configureConnectionFactory(config, name, trustManager, keyManager));
            connectionFactories
                .put(name, closeOnStop(configureConnectionFactory(config, name, trustManager, keyManager)));
        }
    }
    private <T extends Closeable> T closeOnStop(T resource) {
        closeableResources.add(resource);
        return resource;
    }
    @Override
    public Factory<Buffer> getBufferFactory() {
        // Use container default buffer factory.
@@ -237,14 +257,10 @@
    @Override
    public void stop() {
        for (ConnectionFactory factory : connectionFactories.values()) {
            closeSilently(factory);
        }
        closeSilently(closeableResources);
        closeableResources.clear();
        connectionFactories.clear();
        if (executorService != null) {
            executorService.shutdown();
            executorService = null;
        }
        executorService = null;
    }
    private Filter buildAuthorizationFilter(final JsonValue config) throws HttpApplicationException {
@@ -342,7 +358,7 @@
            httpOptions.set(OPTION_KEY_MANAGERS,
                    new KeyManager[] { keyAlias != null ? useSingleCertificate(keyAlias, keyManager) : keyManager });
        }
        return new HttpClientHandler(httpOptions);
        return closeOnStop(new HttpClientHandler(httpOptions));
    }
    private Duration parseCacheExpiration(final JsonValue expirationJson) {