http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/SystemService.java ---------------------------------------------------------------------- diff --git a/system/src/main/java/org/apache/karaf/system/SystemService.java b/system/src/main/java/org/apache/karaf/system/SystemService.java new file mode 100644 index 0000000..2f53946 --- /dev/null +++ b/system/src/main/java/org/apache/karaf/system/SystemService.java @@ -0,0 +1,130 @@ + /* + * 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.system; + +/** + * Describe a system service + */ +public interface SystemService { + + /** + * Types defining what to remove on a restart of Karaf + */ + public enum Swipe { + /** Delete nothing; simple restart */ + NONE, + /** Delete only the cache; everything else remains */ + CACHE, + /** Forces a clean restart by removing the working directory; this option is compatible to the former clean method. */ + ALL + } + + /** + * Halt the Karaf container. + */ + void halt() throws Exception; + + /** + * Halt the Karaf container. + * + * @param time shutdown delay. The time argument can have different formats. + * First, it can be an absolute time in the format hh:mm, in which hh is the hour (1 or 2 digits) and mm + * is the minute of the hour (in two digits). Second, it can be in the format +m, in which m is the number of minutes + * to wait. The word now is an alias for +0. + */ + void halt(String time) throws Exception; + + /** + * Reboot the Karaf container. + * + * @throws Exception + */ + void reboot() throws Exception; + + /** + * Reboot the Karaf container. + * + * @param time reboot delay. The time argument can have different formats. + * First, it can be an absolute time in the format hh:mm, in which hh is the hour (1 or 2 digits) and mm + * is the minute of the hour (in two digits). Second, it can be in the format +m, in which m is the number of minutes + * to wait. The word now is an alias for +0. + * @param clean Force a clean restart by deleting the working directory. + */ + void reboot(String time, Swipe clean) throws Exception; + + /** + * Set the system start level. + * + * @param startLevel the new system start level. + */ + void setStartLevel(int startLevel) throws Exception; + + /** + * Get the system start level. + * + * @return the current system start level. + */ + int getStartLevel() throws Exception; + + /** + * Get the version of the current Karaf instance + * + * @return instance version + */ + String getVersion(); + + /** + * Get the name of the current Karaf instance + * + * @return instance name + */ + String getName(); + + /** + * Set the name of the Karaf instance + * + * @param name new instance name + */ + void setName(String name); + + /** + * Get the current OSGi framework in use. + * + * @return the name of the OSGi framework in use. + * @throws Exception + */ + FrameworkType getFramework(); + + /** + * change OSGi framework + * + * @param framework to use. + */ + void setFramework(FrameworkType framework); + + /** + * Enable or diable debgging + * @param debug enable if true + */ + void setFrameworkDebug(boolean debug); + + /** + * Set a system property and persist to etc/system.properties + * @param key + */ + String setSystemProperty(String key, String value, boolean persist); +}
http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/commands/FrameworkOptions.java ---------------------------------------------------------------------- diff --git a/system/src/main/java/org/apache/karaf/system/commands/FrameworkOptions.java b/system/src/main/java/org/apache/karaf/system/commands/FrameworkOptions.java new file mode 100644 index 0000000..9e16a7d --- /dev/null +++ b/system/src/main/java/org/apache/karaf/system/commands/FrameworkOptions.java @@ -0,0 +1,73 @@ +/* + * 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.system.commands; + +import org.apache.karaf.shell.api.action.Action; +import org.apache.karaf.shell.api.action.Argument; +import org.apache.karaf.shell.api.action.Command; +import org.apache.karaf.shell.api.action.Option; +import org.apache.karaf.shell.api.action.lifecycle.Reference; +import org.apache.karaf.shell.api.action.lifecycle.Service; +import org.apache.karaf.system.FrameworkType; +import org.apache.karaf.system.SystemService; + +/** + * Command for enabling/disabling debug logging on the OSGi framework + */ +@Command(scope = "system", name = "framework", description = "OSGi Framework options.") +@Service +public class FrameworkOptions implements Action { + + @Option(name = "-debug", aliases={"--enable-debug"}, description="Enable debug for the OSGi framework", required = false, multiValued = false) + boolean debug; + + @Option(name = "-nodebug", aliases={"--disable-debug"}, description="Disable debug for the OSGi framework", required = false, multiValued = false) + boolean nodebug; + + @Argument(name = "framework", required = false, description = "Name of the OSGi framework to use") + String framework; + + @Reference + SystemService systemService; + + @Override + public Object execute() throws Exception { + + if (!debug^nodebug && framework == null) { + System.out.printf("Current OSGi framework is %s%n", systemService.getFramework().name()); + return null; + } + if (framework != null) { + FrameworkType frameworkType = FrameworkType.valueOf(framework); + systemService.setFramework(frameworkType); + System.out.println("Changed OSGi framework to " + frameworkType.toString().toLowerCase() + ". Karaf needs to be restarted to make the change effective"); + } + if (debug) { + FrameworkType frameworkType = systemService.getFramework(); + System.out.printf("Enabling debug for OSGi framework (%s)%n", frameworkType.name()); + systemService.setFrameworkDebug(true); + } + if (nodebug) { + FrameworkType frameworkType = systemService.getFramework(); + System.out.printf("Disabling debug for OSGi framework (%s)%n", frameworkType.name()); + systemService.setFrameworkDebug(false); + } + + return null; + } + +} http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/commands/Name.java ---------------------------------------------------------------------- diff --git a/system/src/main/java/org/apache/karaf/system/commands/Name.java b/system/src/main/java/org/apache/karaf/system/commands/Name.java new file mode 100644 index 0000000..a716d82 --- /dev/null +++ b/system/src/main/java/org/apache/karaf/system/commands/Name.java @@ -0,0 +1,51 @@ +/* + * 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.system.commands; + + +import org.apache.karaf.shell.api.action.Action; +import org.apache.karaf.shell.api.action.Argument; +import org.apache.karaf.shell.api.action.Command; +import org.apache.karaf.shell.api.action.lifecycle.Reference; +import org.apache.karaf.shell.api.action.lifecycle.Service; +import org.apache.karaf.system.SystemService; + +/** + * Command to shut down Karaf container. + */ +@Command(scope = "system", name = "name", description = "Show or change Karaf instance name.") +@Service +public class Name implements Action { + + @Argument(name = "name", index = 0, description = "New name for the instance", required = false, multiValued = false) + String name; + + @Reference + SystemService systemService; + + @Override + public Object execute() throws Exception { + if (name == null) { + System.out.println(systemService.getName()); + } else { + systemService.setName(name); + System.out.println("Instance name changed to " + name + ". Restart needed for this to take effect."); + } + return null; + } + +} http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/commands/Shutdown.java ---------------------------------------------------------------------- diff --git a/system/src/main/java/org/apache/karaf/system/commands/Shutdown.java b/system/src/main/java/org/apache/karaf/system/commands/Shutdown.java new file mode 100644 index 0000000..b8b4b41 --- /dev/null +++ b/system/src/main/java/org/apache/karaf/system/commands/Shutdown.java @@ -0,0 +1,104 @@ +/* + * 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.system.commands; + +import org.apache.karaf.shell.api.action.Action; +import org.apache.karaf.shell.api.action.Argument; +import org.apache.karaf.shell.api.action.Command; +import org.apache.karaf.shell.api.action.Option; +import org.apache.karaf.shell.api.action.lifecycle.Reference; +import org.apache.karaf.shell.api.action.lifecycle.Service; +import org.apache.karaf.shell.api.console.Session; +import org.apache.karaf.system.SystemService; + +/** + * Command to shut down Karaf container. + */ +@Command(scope = "system", name = "shutdown", description = "Shutdown Karaf.") +@Service +public class Shutdown implements Action { + + @Option(name = "-f", aliases = "--force", description = "Force the shutdown without confirmation message.", required = false, multiValued = false) + boolean force = false; + + @Option(name = "-r", aliases = "--reboot", description = "Reboot the Karaf container.", required = false, multiValued = false) + boolean reboot = false; + + @Option(name = "-h", aliases = "--halt", description = "Halt the Karaf container.", required = false, multiValued = false) + boolean halt = false; + + @Option(name = "-c", aliases = {"--clean", "--clean-all", "-ca"}, description = "Force a clean restart by deleting the data directory") + private boolean cleanAll; + + @Option(name = "-cc", aliases = {"--clean-cache", "-cc"}, description = "Force a clean restart by deleting the cache directory") + private boolean cleanCache; + + + @Argument(name = "time", index = 0, description = "Shutdown after a specified delay. The time argument can have different" + + " formats. First, it can be an absolute time in the format hh:mm, in which hh is the hour (1 or 2 digits) and mm" + + " is the minute of the hour (in two digits). Second, it can be in the format +m, in which m is the number of minutes" + + " to wait. The word now is an alias for +0.", required = false, multiValued = false) + String time; + + @Reference + SystemService systemService; + + @Reference + Session session; + + @Override + public Object execute() throws Exception { + + if (force) { + if (reboot) { + systemService.reboot(time, determineSwipeType()); + } else { + systemService.halt(time); + } + return null; + } + + for (; ; ) { + String karafName = System.getProperty("karaf.name"); + String msg; + if (reboot) { + msg = String.format("Confirm: reboot instance %s (yes/no): ", karafName); + } else { + msg = String.format("Confirm: halt instance %s (yes/no): ", karafName); + } + String str = session.readLine(msg, null); + if (str.equalsIgnoreCase("yes")) { + if (reboot) { + systemService.reboot(time, determineSwipeType()); + } else { + systemService.halt(time); + } + } + return null; + } + } + + private SystemService.Swipe determineSwipeType() { + if (cleanAll) { + return SystemService.Swipe.ALL; + } else if (cleanCache) { + return SystemService.Swipe.CACHE; + } + return SystemService.Swipe.NONE; + } + +} http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/commands/StartLevel.java ---------------------------------------------------------------------- diff --git a/system/src/main/java/org/apache/karaf/system/commands/StartLevel.java b/system/src/main/java/org/apache/karaf/system/commands/StartLevel.java new file mode 100644 index 0000000..e91c15a --- /dev/null +++ b/system/src/main/java/org/apache/karaf/system/commands/StartLevel.java @@ -0,0 +1,49 @@ +/* + * 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.system.commands; + +import org.apache.karaf.shell.api.action.Action; +import org.apache.karaf.shell.api.action.Argument; +import org.apache.karaf.shell.api.action.Command; +import org.apache.karaf.shell.api.action.lifecycle.Reference; +import org.apache.karaf.shell.api.action.lifecycle.Service; +import org.apache.karaf.system.SystemService; + +/** + * Get/set the system start level. + */ +@Command(scope = "system", name = "start-level", description = "Gets or sets the system start level.") +@Service +public class StartLevel implements Action { + + @Argument(index = 0, name = "level", description = "The new system start level to set", required = false, multiValued = false) + Integer level; + + @Reference + SystemService systemService; + + @Override + public Object execute() throws Exception { + if (level == null) { + System.out.println("Level " + systemService.getStartLevel()); + } else { + systemService.setStartLevel(level); + } + return null; + } + +} http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/commands/SystemProperty.java ---------------------------------------------------------------------- diff --git a/system/src/main/java/org/apache/karaf/system/commands/SystemProperty.java b/system/src/main/java/org/apache/karaf/system/commands/SystemProperty.java new file mode 100644 index 0000000..37c2a1e --- /dev/null +++ b/system/src/main/java/org/apache/karaf/system/commands/SystemProperty.java @@ -0,0 +1,157 @@ +/* + * 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.system.commands; + +import java.io.File; +import java.io.PrintStream; +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.Date; +import java.util.Iterator; +import java.util.Properties; +import java.util.Set; +import java.util.Vector; + +import org.apache.karaf.shell.api.action.Action; +import org.apache.karaf.shell.api.action.Argument; +import org.apache.karaf.shell.api.action.Command; +import org.apache.karaf.shell.api.action.Option; +import org.apache.karaf.shell.api.action.lifecycle.Reference; +import org.apache.karaf.shell.api.action.lifecycle.Service; +import org.apache.karaf.system.SystemService; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; + +/** + * Command that allow access to system properties easily. + */ +@Command(scope = "system", name = "property", description = "Get or set a system property.") +@Service +public class SystemProperty implements Action { + + @Option(name = "-p", aliases = {"--persistent"}, description = "Persist the new value to the etc/system.properties file") + boolean persistent; + + @Option(name = "-f", aliases = {"--file-dump"}, description = "Dump all system properties in a file (in data folder)") + boolean dumpToFile; + + @Option(name = "-u", aliases = {"--unset"}, description = "Show unset know properties with value unset") + boolean unset; + + @Argument(index = 0, name = "key", required = false, description = "The system property name") + String key; + + @Argument(index = 1, name = "value", required = false, description = "New value for the system property") + String value; + + @Reference + BundleContext bundleContext; + + @Reference + SystemService systemService; + + @Override + public Object execute() throws Exception { + if (key == null && value == null) { + Properties props = (Properties) System.getProperties().clone(); + + String def = null; + if (unset) { + def = "unset"; + } + + setProperty(props, Constants.FRAMEWORK_BEGINNING_STARTLEVEL, def); + setProperty(props, Constants.FRAMEWORK_BOOTDELEGATION, def); + setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT, def); + setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_APP, def); + setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_BOOT, def); + setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_EXT, def); + setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_FRAMEWORK, def); + setProperty(props, Constants.FRAMEWORK_EXECPERMISSION, def); + setProperty(props, Constants.FRAMEWORK_EXECUTIONENVIRONMENT, def); + setProperty(props, Constants.FRAMEWORK_LANGUAGE, def); + setProperty(props, Constants.FRAMEWORK_LIBRARY_EXTENSIONS, def); + setProperty(props, Constants.FRAMEWORK_OS_NAME, def); + setProperty(props, Constants.FRAMEWORK_OS_VERSION, def); + setProperty(props, Constants.FRAMEWORK_PROCESSOR, def); + setProperty(props, Constants.FRAMEWORK_SECURITY, def); + setProperty(props, Constants.FRAMEWORK_SECURITY_OSGI, def); + setProperty(props, Constants.FRAMEWORK_STORAGE, def); + setProperty(props, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT, def); + setProperty(props, Constants.FRAMEWORK_SYSTEMPACKAGES, def); + setProperty(props, Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, def); + setProperty(props, Constants.FRAMEWORK_VENDOR, def); + setProperty(props, Constants.FRAMEWORK_VERSION, def); + setProperty(props, Constants.FRAMEWORK_WINDOWSYSTEM, def); + + setProperty(props, Constants.SUPPORTS_BOOTCLASSPATH_EXTENSION, def); + setProperty(props, Constants.SUPPORTS_FRAMEWORK_EXTENSION, def); + setProperty(props, Constants.SUPPORTS_FRAMEWORK_FRAGMENT, def); + setProperty(props, Constants.SUPPORTS_FRAMEWORK_REQUIREBUNDLE, def); + + if (dumpToFile) { + PrintStream ps = new PrintStream( + new File( + bundleContext.getProperty("karaf.data"), + "dump-properties-" + System.currentTimeMillis() + ".properties" + ) + ); + ps.println("#Dump of the System and OSGi properties with the command system:property"); + ps.println("#Dump executed at " + new SimpleDateFormat().format(new Date())); + printOrderedProperties(props, ps); + ps.flush(); + ps.close(); + } else { + printOrderedProperties(props, System.out); + } + + return null; + } + + if (value != null) { + systemService.setSystemProperty(key, value, persistent); + } else { + System.out.println(System.getProperty(key)); + } + + return null; + } + + private void printOrderedProperties(Properties props, PrintStream out) { + Set<Object> keys = props.keySet(); + Vector<String> order = new Vector<String>(keys.size()); + for (Iterator<Object> i = keys.iterator(); i.hasNext(); ) { + Object str = (Object) i.next(); + order.add((String) str); + } + Collections.sort(order); + for (Iterator<String> i = order.iterator(); i.hasNext(); ) { + String key = (String) i.next(); + out.println(key + "=" + props.getProperty(key)); + } + } + + private void setProperty(Properties props, String key, String def) { + String val = bundleContext.getProperty(key); + if (val == null && def != null) { + props.setProperty(key, def); + } else if (val != null) { + props.setProperty(key, val); + } + } + +} http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/commands/Version.java ---------------------------------------------------------------------- diff --git a/system/src/main/java/org/apache/karaf/system/commands/Version.java b/system/src/main/java/org/apache/karaf/system/commands/Version.java new file mode 100644 index 0000000..9837aaa --- /dev/null +++ b/system/src/main/java/org/apache/karaf/system/commands/Version.java @@ -0,0 +1,38 @@ +/* + * 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.system.commands; + +import org.apache.karaf.shell.api.action.Action; +import org.apache.karaf.shell.api.action.Command; +import org.apache.karaf.shell.api.action.lifecycle.Reference; +import org.apache.karaf.shell.api.action.lifecycle.Service; +import org.apache.karaf.system.SystemService; + +@Command(scope = "system", name = "version", description = "Display the instance version") +@Service +public class Version implements Action { + + @Reference + SystemService systemService; + + @Override + public Object execute() throws Exception { + System.out.println(systemService.getVersion()); + return null; + } + +} http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/internal/SystemServiceImpl.java ---------------------------------------------------------------------- diff --git a/system/src/main/java/org/apache/karaf/system/internal/SystemServiceImpl.java b/system/src/main/java/org/apache/karaf/system/internal/SystemServiceImpl.java new file mode 100644 index 0000000..8fa5a38 --- /dev/null +++ b/system/src/main/java/org/apache/karaf/system/internal/SystemServiceImpl.java @@ -0,0 +1,238 @@ +/* +* 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.system.internal; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Calendar; +import java.util.GregorianCalendar; + +import org.apache.felix.utils.properties.Properties; +import org.apache.karaf.system.FrameworkType; +import org.apache.karaf.system.SystemService; +import org.osgi.framework.BundleContext; +import org.osgi.framework.startlevel.FrameworkStartLevel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Implementation of the system service. + */ +public class SystemServiceImpl implements SystemService { + + private static final Logger LOGGER = LoggerFactory.getLogger(SystemServiceImpl.class); + + private BundleContext bundleContext; + + public void setBundleContext(BundleContext bundleContext) { + this.bundleContext = bundleContext; + } + + public BundleContext getBundleContext() { + return this.bundleContext; + } + + public void halt() throws Exception { + halt(null); + } + + public void halt(String time) throws Exception { + shutdown(timeToSleep(time)); + } + + public void reboot() throws Exception { + reboot(null, Swipe.NONE); + } + + public void reboot(String time, Swipe cleanup) throws Exception { + reboot(timeToSleep(time), cleanup); + } + + private void shutdown(final long sleep) { + new Thread() { + public void run() { + try { + sleepWithMsg(sleep, "Shutdown in " + sleep / 1000 / 60 + " minute(s)"); + getBundleContext().getBundle(0).stop(); + } catch (Exception e) { + LOGGER.error("Halt error", e); + } + } + }.start(); + } + + private void reboot(final long sleep, final Swipe clean) { + new Thread() { + public void run() { + try { + sleepWithMsg(sleep, "Reboot in " + sleep / 1000 / 60 + " minute(s)"); + System.setProperty("karaf.restart", "true"); + if (clean.equals(Swipe.ALL)) { + System.setProperty("karaf.clean.all", "true"); + } else if (clean.equals(Swipe.CACHE)) { + System.setProperty("karaf.clean.cache", "true"); + } + bundleContext.getBundle(0).stop(); + } catch (Exception e) { + LOGGER.error("Reboot error", e); + } + } + }.start(); + } + + private void sleepWithMsg(final long sleep, String msg) + throws InterruptedException { + if (sleep > 0) { + LOGGER.info(msg); + System.err.println(msg); + } + Thread.sleep(sleep); + } + + public void setStartLevel(int startLevel) throws Exception { + getBundleContext().getBundle(0).adapt(FrameworkStartLevel.class).setStartLevel(startLevel); + } + + public int getStartLevel() throws Exception { + return getBundleContext().getBundle(0).adapt(FrameworkStartLevel.class).getStartLevel(); + } + + /** + * Convert a time string to sleep period (in millisecond). + * + * @param time the time string. + * @return the corresponding sleep period in millisecond. + */ + private long timeToSleep(String time) throws Exception { + long sleep = 0; + if (time != null) { + if (!time.equals("now")) { + if (time.startsWith("+")) { + // delay in number of minutes provided + time = time.substring(1); + try { + sleep = Long.parseLong(time) * 60 * 1000; + } catch (Exception e) { + throw new IllegalArgumentException("Time " + time + " is not valid"); + } + } else { + // try to parse the date in hh:mm + String[] strings = time.split(":"); + if (strings.length != 2) { + throw new IllegalArgumentException("Time " + time + " is not valid"); + } + GregorianCalendar currentDate = new GregorianCalendar(); + GregorianCalendar shutdownDate = new GregorianCalendar(currentDate.get(Calendar.YEAR), currentDate.get(Calendar.MONTH), currentDate.get(Calendar.DATE), Integer.parseInt(strings[0]), Integer.parseInt(strings[1])); + if (shutdownDate.before(currentDate)) { + shutdownDate.set(Calendar.DATE, shutdownDate.get(Calendar.DATE) + 1); + } + sleep = shutdownDate.getTimeInMillis() - currentDate.getTimeInMillis(); + } + } + } + return sleep; + } + + @Override + public String getVersion() { + return System.getProperty("karaf.version"); + } + + @Override + public String getName() { + return bundleContext.getProperty("karaf.name"); + } + + @Override + public void setName(String name) { + try { + String karafEtc = bundleContext.getProperty("karaf.etc"); + File etcDir = new File(karafEtc); + File syspropsFile = new File(etcDir, "system.properties"); + FileInputStream fis = new FileInputStream(syspropsFile); + Properties props = new Properties(); + props.load(fis); + fis.close(); + props.setProperty("karaf.name", name); + FileOutputStream fos = new FileOutputStream(syspropsFile); + props.store(fos, ""); + fos.close(); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + public FrameworkType getFramework() { + if (bundleContext.getBundle(0).getSymbolicName().contains("felix")) { + return FrameworkType.felix; + } else { + return FrameworkType.equinox; + } + } + + private Properties loadProps() throws IOException { + return new Properties(new File(System.getProperty("karaf.etc"), "config.properties")); + } + + public void setFramework(FrameworkType framework) { + if (framework == null) { + return; + } + try { + Properties properties = loadProps(); + properties.put("karaf.framework", framework.name()); + properties.save(); + } catch (IOException e) { + throw new RuntimeException("Error setting framework: " + e.getMessage(), e); + } + } + + public void setFrameworkDebug(boolean debug) { + try { + Properties properties = loadProps(); + if (debug) { + properties.put("felix.log.level", "4"); + properties.put("osgi.debug", "etc/equinox-debug.properties"); + } else { + properties.remove("felix.log.level"); + properties.remove("osgi.debug"); + } + // TODO populate the equinox-debug.properties file with the one provided in shell/dev module + properties.save(); + } catch (IOException e) { + throw new RuntimeException("Error settting framework debugging: " + e.getMessage(), e); + } + } + + @Override + public String setSystemProperty(String key, String value, boolean persist) { + if (persist) { + try { + String etc = System.getProperty("karaf.etc"); + Properties props = new Properties(new File(etc, "system.properties")); + props.put(key, value); + props.save(); + } catch (IOException e) { + throw new RuntimeException("Error persisting system property", e); + } + } + return System.setProperty(key, value); + } + +} http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/internal/osgi/Activator.java ---------------------------------------------------------------------- diff --git a/system/src/main/java/org/apache/karaf/system/internal/osgi/Activator.java b/system/src/main/java/org/apache/karaf/system/internal/osgi/Activator.java new file mode 100644 index 0000000..b7f8eab --- /dev/null +++ b/system/src/main/java/org/apache/karaf/system/internal/osgi/Activator.java @@ -0,0 +1,38 @@ +/* + * 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.system.internal.osgi; + +import org.apache.karaf.system.SystemService; +import org.apache.karaf.system.internal.SystemServiceImpl; +import org.apache.karaf.system.management.internal.SystemMBeanImpl; +import org.apache.karaf.util.tracker.BaseActivator; + +public class Activator extends BaseActivator { + + @Override + protected void doStart() throws Exception { + SystemServiceImpl systemService = new SystemServiceImpl(); + systemService.setBundleContext(bundleContext); + register(SystemService.class, systemService); + + SystemMBeanImpl mbean = new SystemMBeanImpl(); + mbean.setBundleContext(bundleContext); + mbean.setSystemService(systemService); + registerMBean(mbean, "type=system"); + } + +} http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/management/SystemMBean.java ---------------------------------------------------------------------- diff --git a/system/src/main/java/org/apache/karaf/system/management/SystemMBean.java b/system/src/main/java/org/apache/karaf/system/management/SystemMBean.java new file mode 100644 index 0000000..5d9bdbc --- /dev/null +++ b/system/src/main/java/org/apache/karaf/system/management/SystemMBean.java @@ -0,0 +1,157 @@ +/* + * 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.system.management; + +import javax.management.MBeanException; +import java.util.Map; + +/** + * Describe the system MBean. + */ +public interface SystemMBean { + + /** + * Stop the Karaf instance + * + * @throws Exception + */ + void halt() throws MBeanException; + + /** + * Stop the Karaf instance at a given time. + * + * @param time the time when to stop the Karaf instance. + * @throws Exception + */ + void halt(String time) throws MBeanException; + + /** + * Reboot the Karaf instance. + * + * @throws Exception + */ + void reboot() throws MBeanException; + + /** + * Reboot the Karaf instance at a given time. + * + * @param time the time when to reboot the Karaf instance. + * @throws Exception + */ + void reboot(String time) throws MBeanException; + + /** + * Reboot the Karaf instance at a given time and clean the cache. + * + * @param time the time when to reboot the Karaf instance. + * @throws Exception + */ + void rebootCleanCache(String time) throws MBeanException; + + /** + * Reboot the Karaf instance at a given time and clean all working files. + * + * @param time the time when to reboot the Karaf instance. + * @throws Exception + */ + void rebootCleanAll(String time) throws MBeanException; + + /** + * Set the system bundle start level. + * + * @param startLevel the new system bundle start level. + * @throws Exception + */ + void setStartLevel(int startLevel) throws MBeanException; + + /** + * Get the current system bundle start level. + * + * @return the current system bundle start level. + * @throws Exception + */ + int getStartLevel() throws MBeanException; + + /** + * Get the current OSGi framework in use. + * + * @return the name of the OSGi framework in use. + * @throws Exception + */ + String getFramework(); + + /** + * change OSGi framework + * + * @param framework to use. + */ + void setFramework(String framework); + + /** + * Enable or diable debgging + * @param debug enable if true + */ + void setFrameworkDebug(boolean debug); + + /** + * Get the current Karaf instance name. + * + * @return the current Karaf instance name. + */ + String getName(); + + /** + * Change Karaf instance name. + * + * @param name the new Karaf instance name. + */ + void setName(String name); + + /** + * Get the version of the current Karaf instance. + * + * @return the current Karaf instance version. + */ + String getVersion(); + + /** + * Get all system properties. + * + * @param unset if true, display the OSGi properties even if they are not defined (with "undef" value). + * @param dumpToFile if true, dump the properties into a file in the data folder. + * @return the list of system properties. + */ + Map<String, String> getProperties(boolean unset, boolean dumpToFile) throws MBeanException; + + /** + * Get the value of a given system property. + * + * @param key the system property key. + * @return the system property value. + */ + String getProperty(String key); + + /** + * Set the value of a system property. + * + * @param key the system property key. + * @param value the new system property value. + * @param persistent if true, persist the new value to the etc/system.properties file. + */ + void setProperty(String key, String value, boolean persistent); + +} http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/java/org/apache/karaf/system/management/internal/SystemMBeanImpl.java ---------------------------------------------------------------------- diff --git a/system/src/main/java/org/apache/karaf/system/management/internal/SystemMBeanImpl.java b/system/src/main/java/org/apache/karaf/system/management/internal/SystemMBeanImpl.java new file mode 100644 index 0000000..c0f34cd --- /dev/null +++ b/system/src/main/java/org/apache/karaf/system/management/internal/SystemMBeanImpl.java @@ -0,0 +1,259 @@ +/* + * 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.system.management.internal; + +import org.apache.karaf.system.FrameworkType; +import org.apache.karaf.system.SystemService; +import org.apache.karaf.system.management.SystemMBean; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; + +import javax.management.MBeanException; +import javax.management.NotCompliantMBeanException; +import javax.management.StandardMBean; +import java.io.File; +import java.io.PrintStream; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * System MBean implementation. + */ +public class SystemMBeanImpl extends StandardMBean implements SystemMBean { + + private SystemService systemService; + private BundleContext bundleContext; + + public void setBundleContext(BundleContext bundleContext) { + this.bundleContext = bundleContext; + } + + public SystemMBeanImpl() throws NotCompliantMBeanException { + super(SystemMBean.class); + } + + public void setSystemService(SystemService systemService) { + this.systemService = systemService; + } + + public SystemService getSystemService() { + return this.systemService; + } + + public void halt() throws MBeanException { + try { + systemService.halt(); + } catch (Exception e) { + throw new MBeanException(null, e.getMessage()); + } + } + + public void halt(String time) throws MBeanException { + try { + systemService.halt(time); + } catch (Exception e) { + throw new MBeanException(null, e.getMessage()); + } + } + + public void reboot() throws MBeanException { + try { + systemService.reboot(); + } catch (Exception e) { + throw new MBeanException(null, e.getMessage()); + } + } + + public void reboot(String time) throws MBeanException { + try { + systemService.reboot(time, SystemService.Swipe.NONE); + } catch (Exception e) { + throw new MBeanException(null, e.getMessage()); + } + } + + public void rebootCleanCache(String time) throws MBeanException { + try { + systemService.reboot(time, SystemService.Swipe.CACHE); + } catch (Exception e) { + throw new MBeanException(null, e.getMessage()); + } + } + + public void rebootCleanAll(String time) throws MBeanException { + try { + systemService.reboot(time, SystemService.Swipe.ALL); + } catch (Exception e) { + throw new MBeanException(null, e.getMessage()); + } + } + + public void setStartLevel(int startLevel) throws MBeanException { + try { + systemService.setStartLevel(startLevel); + } catch (Exception e) { + throw new MBeanException(null, e.getMessage()); + } + } + + public int getStartLevel() throws MBeanException { + try { + return systemService.getStartLevel(); + } catch (Exception e) { + throw new MBeanException(null, e.getMessage()); + } + } + + @Override + public String getFramework() { + return this.systemService.getFramework().toString(); + } + + @Override + public void setFramework(String framework) { + this.systemService.setFramework(FrameworkType.valueOf(framework.toLowerCase())); + } + + @Override + public void setFrameworkDebug(boolean debug) { + this.systemService.setFrameworkDebug(debug); + } + + @Override + public String getName() { + return this.systemService.getName(); + } + + @Override + public void setName(String name) { + if (name == null || name.trim().isEmpty()) { + throw new IllegalArgumentException("Instance name can't be null or empty"); + } + this.systemService.setName(name); + } + + @Override + public String getVersion() { + return this.systemService.getVersion(); + } + + @Override + public Map<String, String> getProperties(boolean unset, boolean dumpToFile) throws MBeanException { + try { + Map<String, String> result = new HashMap<String, String>(); + + Properties props = (Properties) java.lang.System.getProperties().clone(); + + String def = null; + if (unset) { + def = "unset"; + } + + setProperty(props, Constants.FRAMEWORK_BEGINNING_STARTLEVEL, def); + setProperty(props, Constants.FRAMEWORK_BOOTDELEGATION, def); + setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT, def); + setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_APP, def); + setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_BOOT, def); + setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_EXT, def); + setProperty(props, Constants.FRAMEWORK_BUNDLE_PARENT_FRAMEWORK, def); + setProperty(props, Constants.FRAMEWORK_EXECPERMISSION, def); + setProperty(props, Constants.FRAMEWORK_EXECUTIONENVIRONMENT, def); + setProperty(props, Constants.FRAMEWORK_LANGUAGE, def); + setProperty(props, Constants.FRAMEWORK_LIBRARY_EXTENSIONS, def); + setProperty(props, Constants.FRAMEWORK_OS_NAME, def); + setProperty(props, Constants.FRAMEWORK_OS_VERSION, def); + setProperty(props, Constants.FRAMEWORK_PROCESSOR, def); + setProperty(props, Constants.FRAMEWORK_SECURITY, def); + setProperty(props, Constants.FRAMEWORK_SECURITY_OSGI, def); + setProperty(props, Constants.FRAMEWORK_STORAGE, def); + setProperty(props, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT, def); + setProperty(props, Constants.FRAMEWORK_SYSTEMPACKAGES, def); + setProperty(props, Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, def); + setProperty(props, Constants.FRAMEWORK_VENDOR, def); + setProperty(props, Constants.FRAMEWORK_VERSION, def); + setProperty(props, Constants.FRAMEWORK_WINDOWSYSTEM, def); + + setProperty(props, Constants.SUPPORTS_BOOTCLASSPATH_EXTENSION, def); + setProperty(props, Constants.SUPPORTS_FRAMEWORK_EXTENSION, def); + setProperty(props, Constants.SUPPORTS_FRAMEWORK_FRAGMENT, def); + setProperty(props, Constants.SUPPORTS_FRAMEWORK_REQUIREBUNDLE, def); + + if (dumpToFile) { + PrintStream ps = new PrintStream(new File(bundleContext.getProperty("karaf.data"), "dump-properties-" + java.lang.System.currentTimeMillis() + ".properties")); + ps.println("#Dump of the System and OSGi properties"); + ps.println("#Dump executed at " + new SimpleDateFormat().format(new Date())); + printOrderedProperties(props, ps); + ps.flush(); + ps.close(); + } else { + printOrderedProperties(props, result); + } + + return result; + } catch (Exception e) { + throw new MBeanException(null, e.getMessage()); + } + } + + private void printOrderedProperties(Properties props, PrintStream out) { + Set<Object> keys = props.keySet(); + Vector<String> order = new Vector<String>(keys.size()); + for (Iterator<Object> i = keys.iterator(); i.hasNext(); ) { + Object str = (Object) i.next(); + order.add((String) str); + } + Collections.sort(order); + for (Iterator<String> i = order.iterator(); i.hasNext(); ) { + String key = (String) i.next(); + out.println(key + "=" + props.getProperty(key)); + } + } + + private void printOrderedProperties(Properties props, Map<String, String> result) { + Set<Object> keys = props.keySet(); + Vector<String> order = new Vector<String>(keys.size()); + for (Iterator<Object> i = keys.iterator(); i.hasNext(); ) { + Object str = (Object) i.next(); + order.add((String) str); + } + Collections.sort(order); + for (Iterator<String> i = order.iterator(); i.hasNext(); ) { + String key = (String) i.next(); + result.put(key, props.getProperty(key)); + } + } + + private void setProperty(Properties props, String key, String def) { + String val = bundleContext.getProperty(key); + if (val == null && def != null) { + props.setProperty(key, def); + } else if (val != null) { + props.setProperty(key, val); + } + } + + @Override + public String getProperty(String key) { + return java.lang.System.getProperty(key); + } + + @Override + public void setProperty(String key, String value, boolean persistent) { + systemService.setSystemProperty(key, value, persistent); + } + +} http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/main/resources/OSGI-INF/bundle.info ---------------------------------------------------------------------- diff --git a/system/src/main/resources/OSGI-INF/bundle.info b/system/src/main/resources/OSGI-INF/bundle.info new file mode 100644 index 0000000..acca1c8 --- /dev/null +++ b/system/src/main/resources/OSGI-INF/bundle.info @@ -0,0 +1,16 @@ +h1. Synopsis + +${project.name} + +${project.description} + +Maven URL: +[mvn:${project.groupId}/${project.artifactId}/${project.version}] + +h1. Description + +This bundle provides support of the system service, which control the Karaf container. + +h1. See also + +Shutdown - section of the Karaf User Guide http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/test/java/org/apache/karaf/system/internal/SystemServiceImplTest.java ---------------------------------------------------------------------- diff --git a/system/src/test/java/org/apache/karaf/system/internal/SystemServiceImplTest.java b/system/src/test/java/org/apache/karaf/system/internal/SystemServiceImplTest.java new file mode 100644 index 0000000..2de4e1e --- /dev/null +++ b/system/src/test/java/org/apache/karaf/system/internal/SystemServiceImplTest.java @@ -0,0 +1,53 @@ +/* +* 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.system.internal; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; + +import org.apache.felix.utils.properties.Properties; +import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Test; +import org.osgi.framework.BundleContext; + +/** + * Implementation of the system service. + */ + +public class SystemServiceImplTest { + + private static final String NEW_NAME = "newName"; + + @Test + public void testSetName() throws URISyntaxException, IOException { + SystemServiceImpl system = new SystemServiceImpl(); + BundleContext bundleContext = EasyMock.createMock(BundleContext.class); + URL propUrl = this.getClass().getClassLoader().getResource("etc/system.properties"); + File propfile = new File(propUrl.toURI()); + EasyMock.expect(bundleContext.getProperty("karaf.etc")).andReturn(propfile.getParentFile().getParent() + "/etc"); + EasyMock.replay(bundleContext); + system.setBundleContext(bundleContext); + system.setName(NEW_NAME); + EasyMock.verify(bundleContext); + Properties props = new Properties(propfile); + String nameAfter = props.getProperty("karaf.name"); + Assert.assertEquals(NEW_NAME, nameAfter); + } +} http://git-wip-us.apache.org/repos/asf/karaf/blob/0a100d76/system/src/test/resources/etc/system.properties ---------------------------------------------------------------------- diff --git a/system/src/test/resources/etc/system.properties b/system/src/test/resources/etc/system.properties new file mode 100644 index 0000000..6749fbb --- /dev/null +++ b/system/src/test/resources/etc/system.properties @@ -0,0 +1,22 @@ +################################################################################ +# +# 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. +# +################################################################################ + +#Comment +karaf.name=oldName +#Comment2