/*
* 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 org.apache.karaf.main;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.UUID;
import org.apache.felix.utils.properties.Properties;
import org.apache.karaf.main.lock.SimpleFileLock;
import org.apache.karaf.main.util.Utils;
import org.apache.karaf.util.config.PropertiesLoader;
import org.osgi.framework.Constants;
public class ConfigProperties {
/**
* The system property for specifying the Karaf home directory. The home directory
* hold the binary install of Karaf.
*/
public static final String PROP_KARAF_HOME = "karaf.home";
/**
* The environment variable for specifying the Karaf home directory. The home directory
* hold the binary install of Karaf.
*/
public static final String ENV_KARAF_HOME = "KARAF_HOME";
/**
* The system property for specifying the Karaf base directory. The base directory
* holds the configuration and data for a Karaf instance.
*/
public static final String PROP_KARAF_BASE = "karaf.base";
/**
* The environment variable for specifying the Karaf base directory. The base directory
* holds the configuration and data for a Karaf instance.
*/
public static final String ENV_KARAF_BASE = "KARAF_BASE";
/**
* The system property for specifying the Karaf data directory. The data directory
* holds the bundles data and cache for a Karaf instance.
*/
public static final String PROP_KARAF_DATA = "karaf.data";
/**
* The environment variable for specifying the Karaf data directory. The data directory
* holds the bundles data and cache for a Karaf instance.
*/
public static final String ENV_KARAF_DATA = "KARAF_DATA";
/**
* The system property for specifying the Karaf etc directory. The etc directory
* holds the configuration for a Karaf instance.
*/
public static final String PROP_KARAF_ETC = "karaf.etc";
/**
* The environment variable for specifying the Karaf etc directory. The etc directory
* holds the configuration for a Karaf instance.
*/
public static final String ENV_KARAF_ETC = "KARAF_ETC";
/**
* The system property for specifying the Karaf data directory. The data directory
* holds the bundles data and cache for a Karaf instance.
*/
public static final String PROP_KARAF_INSTANCES = "karaf.instances";
/**
* The system property for specifying the Karaf data directory. The data directory
* holds the bundles data and cache for a Karaf instance.
*/
public static final String ENV_KARAF_INSTANCES = "KARAF_INSTANCES";
/**
* The system property for hosting the current Karaf version.
*/
public static final String PROP_KARAF_VERSION = "karaf.version";
/**
* The default name used for the configuration properties file.
*/
private static final String CONFIG_PROPERTIES_FILE_NAME = "config.properties";
/**
* The default name used for the system properties file.
*/
public static final String SYSTEM_PROPERTIES_FILE_NAME = "system.properties";
/**
* Config property which identifies directories which contain bundles to be loaded by SMX
*/
private static final String BUNDLE_LOCATIONS = "bundle.locations";
/**
* The lock implementation
*/
private static final String PROPERTY_LOCK_CLASS = "karaf.lock.class";
public static final String PROPERTY_LOCK_DELAY = "karaf.lock.delay";
private static final String PROPERTY_LOCK_LEVEL = "karaf.lock.level";
private static final String PROPERTY_LOCK_SLAVE_BLOCK = "karaf.lock.slave.block";
private static final String DEFAULT_REPO = "karaf.default.repository";
private static final String KARAF_FRAMEWORK = "karaf.framework";
private static final String KARAF_FRAMEWORK_FACTORY = "karaf.framework.factory";
private static final String KARAF_SHUTDOWN_TIMEOUT = "karaf.shutdown.timeout";
private static final String KARAF_SHUTDOWN_PORT = "karaf.shutdown.port";
private static final String KARAF_SHUTDOWN_HOST = "karaf.shutdown.host";
private static final String KARAF_SHUTDOWN_PORT_FILE = "karaf.shutdown.port.file";
private static final String KARAF_SHUTDOWN_COMMAND = "karaf.shutdown.command";
private static final String KARAF_SHUTDOWN_PID_FILE = "karaf.shutdown.pid.file";
private static final String KARAF_PID_FILE = "karaf.pid.file";
private static final String KARAF_STARTUP_MESSAGE = "karaf.startup.message";
private static final String KARAF_DELAY_CONSOLE = "karaf.delay.console";
private static final String KARAF_THREAD_MONITORING = "karaf.thread.monitoring";
private static final String PROPERTY_LOCK_CLASS_DEFAULT = SimpleFileLock.class.getName();
private static final String SECURITY_PROVIDERS = "org.apache.karaf.security.providers";
public static final String DEFAULT_LOCK_DELAY = "1000";
/**
* If a lock should be used before starting the runtime
*/
private static final String PROPERTY_USE_LOCK = "karaf.lock";
File karafHome;
File karafBase;
File karafData;
File karafEtc;
File karafInstances;
Properties props;
String[] securityProviders;
int defaultStartLevel = 100;
int lockStartLevel = 1;
int lockDefaultBootLevel = 1;
int lockDelay;
boolean lockSlaveBlock = false;
int shutdownTimeout = 5 * 60 * 1000;
boolean useLock;
String lockClass;
String frameworkFactoryClass;
URI frameworkBundle;
String defaultRepo;
String bundleLocations;
int defaultBundleStartlevel;
String pidFile;
int shutdownPort;
String shutdownHost;
String portFile;
String shutdownCommand;
String startupMessage;
boolean delayConsoleStart;
boolean threadMonitoring;
public ConfigProperties() throws Exception {
this.karafHome = Utils.getKarafHome(ConfigProperties.class, PROP_KARAF_HOME, ENV_KARAF_HOME);
this.karafBase = Utils.getKarafDirectory(PROP_KARAF_BASE, ENV_KARAF_BASE, karafHome, false, true);
this.karafData = Utils.getKarafDirectory(PROP_KARAF_DATA, ENV_KARAF_DATA, new File(karafBase, "data"), true, true);
this.karafEtc = Utils.getKarafDirectory(PROP_KARAF_ETC, ENV_KARAF_ETC, new File(karafBase, "etc"), true, true);
this.karafInstances = Utils.getKarafDirectory(PROP_KARAF_INSTANCES, ENV_KARAF_INSTANCES, new File(karafHome, "instances"), false, false);
Package p = Package.getPackage("org.apache.karaf.main");
if (p != null && p.getImplementationVersion() != null) {
System.setProperty(PROP_KARAF_VERSION, p.getImplementationVersion());
}
System.setProperty(PROP_KARAF_HOME, karafHome.getPath());
System.setProperty(PROP_KARAF_BASE, karafBase.getPath());
System.setProperty(PROP_KARAF_DATA, karafData.getPath());
System.setProperty(PROP_KARAF_ETC, karafEtc.getPath());
System.setProperty(PROP_KARAF_INSTANCES, karafInstances.getPath());
if (!karafEtc.exists()) {
throw new FileNotFoundException("Karaf etc folder not found: " + karafEtc.getAbsolutePath());
}
configureSAAJForIBMJVM();
PropertiesLoader.loadSystemProperties(new File(karafEtc, SYSTEM_PROPERTIES_FILE_NAME));
this.props = PropertiesLoader.loadConfigProperties(new File(karafEtc, CONFIG_PROPERTIES_FILE_NAME));
this.securityProviders = getSecurityProviders();
this.defaultStartLevel = Integer.parseInt(props.getProperty(Constants.FRAMEWORK_BEGINNING_STARTLEVEL));
System.setProperty(Constants.FRAMEWORK_BEGINNING_STARTLEVEL, Integer.toString(this.defaultStartLevel));
this.lockStartLevel = Integer.parseInt(props.getProperty(PROPERTY_LOCK_LEVEL, Integer.toString(lockStartLevel)));
this.lockDelay = Integer.parseInt(props.getProperty(PROPERTY_LOCK_DELAY, DEFAULT_LOCK_DELAY));
this.lockSlaveBlock = Boolean.parseBoolean(props.getProperty(PROPERTY_LOCK_SLAVE_BLOCK, "false"));
this.props.setProperty(Constants.FRAMEWORK_BEGINNING_STARTLEVEL, Integer.toString(lockDefaultBootLevel));
this.shutdownTimeout = Integer.parseInt(props.getProperty(KARAF_SHUTDOWN_TIMEOUT, Integer.toString(shutdownTimeout)));
this.useLock = Boolean.parseBoolean(props.getProperty(PROPERTY_USE_LOCK, "true"));
this.lockClass = props.getProperty(PROPERTY_LOCK_CLASS, PROPERTY_LOCK_CLASS_DEFAULT);
this.frameworkFactoryClass = props.getProperty(KARAF_FRAMEWORK_FACTORY);
this.frameworkBundle = getFramework();
this.defaultRepo = System.getProperty(DEFAULT_REPO, "system");
this.bundleLocations = props.getProperty(BUNDLE_LOCATIONS);
this.defaultBundleStartlevel = getDefaultBundleStartLevel(60);
this.pidFile = props.getProperty(KARAF_PID_FILE, props.getProperty(KARAF_SHUTDOWN_PID_FILE));
this.shutdownPort = Integer.parseInt(props.getProperty(KARAF_SHUTDOWN_PORT, "0"));
this.shutdownHost = props.getProperty(KARAF_SHUTDOWN_HOST, "localhost");
this.portFile = props.getProperty(KARAF_SHUTDOWN_PORT_FILE);
this.shutdownCommand = props.getProperty(KARAF_SHUTDOWN_COMMAND);
this.startupMessage = props.getProperty(KARAF_STARTUP_MESSAGE, "Apache Karaf starting up. Press Enter to open the shell now...");
this.delayConsoleStart = Boolean.parseBoolean(props.getProperty(KARAF_DELAY_CONSOLE, "false"));
this.threadMonitoring = Boolean.parseBoolean(props.getProperty(KARAF_THREAD_MONITORING, "false"));
System.setProperty(KARAF_DELAY_CONSOLE, Boolean.toString(this.delayConsoleStart));
}
public void performInit() throws Exception {
File cleanAllIndicatorFile = new File(karafData, "clean_all");
File cleanCacheIndicatorFile = new File(karafData, "clean_cache");
if (Boolean.getBoolean("karaf.clean.all") || cleanAllIndicatorFile.exists()) {
if (cleanAllIndicatorFile.exists()) {
cleanAllIndicatorFile.delete();
}
Utils.deleteDirectory(this.karafData);
this.karafData = Utils.getKarafDirectory(PROP_KARAF_DATA, ENV_KARAF_DATA, new File(karafBase, "data"), true, true);
} else {
if (Boolean.getBoolean("karaf.clean.cache") || cleanCacheIndicatorFile.exists()) {
if (cleanCacheIndicatorFile.exists()) {
cleanCacheIndicatorFile.delete();
}
File karafCache = Utils.validateDirectoryExists(new File(karafData, "cache").getPath(), "Invalid cache directory", true, true);
Utils.deleteDirectory(karafCache);
}
}
String frameworkStoragePath = props.getProperty(Constants.FRAMEWORK_STORAGE);
if (frameworkStoragePath == null) {
File storage = new File(karafData.getPath(), "cache");
try {
storage.mkdirs();
} catch (SecurityException se) {
throw new Exception(se.getMessage());
}
props.setProperty(Constants.FRAMEWORK_STORAGE, storage.getAbsolutePath());
}
if (shutdownCommand == null || shutdownCommand.isEmpty()) {
try {
shutdownCommand = UUID.randomUUID().toString();
Properties temp = new Properties(new File(karafEtc, CONFIG_PROPERTIES_FILE_NAME));
temp.put(KARAF_SHUTDOWN_COMMAND, Arrays.asList("", "#", "# Generated command shutdown", "#"), shutdownCommand);
temp.save();
} catch (IOException ioException) {
System.err.println("WARN: can't update etc/config.properties with the generated command shutdown. We advise to manually add the karaf.shutdown.command property.");
}
}
if (threadMonitoring) {
ThreadMXBean threadsBean = ManagementFactory.getThreadMXBean();
if (threadsBean.isThreadCpuTimeSupported()) {
threadsBean.setThreadCpuTimeEnabled(true);
}
if (threadsBean.isThreadContentionMonitoringSupported()) {
threadsBean.setThreadContentionMonitoringEnabled(true);
}
}
}
private String getPropertyOrFail(String propertyName) {
String value = props.getProperty(propertyName);
if (value == null) {
throw new IllegalArgumentException("Property " + propertyName + " must be set in the etc/" + CONFIG_PROPERTIES_FILE_NAME + " configuration file");
}
return value;
}
private String[] getSecurityProviders() {
String prop = props.getProperty(SECURITY_PROVIDERS);
return (prop != null) ? prop.split(",") : new String[] {};
}
private URI getFramework() throws URISyntaxException {
String framework = getPropertyOrFail(KARAF_FRAMEWORK);
String frameworkBundleUri = getPropertyOrFail(KARAF_FRAMEWORK + "." + framework);
return new URI(frameworkBundleUri);
}
private int getDefaultBundleStartLevel(int ibsl) {
try {
String str = props.getProperty("karaf.startlevel.bundle");
if (str != null) {
ibsl = Integer.parseInt(str);
}
} catch (Throwable t) {
}
return ibsl;
}
private void configureSAAJForIBMJVM() {
if (System.getProperty("java.vendor").equals("IBM Corporation")) {
System.setProperty("javax.xml.soap.MessageFactory",
"com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl");
System.setProperty("javax.xml.soap.SOAPFactory",
"com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPFactory1_1Impl");
System.setProperty("javax.xml.soap.SOAPConnectionFactory",
"com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnectionFactory");
System.setProperty("javax.xml.soap.MetaFactory",
"com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl");
}
}
}