com.liferay.portal.util.LicenseUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.liferay.portal.util.LicenseUtil.java

Source

/**
 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library 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 Lesser General Public License for more
 * details.
 */

package com.liferay.portal.util;

import com.liferay.petra.string.CharPool;
import com.liferay.petra.string.StringBundler;
import com.liferay.petra.string.StringPool;
import com.liferay.portal.json.JSONObjectImpl;
import com.liferay.portal.kernel.cluster.ClusterExecutorUtil;
import com.liferay.portal.kernel.cluster.ClusterNode;
import com.liferay.portal.kernel.cluster.ClusterNodeResponse;
import com.liferay.portal.kernel.cluster.ClusterNodeResponses;
import com.liferay.portal.kernel.cluster.ClusterRequest;
import com.liferay.portal.kernel.cluster.FutureClusterResponses;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.license.util.LicenseManagerUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.Constants;
import com.liferay.portal.kernel.util.ContentTypes;
import com.liferay.portal.kernel.util.FileUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.HashMapBuilder;
import com.liferay.portal.kernel.util.Http;
import com.liferay.portal.kernel.util.MethodHandler;
import com.liferay.portal.kernel.util.MethodKey;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.PortalUtil;
import com.liferay.portal.kernel.util.PropsUtil;
import com.liferay.portal.kernel.util.ReleaseInfo;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;

import java.io.File;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URI;

import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;

/**
 * @author Amos Fong
 */
public class LicenseUtil {

    public static final String LICENSE_REPOSITORY_DIR = PropsValues.LIFERAY_HOME.concat("/data/license");

    public static final String LICENSE_SERVER_URL = GetterUtil.get(PropsUtil.get("license.server.url"),
            "https://www.liferay.com");

    public static Map<String, String> getClusterServerInfo(String clusterNodeId) throws Exception {

        ClusterNode localClusterNode = ClusterExecutorUtil.getLocalClusterNode();

        String localClusterNodeId = localClusterNode.getClusterNodeId();

        if (clusterNodeId.equals(localClusterNodeId)) {
            return getServerInfo();
        }

        List<ClusterNode> clusterNodes = ClusterExecutorUtil.getClusterNodes();

        ClusterNode clusterNode = null;

        for (ClusterNode curClusterNode : clusterNodes) {
            String curClusterNodeId = curClusterNode.getClusterNodeId();

            if (curClusterNodeId.equals(clusterNodeId)) {
                clusterNode = curClusterNode;

                break;
            }
        }

        if (clusterNode == null) {
            return null;
        }

        try {
            ClusterRequest clusterRequest = ClusterRequest.createUnicastRequest(_getServerInfoMethodHandler,
                    clusterNodeId);

            FutureClusterResponses futureClusterResponses = ClusterExecutorUtil.execute(clusterRequest);

            ClusterNodeResponses clusterNodeResponses = futureClusterResponses.get(20000, TimeUnit.MILLISECONDS);

            ClusterNodeResponse clusterNodeResponse = clusterNodeResponses
                    .getClusterResponse(clusterNode.getClusterNodeId());

            return (Map<String, String>) clusterNodeResponse.getResult();
        } catch (Exception e) {
            _log.error(e, e);

            throw e;
        }
    }

    public static Set<String> getIpAddresses() {
        return _ipAddresses;
    }

    public static Set<String> getMacAddresses() {
        return _macAddresses;
    }

    public static int getProcessorCores() {
        Runtime runtime = Runtime.getRuntime();

        return runtime.availableProcessors();
    }

    public static byte[] getServerIdBytes() throws Exception {
        if (_serverIdBytes != null) {
            return _serverIdBytes;
        }

        File serverIdFile = new File(LICENSE_REPOSITORY_DIR + "/server/serverId");

        if (!serverIdFile.exists()) {
            return new byte[0];
        }

        _serverIdBytes = FileUtil.getBytes(serverIdFile);

        return _serverIdBytes;
    }

    public static Map<String, String> getServerInfo() {
        return HashMapBuilder.put("hostName", PortalUtil.getComputerName())
                .put("ipAddresses", StringUtil.merge(getIpAddresses()))
                .put("macAddresses", StringUtil.merge(getMacAddresses()))
                .put("processorCores", String.valueOf(getProcessorCores())).build();
    }

    /**
     * @deprecated As of Judson (7.1.x), with no direct replacement
     */
    @Deprecated
    public static void init() {
    }

    public static void registerOrder(HttpServletRequest httpServletRequest) {
        String orderUuid = ParamUtil.getString(httpServletRequest, "orderUuid");
        String productEntryName = ParamUtil.getString(httpServletRequest, "productEntryName");
        int maxServers = ParamUtil.getInteger(httpServletRequest, "maxServers");

        List<ClusterNode> clusterNodes = ClusterExecutorUtil.getClusterNodes();

        if ((clusterNodes == null) || (clusterNodes.size() <= 1) || Validator.isNull(productEntryName)
                || Validator.isNull(orderUuid)) {

            Map<String, Object> attributes = registerOrder(orderUuid, productEntryName, maxServers);

            for (Map.Entry<String, Object> entry : attributes.entrySet()) {
                httpServletRequest.setAttribute(entry.getKey(), entry.getValue());
            }
        } else {
            for (ClusterNode clusterNode : clusterNodes) {
                boolean register = ParamUtil.getBoolean(httpServletRequest,
                        clusterNode.getClusterNodeId() + "_register");

                if (!register) {
                    continue;
                }

                try {
                    _registerClusterOrder(httpServletRequest, clusterNode, orderUuid, productEntryName, maxServers);
                } catch (Exception e) {
                    _log.error(e, e);

                    InetAddress inetAddress = clusterNode.getBindInetAddress();

                    String message = "Error contacting " + inetAddress.getHostName();

                    if (clusterNode.getPortalPort() != -1) {
                        message += StringPool.COLON + clusterNode.getPortalPort();
                    }

                    httpServletRequest.setAttribute(clusterNode.getClusterNodeId() + "_ERROR_MESSAGE", message);
                }
            }
        }
    }

    public static Map<String, Object> registerOrder(String orderUuid, String productEntryName, int maxServers) {

        Map<String, Object> attributes = new HashMap<>();

        if (Validator.isNull(orderUuid)) {
            return attributes;
        }

        try {
            JSONObject jsonObject = _createRequest(orderUuid, productEntryName, maxServers);

            String response = sendRequest(jsonObject.toString());

            JSONObject responseJSONObject = new JSONObjectImpl(response);

            attributes.put("ORDER_PRODUCT_ID", responseJSONObject.getString("productId"));
            attributes.put("ORDER_PRODUCTS", _getOrderProducts(responseJSONObject));

            String errorMessage = responseJSONObject.getString("errorMessage");

            if (Validator.isNotNull(errorMessage)) {
                attributes.put("ERROR_MESSAGE", errorMessage);

                return attributes;
            }

            String licenseXML = responseJSONObject.getString("licenseXML");

            if (Validator.isNotNull(licenseXML)) {
                LicenseManagerUtil.registerLicense(responseJSONObject);

                attributes.clear();
                attributes.put("SUCCESS_MESSAGE", "Your license has been successfully registered.");
            }
        } catch (Exception e) {
            _log.error(e, e);

            attributes.put("ERROR_MESSAGE", "There was an error contacting " + LICENSE_SERVER_URL);
        }

        return attributes;
    }

    public static String sendRequest(String request) throws Exception {
        HttpClient httpClient = null;

        HttpClientConnectionManager httpClientConnectionManager = new BasicHttpClientConnectionManager(
                RegistryBuilder.<ConnectionSocketFactory>create()
                        .register(Http.HTTP, PlainConnectionSocketFactory.getSocketFactory())
                        .register(Http.HTTPS, SSLConnectionSocketFactory.getSystemSocketFactory()).build());

        try {
            HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();

            httpClientBuilder.setConnectionManager(httpClientConnectionManager);

            String serverURL = LICENSE_SERVER_URL;

            if (!serverURL.endsWith(StringPool.SLASH)) {
                serverURL += StringPool.SLASH;
            }

            serverURL += "osb-portlet/license";

            URI uri = new URI(serverURL);

            HttpPost httpPost = new HttpPost(uri);

            CredentialsProvider credentialsProvider = new BasicCredentialsProvider();

            HttpHost proxyHttpHost = null;

            if (Validator.isNotNull(_PROXY_URL)) {
                if (_log.isInfoEnabled()) {
                    _log.info(StringBundler.concat("Using proxy ", _PROXY_URL, StringPool.COLON, _PROXY_PORT));
                }

                proxyHttpHost = new HttpHost(_PROXY_URL, _PROXY_PORT);

                if (Validator.isNotNull(_PROXY_USER_NAME)) {
                    credentialsProvider.setCredentials(new AuthScope(_PROXY_URL, _PROXY_PORT),
                            new UsernamePasswordCredentials(_PROXY_USER_NAME, _PROXY_PASSWORD));
                }
            }

            httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
            httpClientBuilder.setProxy(proxyHttpHost);

            httpClient = httpClientBuilder.build();

            ByteArrayEntity byteArrayEntity = new ByteArrayEntity(request.getBytes(StringPool.UTF8));

            byteArrayEntity.setContentType(ContentTypes.APPLICATION_JSON);

            httpPost.setEntity(byteArrayEntity);

            HttpResponse httpResponse = httpClient.execute(httpPost);

            HttpEntity httpEntity = httpResponse.getEntity();

            String response = StringUtil.read(httpEntity.getContent());

            if (_log.isDebugEnabled()) {
                _log.debug("Server response: " + response);
            }

            if (Validator.isNull(response)) {
                throw new Exception("Server response is null");
            }

            return response;
        } finally {
            if (httpClient != null) {
                httpClientConnectionManager.shutdown();
            }
        }
    }

    public static void writeServerProperties(byte[] serverIdBytes) throws Exception {

        File serverIdFile = new File(LICENSE_REPOSITORY_DIR + "/server/serverId");

        FileUtil.write(serverIdFile, serverIdBytes);
    }

    private static JSONObject _createRequest(String orderUuid, String productEntryName, int maxServers)
            throws Exception {

        JSONObject jsonObject = new JSONObjectImpl();

        jsonObject.put("liferayVersion", ReleaseInfo.getBuildNumber()).put("orderUuid", orderUuid).put("version",
                2);

        if (Validator.isNull(productEntryName)) {
            jsonObject.put(Constants.CMD, "QUERY");
        } else {
            jsonObject.put(Constants.CMD, "REGISTER");

            if (productEntryName.startsWith("basic")) {
                jsonObject.put("productEntryName", "basic");

                if (productEntryName.equals("basic-cluster")) {
                    jsonObject.put("cluster", true).put("maxServers", maxServers);
                } else if (productEntryName.startsWith("basic-")) {
                    String[] productNameArray = StringUtil.split(productEntryName, StringPool.DASH);

                    if (productNameArray.length >= 3) {
                        jsonObject.put("clusterId", productNameArray[2]).put("offeringEntryId",
                                productNameArray[1]);
                    }
                }
            } else {
                jsonObject.put("productEntryName", productEntryName);
            }

            jsonObject.put("hostName", PortalUtil.getComputerName())
                    .put("ipAddresses", StringUtil.merge(getIpAddresses()))
                    .put("macAddresses", StringUtil.merge(getMacAddresses()))
                    .put("processorCores", getProcessorCores())
                    .put("serverId", Arrays.toString(getServerIdBytes()));
        }

        return jsonObject;
    }

    private static Map<String, String> _getOrderProducts(JSONObject jsonObject) {

        JSONObject productsJSONObject = jsonObject.getJSONObject("productsJSONObject");

        if (productsJSONObject == null) {
            return null;
        }

        Map<String, String> sortedMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);

        Iterator<String> itr = productsJSONObject.keys();

        while (itr.hasNext()) {
            String key = itr.next();

            sortedMap.put(key, productsJSONObject.getString(key));
        }

        return sortedMap;
    }

    private static void _registerClusterOrder(HttpServletRequest httpServletRequest, ClusterNode clusterNode,
            String orderUuid, String productEntryName, int maxServers) throws Exception {

        MethodHandler methodHandler = new MethodHandler(_registerOrderMethodKey, orderUuid, productEntryName,
                maxServers);

        ClusterRequest clusterRequest = ClusterRequest.createUnicastRequest(methodHandler,
                clusterNode.getClusterNodeId());

        FutureClusterResponses futureClusterResponses = ClusterExecutorUtil.execute(clusterRequest);

        ClusterNodeResponses clusterNodeResponses = futureClusterResponses.get(20000, TimeUnit.MILLISECONDS);

        ClusterNodeResponse clusterNodeResponse = clusterNodeResponses
                .getClusterResponse(clusterNode.getClusterNodeId());

        Map<String, Object> attributes = (Map<String, Object>) clusterNodeResponse.getResult();

        for (Map.Entry<String, Object> entry : attributes.entrySet()) {
            httpServletRequest.setAttribute(clusterNode.getClusterNodeId() + StringPool.UNDERLINE + entry.getKey(),
                    entry.getValue());
        }
    }

    private static final String _PROXY_PASSWORD = GetterUtil.getString(PropsUtil.get("license.proxy.password"));

    private static final int _PROXY_PORT = GetterUtil.getInteger(PropsUtil.get("license.proxy.port"), 80);

    private static final String _PROXY_URL = PropsUtil.get("license.proxy.url");

    private static final String _PROXY_USER_NAME = GetterUtil.getString(PropsUtil.get("license.proxy.username"));

    private static final Log _log = LogFactoryUtil.getLog(LicenseUtil.class);

    private static final MethodHandler _getServerInfoMethodHandler = new MethodHandler(
            new MethodKey(LicenseUtil.class, "getServerInfo"));
    private static final Set<String> _ipAddresses;
    private static final Set<String> _macAddresses;
    private static final MethodKey _registerOrderMethodKey = new MethodKey(LicenseUtil.class, "registerOrder",
            String.class, String.class, int.class);
    private static byte[] _serverIdBytes;

    static {
        Set<String> ipAddresses = new HashSet<>();

        Set<String> macAddresses = new HashSet<>();

        try {
            Enumeration<NetworkInterface> networkInterfaceEnumeration = NetworkInterface.getNetworkInterfaces();

            while (networkInterfaceEnumeration.hasMoreElements()) {
                NetworkInterface networkInterface = networkInterfaceEnumeration.nextElement();

                Enumeration<InetAddress> inetAddressEnumeration = networkInterface.getInetAddresses();

                while (inetAddressEnumeration.hasMoreElements()) {
                    InetAddress inetAddress = inetAddressEnumeration.nextElement();

                    if (inetAddress.isLinkLocalAddress() || inetAddress.isLoopbackAddress()
                            || !(inetAddress instanceof Inet4Address)) {

                        continue;
                    }

                    ipAddresses.add(inetAddress.getHostAddress());
                }

                byte[] hardwareAddress = networkInterface.getHardwareAddress();

                if (ArrayUtil.isEmpty(hardwareAddress)) {
                    continue;
                }

                StringBuilder sb = new StringBuilder((hardwareAddress.length * 3) - 1);

                String hexString = StringUtil.bytesToHexString(hardwareAddress);

                for (int i = 0; i < hexString.length(); i += 2) {
                    if (i != 0) {
                        sb.append(CharPool.COLON);
                    }

                    sb.append(Character.toLowerCase(hexString.charAt(i)));
                    sb.append(Character.toLowerCase(hexString.charAt(i + 1)));
                }

                macAddresses.add(sb.toString());
            }
        } catch (SocketException se) {
            _log.error("Unable to read local server network interfaces", se);
        }

        _ipAddresses = Collections.unmodifiableSet(ipAddresses);

        _macAddresses = Collections.unmodifiableSet(macAddresses);
    }

}