com.sixt.service.framework.ServiceProperties.java Source code

Java tutorial

Introduction

Here is the source code for com.sixt.service.framework.ServiceProperties.java

Source

/**
 * Copyright 2016-2017 Sixt GmbH & Co. Autovermietung KG
 * 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 com.sixt.service.framework;

import com.jcabi.manifests.Manifests;
import com.sixt.service.framework.logging.SixtLogbackContext;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class ServiceProperties {

    private static final Logger logger = LoggerFactory.getLogger(ServiceProperties.class);

    public static final String REGISTRY_SERVER_KEY = "registryServer";
    public static final String KAFKA_SERVER_KEY = "kafkaServer";
    public static final String DATABASE_SERVER_KEY = "databaseServer";
    public static final String DATABASE_USERNAME_KEY = "databaseUsername";
    public static final String DATABASE_PASSWORD_KEY = "databasePassword";
    public static final String SERVICE_PORT_KEY = "servicePort";
    public static final String LOG_LEVEL_KEY = "logLevel";
    public static final String SERVICE_UNKNOWN = "com.sixt.service.unknown";

    private String serviceName = SERVICE_UNKNOWN;
    private String serviceVersion = "0.0.0-fffffff";
    private String serviceInstanceId = "unknown";
    private int servicePort = 0;
    private Map<String, String> allProperties = new HashMap<>();

    protected SixtLogbackContext logbackContext = new SixtLogbackContext();

    public ServiceProperties() {
    }

    /**
     * Parse the command-line arguments.  Framework-level (standard arguments for
     * all Java services) are parsed, and any remaining arguments and environment
     * variables are set into our properties map as well.
     */
    public void initialize(String[] args) {
        parseServiceProperties();
        parseCommandLineArguments(args);
        parseEnvironmentVariables();
        String logLevel = allProperties.get(LOG_LEVEL_KEY);
        if (!StringUtils.isBlank(logLevel)) {
            System.setProperty("SIXT_LOGGING", logLevel);
            logbackContext.updateLoggerLogLevel(logLevel);
        }
        if (allProperties.containsKey(SERVICE_PORT_KEY)) {
            setServicePort(Integer.parseInt(allProperties.get(SERVICE_PORT_KEY)));
        }
    }

    private void parseServiceProperties() {
        try {
            String name = Manifests.read("Service-Title");
            setServiceName(name);
        } catch (Exception ex) {
            logger.info("Error finding Service-Title in manifests", ex);
        }
        try {
            serviceVersion = Manifests.read("Service-Version");
        } catch (Exception ex) {
            logger.info("Error finding Service-Version in manifests", ex);
        }
        parseServiceInstance();
    }

    /**
     * If running in docker, use that; else, generate test_service
     */
    private void parseServiceInstance() {
        try {
            ProcessBuilder pb = new ProcessBuilder("bash", "-c",
                    "cat /proc/self/cgroup | grep docker | sed 's/^.*\\///' | tail -n1 | cut -c 1-12");
            Process p = pb.start();
            BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String output = reader.readLine();
            if (!StringUtils.isBlank(output)) {
                serviceInstanceId = output.trim();
            }
            p.waitFor();
        } catch (Exception e) {
            logger.error("Error getting docker container id", e);
        }
        if ("unknown".equals(serviceInstanceId)) {
            serviceInstanceId = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 12);
        }
    }

    private void parseCommandLineArguments(String[] args) {
        if (args.length % 2 == 1) {
            throw new IllegalArgumentException("Expecting even number of arguments");
        }
        for (int i = 0; i < args.length; i += 2) {
            String key = args[i];
            while (key.startsWith("-")) {
                key = key.substring(1);
            }
            String value = args[i + 1];
            logger.debug("Setting property from cmd-line {} to {}", key, value);
            allProperties.put(key, value);
        }
    }

    private void parseEnvironmentVariables() {
        Map<String, String> env = System.getenv();
        for (String key : env.keySet()) {
            if (key.startsWith("LC_") || key.startsWith("_")) {
                continue;
            }
            String value = env.get(key);
            logger.debug("Setting property from environment {} to {}", key, value);
            allProperties.put(key, value);
        }
    }

    public void ensureProperties(String[] requiredProps) {
        boolean fail = !areAllPropertiesSet(requiredProps);
        if (fail) {
            throw new IllegalStateException("EnsureProperties failed");
        }
    }

    public boolean areAllPropertiesSet(String[] requiredProps) {
        boolean fail = true;
        if (requiredProps != null) {
            for (String prop : requiredProps) {
                if (allProperties.get(prop) == null) {
                    logger.info("Required property {} was not set", prop);
                    fail = false;
                }
            }
        }
        return fail;
    }

    public String getServiceName() {
        return serviceName;
    }

    public String getServiceVersion() {
        return serviceVersion;
    }

    public String getServiceInstanceId() {
        return serviceInstanceId;
    }

    public void setServicePort(int servicePort) {
        this.servicePort = servicePort;
    }

    public int getServicePort() {
        return servicePort;
    }

    /**
     * Consul server in the form of host:port
     */
    public String getRegistryServer() {
        return allProperties.get(REGISTRY_SERVER_KEY);
    }

    public String getKafkaServer() {
        return allProperties.get(KAFKA_SERVER_KEY);
    }

    public String getDatabaseServer() {
        return allProperties.get(DATABASE_SERVER_KEY);
    }

    public String getDatabaseUsername() {
        return allProperties.get(DATABASE_USERNAME_KEY);
    }

    public String getDatabasePassword() {
        return allProperties.get(DATABASE_PASSWORD_KEY);
    }

    public void addProperty(String key, String value) {
        allProperties.put(key, value);
    }

    public String getProperty(String key) {
        return allProperties.get(key);
    }

    public Map<String, String> getAllProperties() {
        return allProperties;
    }

    public int getIntegerProperty(String key, int defaultValue) {
        String value = getProperty(key);
        if (StringUtils.isNotBlank(value)) {
            try {
                return Integer.valueOf(value);
            } catch (Exception ex) {
                logger.info("Service property '{}' was not an integer value: '{}'", key, value);
            }
        }
        return defaultValue;
    }

    //Intended only for testing
    public void setServiceName(String name) {
        serviceName = name;
    }

    //Intended only for testing
    public void setServiceInstanceId(String id) {
        serviceInstanceId = id;
    }

}