org.kaaproject.kaa.client.KaaClientProperties.java Source code

Java tutorial

Introduction

Here is the source code for org.kaaproject.kaa.client.KaaClientProperties.java

Source

/*
 * Copyright 2014-2016 CyberVision, Inc.
 *
 * Licensed 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 org.kaaproject.kaa.client;

import static org.kaaproject.kaa.client.util.Utils.isBlank;

import org.apache.commons.compress.utils.Charsets;
import org.kaaproject.kaa.client.channel.GenericTransportInfo;
import org.kaaproject.kaa.client.channel.ServerType;
import org.kaaproject.kaa.client.channel.TransportConnectionInfo;
import org.kaaproject.kaa.client.channel.TransportProtocolId;
import org.kaaproject.kaa.client.util.Base64;
import org.kaaproject.kaa.common.endpoint.gen.ProtocolMetaData;
import org.kaaproject.kaa.common.endpoint.gen.ProtocolVersionPair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

/**
 * Service class to store base endpoint configuration.
 */
public class KaaClientProperties extends Properties {
    public static final String KAA_CLIENT_PROPERTIES_FILE = "kaaClientPropertiesFile";
    public static final String BUILD_VERSION = "build.version";
    public static final String BUILD_COMMIT_HASH = "build.commit_hash";
    public static final String TRANSPORT_POLL_DELAY = "transport.poll.initial_delay";
    public static final String TRANSPORT_POLL_PERIOD = "transport.poll.period";
    public static final String TRANSPORT_POLL_UNIT = "transport.poll.unit";
    public static final String BOOTSTRAP_SERVERS = "transport.bootstrap.servers";
    public static final String CONFIG_DATA_DEFAULT = "config.data.default";
    public static final String CONFIG_SCHEMA_DEFAULT = "config.schema.default";
    public static final String SDK_TOKEN = "sdk_token";
    public static final String WORKING_DIR_PROPERTY = "kaa.work_dir";
    public static final String FILE_SEPARATOR = File.separator;
    public static final String WORKING_DIR_DEFAULT = "." + FILE_SEPARATOR;
    public static final String STATE_FILE_NAME_DEFAULT = "state.properties";
    public static final String CLIENT_PRIVATE_KEY_NAME_DEFAULT = "key.private";
    public static final String CLIENT_PUBLIC_KEY_NAME_DEFAULT = "key.public";
    public static final String STATE_FILE_NAME_PROPERTY = "state.file_name";
    public static final String CLIENT_PRIVATE_KEY_FILE_NAME_PROPERTY = "keys.private_name";
    public static final String CLIENT_PUBLIC_KEY_FILE_NAME_PROPERTY = "keys.public_name";
    private static final Logger LOG = LoggerFactory.getLogger(KaaClientProperties.class);
    private static final String DEFAULT_CLIENT_PROPERTIES = "client.properties";
    private static final long serialVersionUID = 8793954229852581418L;
    private static final String PROPERTIES_HASH_ALGORITHM = "SHA";

    private Base64 base64;

    private byte[] propertiesHash;

    public KaaClientProperties() throws IOException {
        super(loadProperties(null));
    }

    public KaaClientProperties(String propertiesLocation) throws IOException {
        super(loadProperties(propertiesLocation));
    }

    public KaaClientProperties(Properties properties) {
        super(properties);
    }

    private static Properties loadProperties(String propsLocation) throws IOException {
        Properties properties = null;
        String propertiesLocation = isBlank(propsLocation) ? DEFAULT_CLIENT_PROPERTIES : propsLocation;
        if (System.getProperty(KAA_CLIENT_PROPERTIES_FILE) != null) {
            propertiesLocation = System.getProperty(KAA_CLIENT_PROPERTIES_FILE);
        }
        properties = new Properties();
        ClassLoader classLoader = Kaa.class.getClassLoader();
        properties.load(classLoader.getResourceAsStream(propertiesLocation));
        return properties;
    }

    private static void checkNotBlankProperty(String fileName, String errorMessage) {
        if (isBlank(fileName)) {
            throw new IllegalArgumentException(errorMessage);
        }
    }

    /**
     * Calculates a hash for SDK properties.
     *
     * @return hash for SDK properties
     */
    public byte[] getPropertiesHash() {
        if (propertiesHash == null) {
            try {
                MessageDigest digest = MessageDigest.getInstance(PROPERTIES_HASH_ALGORITHM);

                updateDigest(digest, TRANSPORT_POLL_DELAY);
                updateDigest(digest, TRANSPORT_POLL_PERIOD);
                updateDigest(digest, TRANSPORT_POLL_UNIT);
                updateDigest(digest, BOOTSTRAP_SERVERS);
                updateDigest(digest, CONFIG_DATA_DEFAULT);
                updateDigest(digest, CONFIG_SCHEMA_DEFAULT);
                updateDigest(digest, SDK_TOKEN);

                propertiesHash = digest.digest();
            } catch (NoSuchAlgorithmException ex) {
                LOG.warn("Failed to calculate hash for SDK properties: {}", ex);
            }
        }

        return propertiesHash;
    }

    private void updateDigest(MessageDigest digest, String propertyName) {
        String value = getProperty(propertyName);
        if (value != null) {
            digest.update(value.getBytes());
        }
    }

    public String getBuildVersion() {
        return getProperty(BUILD_VERSION);
    }

    public String getCommitHash() {
        return getProperty(BUILD_COMMIT_HASH);
    }

    public Map<TransportProtocolId, List<TransportConnectionInfo>> getBootstrapServers()
            throws InvalidKeySpecException, NoSuchAlgorithmException {
        return parseBootstrapServers(getProperty(KaaClientProperties.BOOTSTRAP_SERVERS));
    }

    public String getSdkToken() {
        return getProperty(KaaClientProperties.SDK_TOKEN);
    }

    public Integer getPollDelay() {
        return Integer.valueOf(getProperty(KaaClientProperties.TRANSPORT_POLL_DELAY));
    }

    public Integer getPollPeriod() {
        return Integer.valueOf(getProperty(KaaClientProperties.TRANSPORT_POLL_PERIOD));
    }

    public TimeUnit getPollUnit() {
        return TimeUnit.valueOf(getProperty(KaaClientProperties.TRANSPORT_POLL_UNIT));
    }

    private Map<TransportProtocolId, List<TransportConnectionInfo>> parseBootstrapServers(String serversStr)
            throws InvalidKeySpecException, NoSuchAlgorithmException {
        Map<TransportProtocolId, List<TransportConnectionInfo>> servers = new HashMap<>();
        String[] serversSplit = serversStr.split(";");

        for (String server : serversSplit) {
            if (server != null && !server.trim().isEmpty()) {
                String[] tokens = server.split(":");
                ProtocolMetaData md = new ProtocolMetaData();
                md.setAccessPointId(Integer.valueOf(tokens[0]));
                md.setProtocolVersionInfo(
                        new ProtocolVersionPair(Integer.valueOf(tokens[1]), Integer.valueOf(tokens[2])));
                md.setConnectionInfo(ByteBuffer.wrap(getBase64().decodeBase64(tokens[3])));
                TransportProtocolId key = new TransportProtocolId(md.getProtocolVersionInfo().getId(),
                        md.getProtocolVersionInfo().getVersion());
                List<TransportConnectionInfo> serverList = servers.get(key);
                if (serverList == null) {
                    serverList = new ArrayList<TransportConnectionInfo>();
                    servers.put(key, serverList);
                }
                serverList.add(new GenericTransportInfo(ServerType.BOOTSTRAP, md));
            }
        }
        return servers;
    }

    public byte[] getDefaultConfigData() {
        String config = getProperty(KaaClientProperties.CONFIG_DATA_DEFAULT);
        return (config != null) ? getBase64().decodeBase64(config.getBytes(Charsets.UTF_8)) : null;
    }

    public byte[] getDefaultConfigSchema() {
        String schema = getProperty(KaaClientProperties.CONFIG_SCHEMA_DEFAULT);
        return (schema != null) ? schema.getBytes(Charsets.UTF_8) : null;
    }

    public Base64 getBase64() {
        return base64;
    }

    public void setBase64(Base64 base64) {
        this.base64 = base64;
    }

    public String getWorkingDirectory() {
        String workingDir = getProperty(WORKING_DIR_PROPERTY);
        return isBlank(workingDir) ? WORKING_DIR_DEFAULT : checkDir(workingDir);
    }

    public void setWorkingDirectory(String workDir) {
        checkNotBlankProperty(workDir, "Working directory folder name couldn't be blank");
        setProperty(WORKING_DIR_PROPERTY, checkDir(workDir));
    }

    private String checkDir(String workDir) {
        return workDir.endsWith(FILE_SEPARATOR) ? workDir : workDir + FILE_SEPARATOR;
    }

    public String getStateFileName() {
        String stateFileName = getProperty(STATE_FILE_NAME_PROPERTY);
        return isBlank(stateFileName) ? STATE_FILE_NAME_DEFAULT : stateFileName;
    }

    public void setStateFileName(String fileName) {
        checkNotBlankProperty(fileName, "State file name couldn't be blank");
        setProperty(STATE_FILE_NAME_PROPERTY, fileName);
    }

    public String getStateFileFullName() {
        return getWorkingDirectory() + getStateFileName();
    }

    public String getPublicKeyFileName() {
        String privateKeyName = getProperty(CLIENT_PUBLIC_KEY_FILE_NAME_PROPERTY);
        return isBlank(privateKeyName) ? CLIENT_PRIVATE_KEY_NAME_DEFAULT : privateKeyName;
    }

    public void setPublicKeyFileName(String fileName) {
        checkNotBlankProperty(fileName, "Public key file name couldn't be blank");
        setProperty(CLIENT_PUBLIC_KEY_FILE_NAME_PROPERTY, fileName);
    }

    public String getPublicKeyFileFullName() {
        return getWorkingDirectory() + getPublicKeyFileName();
    }

    public String getPrivateKeyFileName() {
        String publicKeyName = getProperty(CLIENT_PRIVATE_KEY_FILE_NAME_PROPERTY);
        return isBlank(publicKeyName) ? CLIENT_PUBLIC_KEY_NAME_DEFAULT : publicKeyName;
    }

    public void setPrivateKeyFileName(String fileName) {
        checkNotBlankProperty(fileName, "Private key file name couldn't be blank");
        setProperty(CLIENT_PRIVATE_KEY_FILE_NAME_PROPERTY, fileName);
    }

    public String getPrivateKeyFileFullName() {
        return getWorkingDirectory() + getPrivateKeyFileName();
    }

}