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

com.aliyun.mns.client.impl.AbstractAction 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.client.impl;

import com.aliyun.mns.client.AsyncCallback;
import com.aliyun.mns.client.AsyncResult;
import com.aliyun.mns.common.ClientException;
import com.aliyun.mns.common.HttpMethod;
import com.aliyun.mns.common.MNSConstants;
import com.aliyun.mns.common.ServiceException;
import com.aliyun.mns.common.auth.ServiceCredentials;
import com.aliyun.mns.common.auth.ServiceSignature;
import com.aliyun.mns.common.comm.ExecutionContext;
import com.aliyun.mns.common.http.ExceptionResultParser;
import com.aliyun.mns.common.http.HttpCallback;
import com.aliyun.mns.common.http.RequestMessage;
import com.aliyun.mns.common.http.ServiceClient;
import com.aliyun.mns.common.parser.ResultParser;
import com.aliyun.mns.common.utils.AlibabaCloudCredentialsUtil;
import com.aliyun.mns.common.utils.DateUtil;
import com.aliyun.mns.model.AbstractRequest;
import com.aliyuncs.auth.AlibabaCloudCredentials;
import com.aliyuncs.auth.AlibabaCloudCredentialsProvider;
import java.net.URI;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.UUID;
import java.util.concurrent.Future;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class AbstractAction implements
    Action {

    public static final Logger logger = LoggerFactory.getLogger(AbstractAction.class);
    protected String actionName = "";
    private ServiceClient client;
    private ServiceCredentials credentials;
    private HttpMethod method;
    private URI endpoint;
    private String userRequestId = null;

    public AbstractAction(HttpMethod method, String actionName,
        ServiceClient client, ServiceCredentials credentials, URI endpoint) {
        this.method = method;
        this.actionName = actionName;
        this.client = client;
        this.endpoint = endpoint;
        this.credentials = credentials;

        if (this.client.getClientConfiguration().isGenerateRequestId()) {
            userRequestId = UUID.randomUUID().toString();
        }
    }

    private static TreeMap sortHeader(
        Map headers) {
        TreeMap tmpHeaders = new TreeMap();
        Set keySet = headers.keySet();
        for (String key : keySet) {
            if (key.toLowerCase().startsWith(MNSConstants.X_HEADER_MNS_PREFIX)) {
                tmpHeaders.put(key.toLowerCase(), headers.get(key));
            } else {
                tmpHeaders.put(key, headers.get(key));
            }
        }
        return tmpHeaders;
    }

    private static String safeGetHeader(String key, Map headers) {
        if (headers == null) {
            return "";
        }
        String value = headers.get(key);
        if (value == null) {
            return "";
        }
        return value;
    }

    @Override
    public String getActionName() {
        return actionName;
    }

    @Override
    public ServiceClient getClient() {
        return client;
    }

    @Override
    public ServiceCredentials getCredentials() {
        return credentials;
    }

    @Override
    public HttpMethod getMethod() {
        return method;
    }

    public URI getEndpoint() {
        return this.endpoint;
    }

    @Override
    public AsyncResult execute(T reqObject, AsyncCallback asyncHandler)
        throws ClientException, ServiceException {
        return this.executeWithCustomHeaders(reqObject, asyncHandler, null);
    }

    public AsyncResult executeWithCustomHeaders(T reqObject, AsyncCallback asyncHandler,
        Map customHeaders)
        throws ClientException, ServiceException {
        RequestMessage request = buildRequestMessage(reqObject);
        request.setMethod(this.getMethod());
        this.addRequiredHeader(request);
        this.addCustomHeader(request, customHeaders);
        this.addSignatureHeader(request);

        HttpCallback callback = new HttpCallback(
            this.buildResultParser(), this.buildExceptionParser(), asyncHandler, userRequestId);
        AsyncResult asyncResult = callback.getAsyncResult();
        asyncResult.setTimewait(this.client.getClientConfiguration().getSocketTimeout());
        Future future = client.sendRequest(request, new ExecutionContext(), callback);
        asyncResult.setFuture(future);
        return asyncResult;
    }

    @Override
    public V execute(T reqObject) throws ClientException, ServiceException {
        return this.executeWithCustomHeaders(reqObject, null);
    }

    public V executeWithCustomHeaders(T reqObject, Map customHeaders)
        throws ClientException, ServiceException {
        AsyncResult result = executeWithCustomHeaders(reqObject, null, customHeaders);
        V value = result.getResult();
        if (result.isSuccess()) {
            return value;
        }

        if (result.getException() instanceof ClientException) {
            throw (ClientException) result.getException();
        } else if (result.getException() instanceof ServiceException) {
            throw (ServiceException) result.getException();
        } else {
            ClientException ce = new ClientException(result.getException().toString(),
                userRequestId, result.getException());
            ce.setStackTrace(result.getException().getStackTrace());
            throw ce;
        }
    }

    private void addCustomHeader(RequestMessage request, Map customHeaders) {
        if (customHeaders == null || customHeaders.size() == 0) {
            return;
        }
        for (String key : customHeaders.keySet()) {
            request.getHeaders().put(key, customHeaders.get(key));
        }
    }

    protected void addRequiredHeader(RequestMessage request) {
        request.getHeaders().put(MNSConstants.X_HEADER_MNS_API_VERSION,
            MNSConstants.X_HEADER_MNS_API_VERSION_VALUE);

        if (request.getHeaders().get(MNSConstants.DATE) == null) {
            request.getHeaders().put(MNSConstants.DATE,
                DateUtil.formatRfc822Date(new Date()));
        }

        if (request.getHeaders().get(MNSConstants.CONTENT_TYPE) == null) {
            request.getHeaders().put(MNSConstants.CONTENT_TYPE,
                MNSConstants.DEFAULT_CONTENT_TYPE);
        }

        if (userRequestId != null) {
            request.getHeaders().put(MNSConstants.MNS_USER_REQUEST_ID,
                userRequestId);
        }
    }

    protected void addSignatureHeader(RequestMessage request)
        throws ClientException {
        if (credentials == null) {
            return;
        }
        AlibabaCloudCredentialsProvider provider = credentials.getCredentialsProvider();

        if ((credentials.getAccessKeyId() == null || credentials.getAccessKeySecret() == null) && provider == null) {
            return;
        }
        // ak/sk 模式 和 credentials 模式
        boolean akSkMode = (credentials.getAccessKeyId() != null && credentials.getAccessKeySecret() != null);
        boolean alibabaCredentialsMode = (provider != null);

        // init ak/sk/token
        String accessKeyId = null;
        String accessKeySecret = null;
        String securityToken = null;

        if (akSkMode) {
            accessKeyId = credentials.getAccessKeyId();
            accessKeySecret = credentials.getAccessKeySecret();
            securityToken = credentials.getSecurityToken();
        } else if (alibabaCredentialsMode) {
            AlibabaCloudCredentials alibabaCloudCredentials = getAlibabaCloudCredentials(provider);
            if (alibabaCloudCredentials != null) {
                accessKeyId = alibabaCloudCredentials.getAccessKeyId();
                accessKeySecret = alibabaCloudCredentials.getAccessKeySecret();
                securityToken = AlibabaCloudCredentialsUtil.getSecurityToken(alibabaCloudCredentials);
            }
        }

        // Add signature
        request.addHeader(MNSConstants.AUTHORIZATION,
            "MNS " + accessKeyId + ":" + getSignature(request, accessKeySecret)
        );
        // add security_token if security token is not empty.
        if (StringUtils.isNotBlank(securityToken)) {
            request.addHeader(MNSConstants.SECURITY_TOKEN, securityToken);
        }
    }

    private AlibabaCloudCredentials getAlibabaCloudCredentials(AlibabaCloudCredentialsProvider provider) {
        if (provider == null) {
            return null;
        }

        try {
            return provider.getCredentials();
        } catch (Exception e) {
            logger.error("get credentials failed,e:" + e.getMessage(), e);
        }
        return null;
    }

    private String getRelativeResourcePath(String subPath) {
        String rootPath = endpoint.getPath();
        if (subPath != null && !"".equals(subPath.trim())) {
            if (subPath.startsWith("/")) {
                subPath = subPath.substring(1);
            }
            if (!rootPath.endsWith("/")) {
                return rootPath + "/" + subPath;
            }
            return rootPath + subPath;
        }
        return rootPath;
    }

    private String getSignature(RequestMessage request, String accessKeySecret) throws ClientException {
        if (StringUtils.isBlank(accessKeySecret)) {
            return null;
        }

        Map headers = request.getHeaders();

        StringBuffer canonicalizedMNSHeaders = new StringBuffer();
        StringBuffer stringToSign = new StringBuffer();
        String contentMd5 = safeGetHeader(MNSConstants.CONTENT_MD5, headers);
        String contentType = safeGetHeader(MNSConstants.CONTENT_TYPE, headers);
        String date = safeGetHeader(MNSConstants.DATE, headers);
        String canonicalizedResource = getRelativeResourcePath(request
            .getResourcePath());

        TreeMap tmpHeaders = sortHeader(request.getHeaders());
        if (tmpHeaders.size() > 0) {
            Set keySet = tmpHeaders.keySet();
            for (String key : keySet) {
                if (key.toLowerCase().startsWith(
                    MNSConstants.X_HEADER_MNS_PREFIX)) {
                    canonicalizedMNSHeaders.append(key).append(":")
                        .append(tmpHeaders.get(key)).append("\n");
                }
            }
        }
        stringToSign.append(method).append("\n").append(contentMd5)
            .append("\n").append(contentType).append("\n").append(date)
            .append("\n").append(canonicalizedMNSHeaders)
            .append(canonicalizedResource);
        String signature;

        try {
            signature = ServiceSignature.create().computeSignature(
                accessKeySecret, stringToSign.toString());
        } catch (Exception e) {
            throw new ClientException("Signature fail", userRequestId, e);
        }

        return signature;
    }

    protected RequestMessage buildRequestMessage(T reqObject)
        throws ClientException {
        RequestMessage request = buildRequest(reqObject);
        String requestPath = request.getResourcePath();
        if (requestPath != null && (requestPath.startsWith("http://") || requestPath.startsWith("https://"))) {
            if (!requestPath.startsWith(endpoint.toString())) {
                throw new IllegalArgumentException("Endpoint["
                    + endpoint.toString() + "]和访问地址[" + requestPath
                    + "]不匹配.");
            } else {
                requestPath = requestPath.substring(endpoint.toString().length());
                if (requestPath.startsWith("/")) {
                    requestPath = requestPath.substring(1);
                }
                request.setResourcePath(requestPath);
            }
        }
        request.setEndpoint(endpoint);

        return request;
    }

    public String getUserRequestId() {
        return userRequestId;
    }

    protected ResultParser buildResultParser() {
        return null;
    }

    protected ResultParser buildExceptionParser() {
        return new ExceptionResultParser(userRequestId);
    }

    protected abstract RequestMessage buildRequest(T reqObject)
        throws ClientException;
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy