com.clustercontrol.util.EndpointUnit.java Source code

Java tutorial

Introduction

Here is the source code for com.clustercontrol.util.EndpointUnit.java

Source

/**********************************************************************
 * Copyright (C) 2014 NTT DATA Corporation
 * This program is free software; you can redistribute it and/or
 * Modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, version 2.
 *
 * This program is distributed in the hope that it will be
 * useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *********************************************************************/

package com.clustercontrol.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Service;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.soap.SOAPBinding;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.clustercontrol.accesscontrol.dialog.LoginAccount;
import com.clustercontrol.accesscontrol.util.AccessEndpointWrapper;
import com.clustercontrol.fault.InvalidTimezone;
import com.clustercontrol.ws.access.HinemosUnknown_Exception;
import com.clustercontrol.ws.access.InvalidRole_Exception;
import com.clustercontrol.ws.access.InvalidUserPass_Exception;
import com.sun.xml.internal.ws.client.BindingProviderProperties;
import com.sun.xml.internal.ws.developer.JAXWSProperties;

/**
 * Hinemos????
 * HA???????????
 *
 * Hinemos??????????WebServiceException?throw?
 * WebServiceExeption????????????
 */
public class EndpointUnit {

    // 
    private static Log m_log = LogFactory.getLog(EndpointUnit.class);

    private String urlListStr;
    private List<String> urlList;
    private String userId;
    private String password;
    private String managerName;
    private int status = LoginAccount.STATUS_UNCONNECTED;

    private List<String> priorUrlList = null;

    private ConcurrentHashMap<String, Object> endpointMap = new ConcurrentHashMap<String, Object>();

    static {
        // HTTPS????????????
        // ?????Boolean.valueOf??true?????False?????
        // ???????
        boolean doHostVerify = Boolean.valueOf(System.getProperty("https.hostVerify", "false"));

        if (doHostVerify == false) {
            // HostNameVerifier???????????
            // SocketFactory????????????????
            try {
                HostnameVerifier hv = new HostnameVerifier() {
                    public boolean verify(String urlHostName, javax.net.ssl.SSLSession session) {
                        return true;
                    }
                };

                // Create the trust manager.
                javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
                class AllTrustManager implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager {
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

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

                    public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
                            throws java.security.cert.CertificateException {
                        return;
                    }
                }
                javax.net.ssl.TrustManager tm = new AllTrustManager();
                trustAllCerts[0] = tm;
                // Create the SSL context
                javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL");
                // Create the session context
                javax.net.ssl.SSLSessionContext sslsc = sc.getServerSessionContext();
                // Initialize the contexts; the session context takes the
                // trust manager.
                sslsc.setSessionTimeout(0);
                sc.init(null, trustAllCerts, null);
                // Use the default socket factory to create the socket for
                // the secure
                // connection
                javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
                // Set the default host name verifier to enable the connection.
                HttpsURLConnection.setDefaultHostnameVerifier(hv);
                m_log.info("EndpointUnit.static : setup hostverifier completed.");
            } catch (Exception e) {
                m_log.error("EndpointUnit.static : host authentication setup failed.", e);
            }
        }
    }

    public void set(String urlListStr, String userId, String password, String managerName) {
        List<String> urlList = new ArrayList<String>();
        for (String urlStr : urlListStr.split(",")) {
            String url = urlStr.trim();
            urlList.add(url);
        }

        this.urlListStr = urlListStr;
        this.urlList = Collections.unmodifiableList(urlList);
        this.userId = userId;
        this.password = password;
        this.managerName = managerName;

        try {
            PriorUrlListLock.writeLock();

            priorUrlList = new ArrayList<String>(urlList);
        } finally {
            PriorUrlListLock.writeUnlock();
        }

    }

    public void changeEndpoint() {
        if (urlList.size() > 1) {
            try {
                PriorUrlListLock.writeLock();

                String lastPriorUrl = priorUrlList.remove(0);
                priorUrlList.add(lastPriorUrl);
            } finally {
                PriorUrlListLock.writeUnlock();
            }
        }
    }

    private static class PriorUrlListLock {
        private static final ReentrantReadWriteLock _lock = new ReentrantReadWriteLock();

        public static void readLock() {
            _lock.readLock().lock();
        }

        public static void readUnlock() {
            _lock.readLock().unlock();
        }

        public static void writeLock() {
            _lock.writeLock().lock();
        }

        public static void writeUnlock() {
            _lock.writeLock().unlock();
        }
    }

    private void setBindingProvider(Object o, String url) {
        BindingProvider bp = (BindingProvider) o;
        bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url);
        bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, userId);
        bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);
        bp.getRequestContext().put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 8192);

        // Maximum time between establishing a connection and receiving data from the connection (ms)
        int httpRequestTimeout = EndpointManager.getHttpRequestTimeout();
        bp.getRequestContext().put(BindingProviderProperties.REQUEST_TIMEOUT, httpRequestTimeout);
        if (m_log.isTraceEnabled()) {
            m_log.trace("ws timeout updated : requestTimeout = " + httpRequestTimeout + "");
        }

        ((SOAPBinding) bp.getBinding()).setMTOMEnabled(true);
    }

    public class EndpointSetting<T> {
        public final EndpointKey<T> _key;

        public static final String _wsdlSuffix = "?wsdl";

        private EndpointSetting(Class<? extends Service> endpintServiceClass, Class<T> endpointClass,
                String urlPrefix) {
            _key = new EndpointKey<T>(endpintServiceClass, endpointClass, urlPrefix);
        }

        @SuppressWarnings("unchecked")
        public T getEndpoint() {
            try {
                T endpoint = null;

                if (!Service.class.isAssignableFrom(_key._endpointServiceClass)) {
                    return null;
                }

                WebServiceClient wsc = _key._endpointServiceClass.getAnnotation(WebServiceClient.class);
                WebEndpoint we = null;
                for (Method method : _key._endpointServiceClass.getMethods()) {
                    if ((we = method.getAnnotation(WebEndpoint.class)) != null) {
                        break;
                    }
                }

                if (we == null)
                    throw new InternalError("we is null.");

                String urlStr = _key._urlPrefix + wsc.name() + _wsdlSuffix;

                if (endpointMap.containsKey(urlStr)) {
                    endpoint = (T) endpointMap.get(urlStr);
                } else {
                    Class<?>[] types = { URL.class };
                    Constructor<? extends Service> constructor = _key._endpointServiceClass.getConstructor(types);
                    Service service = constructor.newInstance(new URL(urlStr));
                    endpoint = service.getPort(new QName(wsc.targetNamespace(), we.name()), _key._endpointClass);
                    endpointMap.put(urlStr, endpoint);
                }
                setBindingProvider(endpoint, urlStr);

                return endpoint;
            } catch (InvocationTargetException e) {
                m_log.warn("failed creating endpoint. " + e.getMessage() + " (" + e.getClass().getName() + ")");
                throw new WebServiceException(e.getTargetException().getMessage(), e);
            } catch (Exception e) {
                m_log.warn("failed creating endpoint.", e);
                throw new WebServiceException(e.getMessage(), e);
            }
        }
    }

    private class EndpointKey<T> {
        public final Class<? extends Service> _endpointServiceClass;
        public final Class<T> _endpointClass;
        public final String _urlPrefix;

        private EndpointKey(Class<? extends Service> endpointServiceClass, Class<T> endpointClass,
                String urlPrefix) {
            this._endpointServiceClass = endpointServiceClass;
            this._endpointClass = endpointClass;
            this._urlPrefix = urlPrefix;
        };

        @Override
        public int hashCode() {
            int h = 1;
            h = h * 31 + (_endpointServiceClass == null ? 0 : _endpointServiceClass.hashCode());
            h = h * 31 + (_endpointClass == null ? 0 : _endpointClass.hashCode());
            h = h * 31 + (_urlPrefix == null ? 0 : _urlPrefix.hashCode());
            return h;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }

            if (obj instanceof EndpointKey<?>) {
                EndpointKey<?> cast = (EndpointKey<?>) obj;
                if (_endpointServiceClass != null && _endpointServiceClass.equals(cast._endpointServiceClass)) {
                    if (_endpointClass != null && _endpointClass.equals(cast._endpointClass)) {
                        if (_urlPrefix != null && _urlPrefix.equals(cast._urlPrefix)) {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        @Override
        public String toString() {
            return String.format("%s : _endpointServiceClass = %s, _endpointClass = %s, _urlStr = %s",
                    EndpointKey.class.getSimpleName(), _endpointServiceClass.getSimpleName(),
                    _endpointClass.getSimpleName(), _urlPrefix);
        }
    }

    /**
     *  ???Service??EndpointSetting?
     * @param <T>
     * @return
     */
    public <T> List<EndpointSetting<T>> getEndpoint(Class<? extends Service> endpointServiceClass,
            Class<T> endpointClass) {
        try {
            PriorUrlListLock.readLock();

            List<EndpointSetting<T>> list = new ArrayList<EndpointSetting<T>>(priorUrlList.size());
            for (String url : priorUrlList) {
                list.add(new EndpointSetting<T>(endpointServiceClass, endpointClass, url));
            }
            return Collections.unmodifiableList(list);
        } finally {
            PriorUrlListLock.readUnlock();
        }
    }

    public boolean isActive() {
        return LoginAccount.STATUS_CONNECTED == status;
    }

    public int getStatus() {
        return status;
    }

    public void connect()
            throws HinemosUnknown_Exception, InvalidRole_Exception, InvalidUserPass_Exception, InvalidTimezone {
        m_log.debug("connect : " + urlList);

        // Check login result at first
        int managerTZOffset = AccessEndpointWrapper.getWrapper(managerName).checkLogin(this);

        // ??
        Integer clientTZOffset = TimezoneUtil.getTimeZoneOffset();
        m_log.debug("connect : client's timezone = " + clientTZOffset + " , " + managerName + "'s timezone = "
                + managerTZOffset);

        // ???????????????
        // ??
        if (clientTZOffset != null && clientTZOffset != managerTZOffset) {
            m_log.info("connect : " + managerName + "'s timezone(" + managerTZOffset + ") does not match client's("
                    + clientTZOffset + ")");
            throw new InvalidTimezone();
        }

        // ???????????????
        if (clientTZOffset == null) {
            TimezoneUtil.setTimeZoneOffset(managerTZOffset);
        }

        // Add to active manager list after login success(no exception occurred)
        status = LoginAccount.STATUS_CONNECTED;
        return;
    }

    /**
     * 
     */
    public void disconnect() {
        m_log.debug("disconnect : " + urlList);

        status = LoginAccount.STATUS_UNCONNECTED;
    }

    public String getUrlListStr() {
        return urlListStr;
    }

    public List<String> getUrlList() {
        return urlList;
    }

    public String getUserId() {
        return userId;
    }

    public String getPassword() {
        return password;
    }

    public String getManagerName() {
        return managerName;
    }
}