All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.jersey.client.ClientExecutorProvidersConfigurator Maven / Gradle / Ivy

Go to download

A bundle project producing JAX-RS RI bundles. The primary artifact is an "all-in-one" OSGi-fied JAX-RS RI bundle (jaxrs-ri.jar). Attached to that are two compressed JAX-RS RI archives. The first archive (jaxrs-ri.zip) consists of binary RI bits and contains the API jar (under "api" directory), RI libraries (under "lib" directory) as well as all external RI dependencies (under "ext" directory). The secondary archive (jaxrs-ri-src.zip) contains buildable JAX-RS RI source bundle and contains the API jar (under "api" directory), RI sources (under "src" directory) as well as all external RI dependencies (under "ext" directory). The second archive also contains "build.xml" ANT script that builds the RI sources. To build the JAX-RS RI simply unzip the archive, cd to the created jaxrs-ri directory and invoke "ant" from the command line.

There is a newer version: 3.1.9
Show newest version
/*
 * Copyright (c) 2017, 2024 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package org.glassfish.jersey.client;

import java.lang.reflect.Method;
import java.security.AccessController;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.glassfish.jersey.internal.BootstrapBag;
import org.glassfish.jersey.internal.inject.Bindings;
import org.glassfish.jersey.internal.inject.InjectionManager;
import org.glassfish.jersey.internal.inject.InstanceBinding;
import org.glassfish.jersey.internal.util.ReflectionHelper;
import org.glassfish.jersey.internal.util.collection.Value;
import org.glassfish.jersey.internal.util.collection.Values;
import org.glassfish.jersey.model.internal.ComponentBag;
import org.glassfish.jersey.process.internal.AbstractExecutorProvidersConfigurator;
import org.glassfish.jersey.spi.ExecutorServiceProvider;
import org.glassfish.jersey.spi.ScheduledExecutorServiceProvider;

import jakarta.ws.rs.core.Configuration;

/**
 * Configurator which initializes and register {@link ExecutorServiceProvider} and
 * {@link ScheduledExecutorServiceProvider}.
 *
 * @author Petr Bouda
 */
class ClientExecutorProvidersConfigurator extends AbstractExecutorProvidersConfigurator {

    private static final Logger LOGGER = Logger.getLogger(ClientExecutorProvidersConfigurator.class.getName());
    private static final ExecutorService MANAGED_EXECUTOR_SERVICE = lookupManagedExecutorService();

    private final ComponentBag componentBag;
    private final JerseyClient client;
    private final ExecutorService customExecutorService;
    private final ScheduledExecutorService customScheduledExecutorService;

    ClientExecutorProvidersConfigurator(ComponentBag componentBag, JerseyClient client,
                                        ExecutorService customExecutorService,
                                        ScheduledExecutorService customScheduledExecutorService) {
        this.componentBag = componentBag;
        this.client = client;
        this.customExecutorService = customExecutorService;
        this.customScheduledExecutorService = customScheduledExecutorService;
    }

    @Override
    public void init(InjectionManager injectionManager, BootstrapBag bootstrapBag) {
        final Configuration configuration = bootstrapBag.getConfiguration();
        Map runtimeProperties = configuration.getProperties();

        ExecutorServiceProvider defaultAsyncExecutorProvider;
        ScheduledExecutorServiceProvider defaultScheduledExecutorProvider;

        final ExecutorService clientExecutorService = client.getExecutorService() == null
                // custom executor service can be also set via managed client config class, in that case, it ends up in the
                // customExecutorService field (similar for scheduled version)
                ? customExecutorService
                : client.getExecutorService();

        // if there is a users provided executor service, use it
        if (clientExecutorService != null) {
            defaultAsyncExecutorProvider = new ClientExecutorServiceProvider(clientExecutorService);
            // otherwise, check for ClientProperties.ASYNC_THREADPOOL_SIZE - if that is set, Jersey will create the
            // ExecutorService to be used. If not and running on Java EE container, ManagedExecutorService will be used.
            // Final fallback is DefaultClientAsyncExecutorProvider with defined default.
        } else {
            // Default async request executors support
            Integer asyncThreadPoolSize = ClientProperties
                    .getValue(runtimeProperties, ClientProperties.ASYNC_THREADPOOL_SIZE, Integer.class);

            if (asyncThreadPoolSize != null) {
                // TODO: Do we need to register DEFAULT Executor and ScheduledExecutor to InjectionManager?
                asyncThreadPoolSize = (asyncThreadPoolSize < 0) ? 0 : asyncThreadPoolSize;
                InstanceBinding asyncThreadPoolSizeBinding = Bindings
                        .service(asyncThreadPoolSize)
                        .named("ClientAsyncThreadPoolSize");
                injectionManager.register(asyncThreadPoolSizeBinding);

                defaultAsyncExecutorProvider = new DefaultClientAsyncExecutorProvider(asyncThreadPoolSize, configuration);
            } else {
                if (MANAGED_EXECUTOR_SERVICE != null) {
                    defaultAsyncExecutorProvider = new ClientExecutorServiceProvider(MANAGED_EXECUTOR_SERVICE);
                } else {
                    defaultAsyncExecutorProvider = new DefaultClientAsyncExecutorProvider(0, configuration);
                }
            }
        }

        InstanceBinding executorBinding = Bindings
                .service(defaultAsyncExecutorProvider)
                .to(ExecutorServiceProvider.class);

        injectionManager.register(executorBinding);

        final ScheduledExecutorService clientScheduledExecutorService = client.getScheduledExecutorService() == null
                // scheduled executor service set from {@link ClientConfig}.
                ? customScheduledExecutorService
                : client.getScheduledExecutorService();

        if (clientScheduledExecutorService != null) {
            defaultScheduledExecutorProvider =
                    new ClientScheduledExecutorServiceProvider(Values.of(clientScheduledExecutorService));
        } else {
            ScheduledExecutorService scheduledExecutorService = lookupManagedScheduledExecutorService();
            defaultScheduledExecutorProvider =
                scheduledExecutorService == null
                        // default client background scheduler disposes the executor service when client is closed.
                        // we don't need to do that for user provided (via ClientBuilder) or managed executor service.
                        ? new DefaultClientBackgroundSchedulerProvider()
                        : new ClientScheduledExecutorServiceProvider(Values.of(scheduledExecutorService));
        }

        InstanceBinding schedulerBinding = Bindings
                .service(defaultScheduledExecutorProvider)
                .to(ScheduledExecutorServiceProvider.class);
        injectionManager.register(schedulerBinding);

        registerExecutors(injectionManager, componentBag, defaultAsyncExecutorProvider,
                defaultScheduledExecutorProvider, bootstrapBag.getManagedObjectsFinalizer());
    }

    private static ExecutorService lookupManagedExecutorService() {
        // Get the default ManagedExecutorService, if available
        try {
            // Android and some other environments don't have InitialContext class available.
            final Class aClass =
                    AccessController.doPrivileged(ReflectionHelper.classForNamePA("javax.naming.InitialContext"));

            final Object initialContext = aClass.newInstance();

            final Method lookupMethod = aClass.getMethod("lookup", String.class);
            return (ExecutorService) lookupMethod.invoke(initialContext, "java:comp/DefaultManagedExecutorService");
        } catch (Exception e) {
            // ignore
            if (LOGGER.isLoggable(Level.FINE)) {
                LOGGER.log(Level.FINE, e.getMessage(), e);
            }
        } catch (LinkageError error) {
            // ignore - JDK8 compact2 profile - http://openjdk.java.net/jeps/161
        }

        return null;
    }

    private ScheduledExecutorService lookupManagedScheduledExecutorService() {
        try {
            // Android and some other environments don't have InitialContext class available.
            final Class aClass =
                    AccessController.doPrivileged(ReflectionHelper.classForNamePA("javax.naming.InitialContext"));
            final Object initialContext = aClass.newInstance();

            final Method lookupMethod = aClass.getMethod("lookup", String.class);
            return (ScheduledExecutorService) lookupMethod
                    .invoke(initialContext, "java:comp/DefaultManagedScheduledExecutorService");
        } catch (Exception e) {
            // ignore
            if (LOGGER.isLoggable(Level.FINE)) {
                LOGGER.log(Level.FINE, e.getMessage(), e);
            }
        } catch (LinkageError error) {
            // ignore - JDK8 compact2 profile - http://openjdk.java.net/jeps/161
        }

        return null;
    }

    @ClientAsyncExecutor
    public static class ClientExecutorServiceProvider implements ExecutorServiceProvider {

        private final ExecutorService executorService;

        ClientExecutorServiceProvider(ExecutorService executorService) {
            this.executorService = executorService;
        }

        @Override
        public ExecutorService getExecutorService() {
            return executorService;
        }

        @Override
        public void dispose(ExecutorService executorService) {

        }
    }

    @ClientBackgroundScheduler
    public static class ClientScheduledExecutorServiceProvider implements ScheduledExecutorServiceProvider {

        private final Value executorService;

        ClientScheduledExecutorServiceProvider(Value executorService) {
            this.executorService = executorService;
        }

        @Override
        public ScheduledExecutorService getExecutorService() {
            return executorService.get();
        }

        @Override
        public void dispose(ExecutorService executorService) {

        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy