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

com.aliyun.mns.common.http.HttpFactory Maven / Gradle / Ivy

Go to download

Aliyun Message and Notification Service SDK for Java Copyright (C) Alibaba Cloud Computing All rights reserved. 版权所有 (C)阿里云计算有限公司 http://www.aliyun.com

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 com.aliyun.mns.common.http;

import com.aliyun.mns.common.ClientException;
import com.aliyun.mns.common.HttpMethod;
import com.aliyun.mns.common.comm.ExecutionContext;
import com.aliyun.mns.common.comm.RepeatableInputStreamEntity;
import com.aliyun.mns.common.utils.HttpHeaders;
import com.aliyun.mns.common.utils.VersionInfoUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.NTCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpOptions;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
import org.apache.http.impl.nio.reactor.IOReactorConfig;
import org.apache.http.nio.conn.NHttpClientConnectionManager;
import org.apache.http.nio.reactor.IOReactorException;
import org.apache.http.nio.reactor.IOReactorExceptionHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The factory to create HTTP-related objects.
 */
public class HttpFactory {

    public static Logger logger = LoggerFactory.getLogger(HttpFactory.class);

    private static SSLConnectionSocketFactory getSSLSocketFactory() {
        TrustManager[] trustAllCerts = new TrustManager[] {
            new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkClientTrusted(
                    java.security.cert.X509Certificate[] certs, String authType) {
                }

                public void checkServerTrusted(
                    java.security.cert.X509Certificate[] certs, String authType) {
                }
            }};

        try {
            SSLContext sslcontext = SSLContext.getInstance("SSL");
            sslcontext.init(null, trustAllCerts, null);
            SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(
                sslcontext,
                SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            return ssf;

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Create a PoolingNHttpClientConnectionManager instance
     *
     * @param config Client configuration
     * @return manager
     */
    public static PoolingNHttpClientConnectionManager createConnectionManager(ClientConfiguration config) {
        // Set HTTP params.
        // Create I/O reactor configuration
        IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
            .setIoThreadCount(config.getIoReactorThreadCount())
            .setConnectTimeout(config.getConnectionTimeout())
            .setSoTimeout(config.getSocketTimeout())
            .setSoKeepAlive(config.isSoKeepAlive()).build();

        // Create a custom I/O reactort
        DefaultConnectingIOReactor ioReactor;
        try {
            ioReactor = new DefaultConnectingIOReactor(ioReactorConfig);
            ioReactor.setExceptionHandler(new IOReactorExceptionHandler() {
                @Override
                public boolean handle(IOException ex) {
                    logger.error("I/O error", ex);
                    return true;
                }

                @Override
                public boolean handle(RuntimeException ex) {
                    logger.error("I/O runtime error", ex);
                    return true;
                }
            });
        } catch (IOReactorException e) {
            throw new RuntimeException(e);
        }

        PoolingNHttpClientConnectionManager connManager = new PoolingNHttpClientConnectionManager(
            ioReactor);
        connManager.setDefaultMaxPerRoute(config.getMaxConnectionsPerRoute());
        connManager.setMaxTotal(config.getMaxConnections());

        return connManager;
    }

    /**
     * Creates a HttpAsyncClient instance.
     *
     * @param connManager Connection Manager
     * @param config      Client configuration.
     * @return closeable client
     */
    public static CloseableHttpAsyncClient createHttpAsyncClient(
        PoolingNHttpClientConnectionManager connManager,
        ClientConfiguration config) {
        HttpAsyncClientBuilder httpClientBuilder = HttpAsyncClients.custom()
            .setConnectionManager(connManager);

        // Set proxy if set.
        String proxyHost = config.getProxyHost();
        int proxyPort = config.getProxyPort();

        if (proxyHost != null && proxyPort > 0) {
            HttpHost proxy = new HttpHost(proxyHost, proxyPort);

            httpClientBuilder.setProxy(proxy);

            String proxyUsername = config.getProxyUsername();
            String proxyPassword = config.getProxyPassword();

            if (proxyUsername != null && proxyPassword != null) {
                String proxyDomain = config.getProxyDomain();
                String proxyWorkstation = config.getProxyWorkstation();

                CredentialsProvider credentialsProvider = new BasicCredentialsProvider();

                credentialsProvider.setCredentials(new AuthScope(proxy),
                    new NTCredentials(proxyUsername, proxyPassword,
                        proxyWorkstation, proxyDomain)
                );

                httpClientBuilder
                    .setDefaultCredentialsProvider(credentialsProvider);

            }
        }

        RequestConfig defaultRequestConfig = RequestConfig
            .custom()
            .setCookieSpec(CookieSpecs.BEST_MATCH)
            .setExpectContinueEnabled(true)
            .setStaleConnectionCheckEnabled(true)
            .setTargetPreferredAuthSchemes(
                Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST))
            .setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC))
            .setConnectTimeout(config.getConnectionTimeout())
            .setSocketTimeout(config.getSocketTimeout())
            .setExpectContinueEnabled(config.isExceptContinue()).build();

        httpClientBuilder.setDefaultRequestConfig(defaultRequestConfig);
        httpClientBuilder
            .setMaxConnPerRoute(config.getMaxConnectionsPerRoute());
        httpClientBuilder.setMaxConnTotal(config.getMaxConnections());
        httpClientBuilder.setUserAgent(VersionInfoUtils.getDefaultUserAgent());
        CloseableHttpAsyncClient httpclient = httpClientBuilder.build();

        return httpclient;
    }

    /**
     * Creates a HttpRequestBase instance.
     *
     * @param request Request message.
     * @param context Context
     * @return HttpRequestBase instance.
     */
    public static HttpRequestBase createHttpRequest(ServiceClient.Request request,
        ExecutionContext context) {

        String uri = request.getUri();
        HttpMethod method = request.getMethod();
        HttpRequestBase httpRequest;
        if (method == HttpMethod.POST) {
            // POST
            HttpPost postMethod = new HttpPost(uri);

            if (request.getContent() != null) {
                postMethod.setEntity(new RepeatableInputStreamEntity(request));
            }

            httpRequest = postMethod;
        } else if (method == HttpMethod.PUT) {
            // PUT
            HttpPut putMethod = new HttpPut(uri);

            if (request.getContent() != null) {
                putMethod.setEntity(new RepeatableInputStreamEntity(request));
            }

            httpRequest = putMethod;
        } else if (method == HttpMethod.GET) {
            // GET
            httpRequest = new HttpGet(uri);
        } else if (method == HttpMethod.DELETE) {
            // DELETE
            //httpRequest = new HttpDelete(uri);
            // support body in Delete
            MNSHttpDelete deleteMethod = new MNSHttpDelete(uri);
            if (request.getContent() != null) {
                deleteMethod.setEntity(new RepeatableInputStreamEntity(request));
            }
            httpRequest = deleteMethod;
        } else if (method == HttpMethod.HEAD) {
            httpRequest = new HttpHead(uri);
        } else if (method == HttpMethod.OPTIONS) {
            httpRequest = new HttpOptions(uri);
        } else {
            throw new IllegalArgumentException(String.format(
                "Unsupported HTTP method: %s.", request.getMethod()
                    .toString()
            ));
        }

        configureRequestHeaders(request, context, httpRequest);
        // httpRequest.addHeader("User-Agent","aliyun-java-sdk");
        return httpRequest;
    }

    private static void configureRequestHeaders(ServiceClient.Request request,
        ExecutionContext context, HttpRequestBase httpRequest) {
        // Copy headers in the request message to the HTTP request
        for (Entry entry : request.getHeaders().entrySet()) {
            // HttpClient fills in the Content-Length,
            // and complains if add it again, so skip it as well as the Host
            // header.
            if (entry.getKey().equalsIgnoreCase(HttpHeaders.CONTENT_LENGTH)
                || entry.getKey().equalsIgnoreCase(HttpHeaders.HOST)) {
                continue;
            }

            httpRequest.addHeader(entry.getKey(), entry.getValue());
        }

        // Set content type and encoding
        // if (httpRequest.getHeaders(HttpHeaders.CONTENT_TYPE) == null ||
        // httpRequest.getHeaders(HttpHeaders.CONTENT_TYPE).length == 0){
        // httpRequest.addHeader(HttpHeaders.CONTENT_TYPE,
        // "application/x-www-form-urlencoded; " +
        // "charset=" + context.getCharset().toLowerCase());
        // }
    }

    public static class IdleConnectionMonitor extends Thread {
        private static final IdleConnectionMonitor instance = new IdleConnectionMonitor();
        private final List connMgrs = new ArrayList();
        private volatile boolean shutdown = false;

        private int CONNECTION_MANAGER_LIMIT = 50;

        private IdleConnectionMonitor() {
            this.setName("IdleConnectionMonitorThread");
            this.setDaemon(true);
            this.start();
        }

        public static IdleConnectionMonitor getInstance() {
            return instance;
        }

        public void addConnMgr(NHttpClientConnectionManager connMgr) {
            synchronized (connMgrs) {
                if (CONNECTION_MANAGER_LIMIT > 0 && connMgrs.size() > CONNECTION_MANAGER_LIMIT) {
                    throw new ClientException("Too Many ServiceClient created.", null);
                }
                connMgrs.add(connMgr);
            }
        }

        public void removeConnMgr(NHttpClientConnectionManager connMgr) {
            synchronized (connMgrs) {
                connMgrs.remove(connMgr);
            }
        }

        public void set_CONNECTION_MANAGER_LIMIT(int limit) {
            this.CONNECTION_MANAGER_LIMIT = limit;
        }

        @Override
        public void run() {
            try {
                while (!shutdown) {
                    sleep(15000);
                    List tmpConnMgrs;
                    synchronized (connMgrs) {
                        tmpConnMgrs = new ArrayList(connMgrs);
                    }
                    for (NHttpClientConnectionManager connMgr : tmpConnMgrs) {
                        // Close expired connections
                        connMgr.closeExpiredConnections();
                        // Optionally, close connections
                        // that have been idle longer than 30 sec
                        connMgr.closeIdleConnections(30, TimeUnit.SECONDS);
                    }
                }
            } catch (InterruptedException ex) {
                // terminate
            }
        }

        synchronized public void shutdown() {
            shutdown = true;
        }

    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy