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

com.aliyun.mns.common.http.HttpCallback 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.client.AsyncCallback;
import com.aliyun.mns.client.AsyncResult;
import com.aliyun.mns.common.ClientException;
import com.aliyun.mns.common.parser.ResultParser;
import com.aliyun.mns.common.utils.HttpUtil;
import com.aliyun.mns.common.utils.IOUtils;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.concurrent.FutureCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HttpCallback implements FutureCallback {
    private static Logger log = LoggerFactory.getLogger(HttpCallback.class);
    private boolean success = false;
    private Exception exception = null;
    private ResponseMessage responseMessage = null;
    private boolean cancalled = false;
    private ResultParser resultParser;
    private AsyncCallback callback;
    private DefaultAsyncResult result;
    private ResultParser exceptionParser;
    private String userRequestId = null;
    private static ExecutorService executor;

    static {
        executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        ((ThreadPoolExecutor) executor).setKeepAliveTime(30, TimeUnit.SECONDS);
        ((ThreadPoolExecutor) executor).allowCoreThreadTimeOut(true);
    }

    public static void setCallbackExecutor(ExecutorService executor) {
        HttpCallback.executor = executor;
    }

    public HttpCallback(ResultParser resultParser,
        ResultParser exceptionParser,
        AsyncCallback callback,
        String userRequestId) {
        this.resultParser = resultParser;
        this.callback = callback;
        this.exceptionParser = exceptionParser;
        this.result = new DefaultAsyncResult(this);
        this.userRequestId = userRequestId;
    }

    private void executeCallback(final AsyncCallback callback, final T result) {
        executor.submit(new Runnable() {
            @Override
            public void run() {
                callback.onSuccess(result);
            }
        });
    }

    private void executeCallback(final AsyncCallback callback, final Exception ex) {
        executor.submit(new Runnable() {
            @Override
            public void run() {
                callback.onFail(ex);
            }
        });
    }

    @Override
    public void completed(HttpResponse response) {
        try {
            buildResponseMessage(response);
        } catch (Exception ex) {
            log.error(ex.getMessage());
            if (callback != null) {
                executeCallback(callback, ex);
            }
            result.onFail(ex);
            log.error("onFail finish when exception in completed");
        }
    }

    protected void buildResponseMessage(HttpResponse response) {
        // Build result
        responseMessage = new ResponseMessage();
        // message.setUrl(request.getUri());
        if (response.getStatusLine() != null) {
            responseMessage.setStatusCode(response.getStatusLine()
                .getStatusCode());
        }

        if (response.getEntity() != null) {
            try {
                responseMessage.setContent(response.getEntity().getContent());
            } catch (IllegalStateException e) {
                log.error(e.getMessage(), e);
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
        }
        // fill in headers
        Header[] headers = response.getAllHeaders();
        Map resultHeaders = new HashMap();
        for (int i = 0; i < headers.length; i++) {
            Header h = headers[i];
            resultHeaders.put(h.getName(), h.getValue());
        }
        HttpUtil.convertHeaderCharsetFromIso88591(resultHeaders);
        responseMessage.setHeaders(resultHeaders);

        handleResult();
    }

    private void close() {
        if (responseMessage != null) {
            try {
                this.responseMessage.close();
            } catch (IOException e) {
            }
        }

    }

    private void handleResult() {
        try {
            if (responseMessage.isSuccessful()) {
                T obj = null;
                if (resultParser != null) {
                    obj = this.resultParser.parse(responseMessage);
                }
                if (callback != null) {
                    executeCallback(callback, obj);
                }

                result.onSuccess(obj);
                this.success = true;
            } else {
                Exception obj = exceptionParser.parse(responseMessage);
                if (callback != null) {
                    executeCallback(callback, obj);
                }

                result.onFail(obj);

            }
        } catch (Exception ex) {
            try {
                System.out.println(IOUtils.readStreamAsString(responseMessage.getContent(), "UTF-8"));
            } catch (Exception e) {
            }
            if (callback != null) {
                executeCallback(callback, ex);
            }
            result.onFail(ex);
        }

    }

    @Override
    public void failed(Exception ex) {
        this.exception = ex;
        try {
            if (callback != null) {
                executeCallback(callback, ex);
            }
            result.onFail(ex);
        } catch (Exception e) {
            if (callback != null) {
                executeCallback(callback, ex);
            }
            result.onFail(e);
        }
    }

    @Override
    public void cancelled() {
        this.cancalled = true;
        exception = new ClientException("call is cancelled.", userRequestId);
        try {
            if (callback != null) {
                executeCallback(callback, exception);
            }
            result.onFail(exception);
        } catch (Exception e) {
            if (callback != null) {
                executeCallback(callback, e);
            }
            result.onFail(e);
        }
    }

    public String getUserRequestId() {
        return userRequestId;
    }

    public boolean isCancelled() {
        return cancalled;
    }

    public boolean isSuccess() {
        return success;
    }

    public Exception getException() {
        return this.exception;
    }

    public ResponseMessage getResponseMessage() {
        return responseMessage;
    }

    public AsyncResult getAsyncResult() {
        return this.result;
    }

    static class DefaultAsyncResult implements AsyncResult {
        private ReentrantLock rlock = new ReentrantLock();
        private Condition lock = rlock.newCondition();

        private long defaultTimewait;
        private long startTimeMillis;

        private boolean completed = false;
        private T result = null;
        private boolean success;
        private Exception exception;

        private HttpCallback callback;
        private Future future;

        protected DefaultAsyncResult(HttpCallback callback) {
            this.callback = callback;
            this.startTimeMillis = System.currentTimeMillis();
        }

        public void setTimewait(long timewait) {
            defaultTimewait = timewait;
        }

        public void setFuture(Future future) {
            this.future = future;
        }

        /*
         * (non-Javadoc)
         *
         */
        @Override
        public T getResult() {
            T result = getResult(defaultTimewait);
            while (result == null && (this.future != null && !this.future.isDone())) {
                result = getResult(defaultTimewait);
            }
            return result;
        }

        /*
         * (non-Javadoc)
         *
         */
        @Override
        public T getResult(long timewait) {
            if (!completed) {
                rlock.lock();
                try {
                    if (!completed) {
                        boolean signaled = false;
                        if (timewait <= 0) {
                            signaled = lock.await(defaultTimewait, TimeUnit.MILLISECONDS);
                        } else {
                            signaled = lock.await(timewait, TimeUnit.MILLISECONDS);
                        }
                        if (!signaled
                            && (this.future != null && this.future.isDone())
                            && System.currentTimeMillis() >= (startTimeMillis + defaultTimewait)) {
                            this.exception = new ClientException("Client wait result timeout!",
                                this.callback.getUserRequestId());
                            this.success = false;
                            this.completed = true;
                        }
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                } finally {
                    rlock.unlock();
                }
            }
            return result;
        }

        public void onSuccess(T result) {
            rlock.lock();
            try {
                if (completed) {
                    return;
                }
                this.result = result;
                this.success = true;
                this.completed = true;
                lock.signal();
            } finally {
                rlock.unlock();
            }
        }

        public void onFail(Exception ex) {
            rlock.lock();
            try {
                if (completed) {
                    return;
                }
                this.exception = ex;
                this.success = false;
                this.completed = true;
                lock.signal();
            } finally {
                rlock.unlock();
            }
        }

        /*
         * (non-Javadoc)
         *
         * @see om.aliyun.mns.client.impl.AsyncResult#isSuccess()
         */
        @Override
        public boolean isSuccess() {
            return success;
        }

        /*
         * (non-Javadoc)
         *
         */
        @Override
        public Exception getException() {
            return exception;
        }

        //TODO: erase it ?
        public void close() {
            callback.close();
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy