You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2014/04/10 16:15:49 UTC
[27/59] [abbrv] [KARAF-2852] Merge instance/core and instance/command
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceToTableMapperTest.java
----------------------------------------------------------------------
diff --git a/instance/core/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceToTableMapperTest.java b/instance/core/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceToTableMapperTest.java
deleted file mode 100644
index c9541d3..0000000
--- a/instance/core/src/test/java/org/apache/karaf/instance/core/management/internal/InstanceToTableMapperTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.instance.core.management.internal;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.TabularData;
-
-import junit.framework.TestCase;
-
-import org.apache.karaf.instance.core.Instance;
-import org.apache.karaf.instance.core.internal.InstanceToTableMapper;
-import org.easymock.EasyMock;
-import org.junit.Assert;
-
-public class InstanceToTableMapperTest extends TestCase {
- public void testJMXInstance() throws Exception {
- Instance instance = EasyMock.createMock(Instance.class);
- EasyMock.expect(instance.getPid()).andReturn(1712);
- EasyMock.expect(instance.getName()).andReturn("MyInstance");
- EasyMock.expect(instance.isRoot()).andReturn(false);
- EasyMock.expect(instance.getSshPort()).andReturn(0);
- EasyMock.expect(instance.getRmiRegistryPort()).andReturn(0);
- EasyMock.expect(instance.getRmiServerPort()).andReturn(0);
- EasyMock.expect(instance.getState()).andThrow(new Exception("gotcha"));
- EasyMock.expect(instance.getLocation()).andReturn("somewhere");
- EasyMock.expect(instance.getJavaOpts()).andReturn("someopts");
- EasyMock.replay(instance);
-
- TabularData td = InstanceToTableMapper.tableFrom(Collections.singletonList(instance));
- Collection<?> keys = (Collection<?>) td.keySet().iterator().next();
- Assert.assertEquals("MyInstance", keys.iterator().next());
-
- CompositeData cd = td.get(keys.toArray());
- Assert.assertEquals(1712, cd.get("Pid"));
- Assert.assertEquals("MyInstance", cd.get("Name"));
- Assert.assertEquals(false, cd.get("Is Root"));
- Assert.assertEquals(0, cd.get("SSH Port"));
- Assert.assertEquals(0, cd.get("RMI Registry Port"));
- Assert.assertEquals(0, cd.get("RMI Server Port"));
- Assert.assertEquals("Error", cd.get("State"));
- Assert.assertEquals("somewhere", cd.get("Location"));
- Assert.assertEquals("someopts", cd.get("JavaOpts"));
- }
-
- public void testJMXInstance2() throws Exception {
- Instance instance = EasyMock.createMock(Instance.class);
- EasyMock.expect(instance.getPid()).andReturn(1712);
- EasyMock.expect(instance.getName()).andReturn("MyInstance");
- EasyMock.expect(instance.isRoot()).andReturn(true);
- EasyMock.expect(instance.getSshPort()).andReturn(0);
- EasyMock.expect(instance.getRmiRegistryPort()).andReturn(0);
- EasyMock.expect(instance.getRmiServerPort()).andReturn(0);
- EasyMock.expect(instance.getState()).andReturn("Started");
- EasyMock.expect(instance.getLocation()).andReturn(null);
- EasyMock.expect(instance.getJavaOpts()).andReturn(null);
- EasyMock.replay(instance);
-
- TabularData td = InstanceToTableMapper.tableFrom(Collections.singletonList(instance));
- Collection<?> keys = (Collection<?>) td.keySet().iterator().next();
- Assert.assertEquals("MyInstance", keys.iterator().next());
-
- CompositeData cd = td.get(keys.toArray());
- Assert.assertEquals(1712, cd.get("Pid"));
- Assert.assertEquals("MyInstance", cd.get("Name"));
- Assert.assertEquals(true, cd.get("Is Root"));
- Assert.assertEquals(0, cd.get("SSH Port"));
- Assert.assertEquals(0, cd.get("RMI Registry Port"));
- Assert.assertEquals(0, cd.get("RMI Server Port"));
- Assert.assertEquals("Started", cd.get("State"));
- Assert.assertNull(cd.get("Location"));
- Assert.assertNull(cd.get("JavaOpts"));
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/test/java/org/apache/karaf/jpm/MainTest.java
----------------------------------------------------------------------
diff --git a/instance/core/src/test/java/org/apache/karaf/jpm/MainTest.java b/instance/core/src/test/java/org/apache/karaf/jpm/MainTest.java
deleted file mode 100644
index e7f7c83..0000000
--- a/instance/core/src/test/java/org/apache/karaf/jpm/MainTest.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.jpm;
-
-public class MainTest {
-
- public static void main(String[] args) throws Exception {
- Thread.sleep(Long.parseLong(args[0]));
- }
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/test/java/org/apache/karaf/jpm/ProcessTest.java
----------------------------------------------------------------------
diff --git a/instance/core/src/test/java/org/apache/karaf/jpm/ProcessTest.java b/instance/core/src/test/java/org/apache/karaf/jpm/ProcessTest.java
deleted file mode 100644
index 9cdc5ad..0000000
--- a/instance/core/src/test/java/org/apache/karaf/jpm/ProcessTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.jpm;
-
-import java.io.File;
-
-import junit.framework.TestCase;
-
-import org.apache.karaf.jpm.impl.ProcessBuilderFactoryImpl;
-import org.apache.karaf.jpm.impl.ScriptUtils;
-
-public class ProcessTest extends TestCase {
-
- public void testCreate() throws Exception {
- String javaPath = new File(System.getProperty("java.home"), ScriptUtils.isWindows() ? "bin\\java.exe" : "bin/java").getCanonicalPath();
- System.err.println(javaPath);
- StringBuilder command = new StringBuilder();
- command.append("\"").append(javaPath).append("\"");
- command.append(" -Dprop=\"key\"");
- command.append(" -classpath ");
- String clRes = getClass().getName().replace('.', '/') + ".class";
- String str = getClass().getClassLoader().getResource(clRes).toString();
- str = str.substring("file:".length(), str.indexOf(clRes));
- command.append(str);
- command.append(" ");
- command.append(MainTest.class.getName());
- command.append(" ");
- command.append(60000);
- System.err.println("Executing: " + command.toString());
-
- ProcessBuilder builder = new ProcessBuilderFactoryImpl().newBuilder();
- org.apache.karaf.jpm.Process p = builder.command(command.toString()).start();
- assertNotNull(p);
- System.err.println("Process: " + p.getPid());
- assertNotNull(p.getPid());
- Thread.sleep(1000);
- System.err.println("Running: " + p.isRunning());
- assertTrue(p.isRunning());
- System.err.println("Destroying");
- p.destroy();
- Thread.sleep(1000);
- System.err.println("Running: " + p.isRunning());
- assertFalse(p.isRunning());
- }
-
- /*
- * When the process creation fails, no error is reported by the script
- *
- public void testFailure() throws Exception {
- ProcessBuilder builder = ProcessBuilderFactory.newInstance().newBuilder();
- Process p = builder.command("ec").start();
- fail("An exception should have been thrown");
- }
- */
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/core/src/test/resources/etc/startup.properties
----------------------------------------------------------------------
diff --git a/instance/core/src/test/resources/etc/startup.properties b/instance/core/src/test/resources/etc/startup.properties
deleted file mode 100644
index df7c9bc..0000000
--- a/instance/core/src/test/resources/etc/startup.properties
+++ /dev/null
@@ -1,20 +0,0 @@
-################################################################################
-#
-# 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.
-#
-################################################################################
-
-# Fake startup.properties for unit tests as the startup properties in generated by the karaf-maven-plugin
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/pom.xml
----------------------------------------------------------------------
diff --git a/instance/pom.xml b/instance/pom.xml
index c6c1930..baeb2f9 100644
--- a/instance/pom.xml
+++ b/instance/pom.xml
@@ -10,7 +10,7 @@
(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
+ 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,
@@ -29,13 +29,172 @@
</parent>
<groupId>org.apache.karaf.instance</groupId>
- <artifactId>instance</artifactId>
- <packaging>pom</packaging>
- <name>Apache Karaf :: Instance</name>
+ <artifactId>org.apache.karaf.instance.core</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Karaf :: Instance :: Core</name>
+ <description>Core implementation of the instance feature to manipulate Karaf child instances.</description>
- <modules>
- <module>core</module>
- <module>command</module>
- </modules>
+ <properties>
+ <appendedResourcesDirectory>${project.basedir}/../../etc/appended-resources</appendedResourcesDirectory>
+ </properties>
+ <dependencies>
+
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.utils</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.karaf</groupId>
+ <artifactId>org.apache.karaf.util</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.karaf.features</groupId>
+ <artifactId>org.apache.karaf.features.core</artifactId>
+ <optional>true</optional>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-jdk14</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>${project.basedir}/src/main/resources</directory>
+ <includes>
+ <include>**/*</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>${project.basedir}/src/main/resources</directory>
+ <filtering>true</filtering>
+ <includes>
+ <include>**/*.info</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>${project.build.directory}/generated-resources</directory>
+ <includes>
+ <include>**/*.*</include>
+ </includes>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.build.directory}/generated-resources/org/apache/karaf/instance/</outputDirectory>
+ <resources>
+ <resource>
+ <directory>${project.basedir}/../assemblies/features/framework/src/main/resources</directory>
+ <excludes>
+ <exclude>**/org.apache.karaf.management.cfg</exclude>
+ <exclude>**/org.apache.karaf.shell.cfg</exclude>
+ <exclude>**/system.properties</exclude>
+ </excludes>
+ </resource>
+ <resource>
+ <directory>${project.basedir}/../assemblies/features/framework/src/main/filtered-resources</directory>
+ <filtering>true</filtering>
+ <includes>
+ <include>**/*.properties</include>
+ <include>**/*.cfg</include>
+ <include>**/*.xml</include>
+ <include>**/*.info</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>${project.basedir}/../assemblies/features/framework/src/main/snapshot</directory>
+ <filtering>true</filtering>
+ <includes>
+ <include>**/*.cfg</include>
+ </includes>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.apache.karaf.instance.core
+ </Export-Package>
+ <!-- We have to avoid importing instance.core.internal and jansi
+ as Execute.java accesses the InstanceServiceImpl and jansi
+ (but only outside OSGi) -->
+ <Import-Package>
+ !org.apache.karaf.shell.impl.action.command,
+ !org.apache.karaf.instance.core.internal,
+ *
+ </Import-Package>
+ <Provide-Capability>
+ service-reference;effective:=active;objectClass=org.apache.karaf.instance.core.InstanceService
+ </Provide-Capability>
+ <Private-Package>
+ org.apache.karaf.jpm,
+ org.apache.karaf.jpm.impl,
+ org.apache.karaf.instance.main,
+ org.apache.karaf.instance.command,
+ org.apache.karaf.instance.command.completers,
+ org.apache.karaf.instance.core.internal,
+ org.apache.karaf.instance.core.internal.osgi,
+ org.apache.felix.utils.properties;-split-package:=merge-first,
+ org.apache.karaf.util.locks,
+ org.apache.karaf.util.tracker
+ </Private-Package>
+ <Bundle-Activator>
+ org.apache.karaf.instance.core.internal.osgi.Activator
+ </Bundle-Activator>
+ <Karaf-Commands>org.apache.karaf.instance.command.*</Karaf-Commands>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <!-- this is not a unit test but an application used for testing -->
+ <exclude>**/MainTest.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/ChangeOptsCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/ChangeOptsCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/ChangeOptsCommand.java
new file mode 100644
index 0000000..c526c07
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/ChangeOptsCommand.java
@@ -0,0 +1,41 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "instance", name = "opts-change", description = "Changes the Java options of an existing container instance.")
+@Service
+public class ChangeOptsCommand extends InstanceCommandSupport {
+
+ @Argument(index = 0, name = "name", description="The name of the container instance", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ private String instance = null;
+
+ @Argument(index = 1, name = "javaOpts", description = "The new Java options to set", required = true, multiValued = false)
+ private String javaOpts;
+
+ protected Object doExecute() throws Exception {
+ getExistingInstance(instance).changeJavaOpts(javaOpts);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/ChangeRmiRegistryPortCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/ChangeRmiRegistryPortCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/ChangeRmiRegistryPortCommand.java
new file mode 100644
index 0000000..de5bfaf
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/ChangeRmiRegistryPortCommand.java
@@ -0,0 +1,41 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "instance", name = "rmi-registry-port-change", description = "Changes the RMI registry port (used by management layer) of an existing container instance.")
+@Service
+public class ChangeRmiRegistryPortCommand extends InstanceCommandSupport {
+
+ @Argument(index = 0, name = "name", description = "The name of the container instance", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ private String instance = null;
+
+ @Argument(index = 1, name = "port", description = "The new RMI registry port to set", required = true, multiValued = false)
+ private int port = 0;
+
+ protected Object doExecute() throws Exception {
+ getExistingInstance(instance).changeRmiRegistryPort(port);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/ChangeRmiServerPortCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/ChangeRmiServerPortCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/ChangeRmiServerPortCommand.java
new file mode 100644
index 0000000..0ac2cf7
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/ChangeRmiServerPortCommand.java
@@ -0,0 +1,41 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "instance", name = "rmi-server-port-change", description = "Changes the RMI server port (used by management layer) of an existing instance.")
+@Service
+public class ChangeRmiServerPortCommand extends InstanceCommandSupport {
+
+ @Argument(index = 0, name = "name", description = "The name of the container instance", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ private String instance = null;
+
+ @Argument(index = 1, name = "port", description = "The new RMI server port to set", required = true, multiValued = false)
+ private int port = 0;
+
+ protected Object doExecute() throws Exception {
+ getExistingInstance(instance).changeRmiServerPort(port);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/ChangeSshPortCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/ChangeSshPortCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/ChangeSshPortCommand.java
new file mode 100644
index 0000000..17ad26c
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/ChangeSshPortCommand.java
@@ -0,0 +1,41 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "instance", name = "ssh-port-change", description = "Changes the secure shell port of an existing container instance.")
+@Service
+public class ChangeSshPortCommand extends InstanceCommandSupport {
+
+ @Argument(index = 0, name = "name", description="The name of the container instance", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ private String instance = null;
+
+ @Argument(index = 1, name = "port", description = "The new secure shell port to set", required = true, multiValued = false)
+ private int port = 0;
+
+ protected Object doExecute() throws Exception {
+ getExistingInstance(instance).changeSshPort(port);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/CloneCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/CloneCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/CloneCommand.java
new file mode 100644
index 0000000..e4f28c5
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/CloneCommand.java
@@ -0,0 +1,66 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+import org.apache.karaf.instance.core.InstanceSettings;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+/**
+ * Clone an existing instance.
+ */
+@Command(scope = "instance", name = "clone", description = "Clones an existing container instance.")
+@Service
+public class CloneCommand extends InstanceCommandSupport {
+
+ @Option(name = "-s", aliases = {"--ssh-port"}, description = "Port number for remote secure shell connection", required = false, multiValued = false)
+ int sshPort = 0;
+
+ @Option(name = "-r", aliases = {"-rr", "--rmi-port", "--rmi-registry-port"}, description = "Port number for RMI registry connection", required = false, multiValued = false)
+ int rmiRegistryPort = 0;
+
+ @Option(name = "-rs", aliases = {"--rmi-server-port"}, description = "Port number for RMI server connection", required = false, multiValued = false)
+ int rmiServerPort = 0;
+
+ @Option(name = "-l", aliases = {"--location"}, description = "Location of the cloned container instance in the file system", required = false, multiValued = false)
+ String location;
+
+ @Option(name = "-o", aliases = {"--java-opts"}, description = "JVM options to use when launching the cloned instance", required = false, multiValued = false)
+ String javaOpts;
+
+ @Option(name = "-v", aliases = {"--verbose"}, description = "Display actions performed by the command (disabled by default)", required = false, multiValued = false)
+ boolean verbose = false;
+
+ @Argument(index = 0, name = "name", description = "The name of the source container instance", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ String name;
+
+ @Argument(index = 1, name = "cloneName", description = "The name of the cloned container instance", required = true, multiValued = false)
+ String cloneName;
+
+
+ protected Object doExecute() throws Exception {
+ InstanceSettings settings = new InstanceSettings(sshPort, rmiRegistryPort, rmiServerPort, location, javaOpts, null, null);
+ getInstanceService().cloneInstance(name, cloneName, settings, verbose);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/ConnectCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/ConnectCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/ConnectCommand.java
new file mode 100644
index 0000000..c81a3eb
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/ConnectCommand.java
@@ -0,0 +1,78 @@
+/*
+ * 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.instance.command;
+
+import java.util.List;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+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;
+
+@Command(scope = "instance", name = "connect", description = "Connects to an existing container instance.")
+@Service
+public class ConnectCommand extends InstanceCommandSupport {
+
+ @Option(name="-u", aliases={"--username"}, description="Remote user name", required = false, multiValued = false)
+ private String username;
+
+ @Option(name = "-p", aliases = {"--password"}, description = "Remote password", required = false, multiValued = false)
+ private String password;
+
+ @Argument(index = 0, name="name", description="The name of the container instance", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ private String instance = null;
+
+ @Argument(index = 1, name = "command", description = "Optional command to execute", required = false, multiValued = true)
+ private List<String> command;
+
+ @Reference
+ Session session;
+
+ protected Object doExecute() throws Exception {
+ String cmdStr = "";
+ if (command != null) {
+ StringBuilder sb = new StringBuilder();
+ for (String cmd : command) {
+ if (sb.length() > 0) {
+ sb.append(' ');
+ }
+ sb.append(cmd);
+ }
+ cmdStr = "'" + sb.toString().replaceAll("'", "\\'") + "'";
+ }
+
+ int port = getExistingInstance(instance).getSshPort();
+ if (username != null) {
+ if (password == null) {
+ session.execute("ssh:ssh -q -l " + username + " -p " + port + " localhost " + cmdStr);
+ } else {
+ session.execute("ssh:ssh -q -l " + username + " -P " + password + " -p " + port + " localhost " + cmdStr);
+ }
+ } else {
+ session.execute("ssh:ssh -q -p " + port + " localhost " + cmdStr);
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/CreateCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/CreateCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/CreateCommand.java
new file mode 100644
index 0000000..0dcc3ac
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/CreateCommand.java
@@ -0,0 +1,74 @@
+/*
+ * 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.instance.command;
+
+import java.util.List;
+
+import org.apache.karaf.features.command.completers.AllFeatureCompleter;
+import org.apache.karaf.features.command.completers.InstalledRepoUriCompleter;
+import org.apache.karaf.instance.core.InstanceSettings;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+/**
+ * Creates a new instance.
+ */
+@Command(scope = "instance", name = "create", description = "Creates a new container instance.")
+@Service
+public class CreateCommand extends InstanceCommandSupport
+{
+ @Option(name = "-s", aliases = {"--ssh-port"}, description = "Port number for remote secure shell connection", required = false, multiValued = false)
+ int sshPort = 0;
+
+ @Option(name = "-r", aliases = {"-rr", "--rmi-port", "--rmi-registry-port"}, description = "Port number for RMI registry connection", required = false, multiValued = false)
+ int rmiRegistryPort = 0;
+
+ @Option(name = "-rs", aliases = {"--rmi-server-port"}, description = "Port number for RMI server connection", required = false, multiValued = false)
+ int rmiServerPort = 0;
+
+ @Option(name = "-l", aliases = {"--location"}, description = "Location of the new container instance in the file system", required = false, multiValued = false)
+ String location;
+
+ @Option(name = "-o", aliases = {"--java-opts"}, description = "JVM options to use when launching the instance", required = false, multiValued = false)
+ String javaOpts;
+
+ @Option(name = "-f", aliases = {"--feature"},
+ description = "Initial features. This option can be specified multiple times to enable multiple initial features", required = false, multiValued = true)
+ @Completion(AllFeatureCompleter.class)
+ List<String> features;
+
+ @Option(name = "-furl", aliases = {"--featureURL"},
+ description = "Additional feature descriptor URLs. This option can be specified multiple times to add multiple URLs", required = false, multiValued = true)
+ @Completion(InstalledRepoUriCompleter.class)
+ List<String> featureURLs;
+
+ @Option(name = "-v", aliases = {"--verbose"}, description = "Display actions performed by the command (disabled by default)", required = false, multiValued = false)
+ boolean verbose = false;
+
+ @Argument(index = 0, name = "name", description="The name of the new container instance", required = true, multiValued = false)
+ String instance = null;
+
+ protected Object doExecute() throws Exception {
+ InstanceSettings settings = new InstanceSettings(sshPort, rmiRegistryPort, rmiServerPort, location, javaOpts, featureURLs, features);
+ getInstanceService().createInstance(instance, settings, verbose);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/DestroyCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/DestroyCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/DestroyCommand.java
new file mode 100644
index 0000000..fb2964f
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/DestroyCommand.java
@@ -0,0 +1,41 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+/**
+ * Destroy an existing instance.
+ */
+@Command(scope = "instance", name = "destroy", description = "Destroys an existing container instance.")
+@Service
+public class DestroyCommand extends InstanceCommandSupport
+{
+ @Argument(index = 0, name = "name", description= "The name of the container instance to destroy", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ private String instance = null;
+
+ protected Object doExecute() throws Exception {
+ getExistingInstance(instance).destroy();
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/InstanceCommandSupport.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/InstanceCommandSupport.java b/instance/src/main/java/org/apache/karaf/instance/command/InstanceCommandSupport.java
new file mode 100644
index 0000000..3b0b535
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/InstanceCommandSupport.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.instance.command;
+
+import org.apache.karaf.instance.core.Instance;
+import org.apache.karaf.instance.core.InstanceService;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+
+public abstract class InstanceCommandSupport implements Action {
+
+ @Reference
+ private InstanceService instanceService;
+
+ public InstanceService getInstanceService() {
+ return instanceService;
+ }
+
+ public void setInstanceService(InstanceService instanceService) {
+ this.instanceService = instanceService;
+ }
+
+ protected Instance getExistingInstance(String name) {
+ Instance i = instanceService.getInstance(name);
+ if (i == null) {
+ throw new IllegalArgumentException("Instances '" + name + "' does not exist");
+ }
+ return i;
+ }
+
+ @Override
+ public Object execute() throws Exception {
+ return doExecute();
+ }
+
+ protected abstract Object doExecute() throws Exception;
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/ListCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/ListCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/ListCommand.java
new file mode 100644
index 0000000..fe571a8
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/ListCommand.java
@@ -0,0 +1,81 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.core.Instance;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.table.ShellTable;
+
+@Command(scope = "instance", name = "list", description = "Lists all existing container instances.")
+@Service
+public class ListCommand extends InstanceCommandSupport {
+
+ @Option(name = "-l", aliases = { "--location" }, description = "Displays the location of the container instances", required = false, multiValued = false)
+ boolean location;
+
+ @Option(name = "-o", aliases = { "--java-opts" }, description = "Displays the Java options used to launch the JVM", required = false, multiValued = false)
+ boolean javaOpts;
+
+ @Option(name = "--no-color", description = "Disable table rendered output", required = false, multiValued = false)
+ boolean noFormat;
+
+ protected Object doExecute() throws Exception {
+ getInstanceService().refreshInstance();
+ Instance[] instances = getInstanceService().getInstances();
+ ShellTable table = new ShellTable();
+ table.column("SSH Port").alignRight();
+ table.column("RMI Registry").alignRight();
+ table.column("RMI Server").alignRight();
+ table.column("State");
+ table.column("PID");
+ table.column(getRightColumnHeader());
+ for (Instance instance : instances) {
+ table.addRow().addContent(
+ instance.getSshPort(),
+ instance.getRmiRegistryPort(),
+ instance.getRmiServerPort(),
+ instance.getState(),
+ instance.getPid(),
+ getRightColumnValue(instance));
+ }
+ table.print(System.out, !noFormat);
+ return null;
+ }
+
+ private String getRightColumnHeader() {
+ if (javaOpts) {
+ return "JavaOpts";
+ } else if (location) {
+ return "Location";
+ } else {
+ return "Name";
+ }
+ }
+
+ private String getRightColumnValue(Instance instance) {
+ if (javaOpts) {
+ return instance.getJavaOpts();
+ } else if (location) {
+ return instance.getLocation();
+ } else {
+ return instance.getName();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/RenameCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/RenameCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/RenameCommand.java
new file mode 100644
index 0000000..ef68400
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/RenameCommand.java
@@ -0,0 +1,45 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "instance", name = "rename", description = "Rename an existing container instance.")
+@Service
+public class RenameCommand extends InstanceCommandSupport {
+
+ @Option(name = "-v", aliases = {"--verbose"}, description = "Display actions performed by the command (disabled by default)", required = false, multiValued = false)
+ boolean verbose = false;
+
+ @Argument(index = 0, name = "name", description = "The name of the container instance to rename", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ String instance = null;
+
+ @Argument(index = 1, name = "new-name", description = "The new name of the container instance", required = true, multiValued = false)
+ String newName = null;
+
+ protected Object doExecute() throws Exception {
+ getInstanceService().renameInstance(instance, newName, verbose);
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/StartCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/StartCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/StartCommand.java
new file mode 100644
index 0000000..8c52d5e
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/StartCommand.java
@@ -0,0 +1,76 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+import org.apache.karaf.instance.core.Instance;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "instance", name = "start", description = "Start an existing container instance.")
+@Service
+public class StartCommand extends InstanceCommandSupport {
+
+ @Option(name = "-d", aliases = { "--debug"}, description = "Start the instance in debug mode", required = false, multiValued = false)
+ private boolean debug;
+
+ @Option(name = "-o", aliases = { "--java-opts"}, description = "Java options when launching the instance", required = false, multiValued = false)
+ private String javaOpts;
+
+ @Option(name = "-w", aliases = { "--wait"}, description = "Wait for the instance to be fully started", required = false, multiValued = false)
+ private boolean wait;
+
+ @Argument(index = 0, name = "name", description = "The name of the container instance", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ private String instance = null;
+
+ static final String DEBUG_OPTS = " -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005";
+ static final String DEFAULT_OPTS = "-server -Xmx512M -Dcom.sun.management.jmxremote";
+
+ protected Object doExecute() throws Exception {
+ Instance child = getExistingInstance(instance);
+ String opts = javaOpts;
+ if (opts == null) {
+ opts = child.getJavaOpts();
+ }
+ if (opts == null) {
+ opts = DEFAULT_OPTS;
+ }
+ if (debug) {
+ opts += DEBUG_OPTS;
+ }
+ if (wait) {
+ String state = child.getState();
+ if (Instance.STOPPED.equals(state)) {
+ child.start(opts);
+ }
+ if (!Instance.STARTED.equals(state)) {
+ do {
+ Thread.sleep(500);
+ state = child.getState();
+ } while (Instance.STARTING.equals(state));
+ }
+ } else {
+ child.start(opts);
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/StatusCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/StatusCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/StatusCommand.java
new file mode 100644
index 0000000..82100e1
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/StatusCommand.java
@@ -0,0 +1,40 @@
+/*
+ * 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.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+import org.apache.karaf.instance.core.Instance;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "instance", name = "status", description = "Check the current status of an instance.")
+@Service
+public class StatusCommand extends InstanceCommandSupport {
+
+ @Argument(index = 0, name = "name", description = "The name of the instance", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ private String name;
+
+ protected Object doExecute() throws Exception {
+ Instance instance = getExistingInstance(name);
+ System.out.println(instance.getState());
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/StopCommand.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/StopCommand.java b/instance/src/main/java/org/apache/karaf/instance/command/StopCommand.java
new file mode 100644
index 0000000..6c8de10
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/StopCommand.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.instance.command;
+
+import org.apache.karaf.instance.command.completers.InstanceCompleter;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "instance", name = "stop", description = "Stop an existing container instance.")
+@Service
+public class StopCommand extends InstanceCommandSupport {
+
+ @Argument(index = 0, name = "name", description = "The name of the container instance", required = true, multiValued = false)
+ @Completion(InstanceCompleter.class)
+ private String instance = null;
+
+ protected Object doExecute() throws Exception {
+ getExistingInstance(instance).stop();
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/command/completers/InstanceCompleter.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/command/completers/InstanceCompleter.java b/instance/src/main/java/org/apache/karaf/instance/command/completers/InstanceCompleter.java
new file mode 100644
index 0000000..4468374
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/command/completers/InstanceCompleter.java
@@ -0,0 +1,52 @@
+/*
+ * 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.instance.command.completers;
+
+import java.util.List;
+
+import org.apache.karaf.instance.core.Instance;
+import org.apache.karaf.instance.core.InstanceService;
+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.CommandLine;
+import org.apache.karaf.shell.api.console.Completer;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.support.completers.StringsCompleter;
+
+/**
+ * Displays a list of configured server instances for the instance commands.
+ *
+ */
+@Service
+public class InstanceCompleter implements Completer {
+
+ @Reference
+ private InstanceService instanceService;
+
+ public void setInstanceService(InstanceService instanceService) {
+ this.instanceService = instanceService;
+ }
+
+ public int complete(Session session, CommandLine commandLine, List<String> candidates) {
+ StringsCompleter delegate = new StringsCompleter();
+ for (Instance instance : instanceService.getInstances()) {
+ delegate.getStrings().add(instance.getName());
+ }
+ return delegate.complete(session, commandLine, candidates);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/core/Instance.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/core/Instance.java b/instance/src/main/java/org/apache/karaf/instance/core/Instance.java
new file mode 100644
index 0000000..5e78bb2
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/core/Instance.java
@@ -0,0 +1,66 @@
+/*
+ * 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.instance.core;
+
+public interface Instance {
+
+ String STOPPED = "Stopped";
+ String STARTING = "Starting";
+ String STARTED = "Started";
+ String ERROR = "Error";
+
+ String getName();
+
+ @Deprecated
+ void setName(String name);
+
+ boolean isRoot();
+
+ String getLocation();
+
+ @Deprecated
+ void setLocation(String location);
+
+ int getPid();
+
+ int getSshPort();
+
+ void changeSshPort(int port) throws Exception;
+
+ int getRmiRegistryPort();
+
+ void changeRmiRegistryPort(int port) throws Exception;
+
+ int getRmiServerPort();
+
+ void changeRmiServerPort(int port) throws Exception;
+
+ String getJavaOpts();
+
+ void changeJavaOpts(String javaOpts) throws Exception;
+
+ void start(String javaOpts) throws Exception;
+
+ void stop() throws Exception;
+
+ void destroy() throws Exception;
+
+ String getState() throws Exception;
+
+ @Deprecated
+ boolean isAttached();
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/core/InstanceService.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/core/InstanceService.java b/instance/src/main/java/org/apache/karaf/instance/core/InstanceService.java
new file mode 100644
index 0000000..cc6c10c
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/core/InstanceService.java
@@ -0,0 +1,33 @@
+/*
+ * 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.instance.core;
+
+public interface InstanceService {
+
+ Instance createInstance(String name, InstanceSettings settings, boolean printOutput) throws Exception;
+
+ void renameInstance(String name, String newName, boolean printOutput) throws Exception;
+
+ @Deprecated
+ void refreshInstance() throws Exception;
+
+ Instance cloneInstance(String name, String cloneName, InstanceSettings settings, boolean printOutput) throws Exception;
+
+ Instance[] getInstances();
+
+ Instance getInstance(String name);
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/core/InstanceSettings.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/core/InstanceSettings.java b/instance/src/main/java/org/apache/karaf/instance/core/InstanceSettings.java
new file mode 100644
index 0000000..0f9cf97
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/core/InstanceSettings.java
@@ -0,0 +1,97 @@
+/*
+ * 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.instance.core;
+
+import java.util.List;
+
+public class InstanceSettings {
+
+ private final int sshPort;
+ private final int rmiRegistryPort;
+ private final int rmiServerPort;
+ private final String location;
+ private final String javaOpts;
+ private final List<String> featureURLs;
+ private final List<String> features;
+
+ public InstanceSettings(int sshPort, int rmiRegistryPort, int rmiServerPort, String location, String javaOpts, List<String> featureURLs, List<String> features) {
+ this.sshPort = sshPort;
+ this.rmiRegistryPort = rmiRegistryPort;
+ this.rmiServerPort = rmiServerPort;
+ this.location = location;
+ this.javaOpts = javaOpts;
+ this.featureURLs = featureURLs;
+ this.features = features;
+ }
+
+ public int getSshPort() {
+ return sshPort;
+ }
+
+ public int getRmiRegistryPort() {
+ return rmiRegistryPort;
+ }
+
+ public int getRmiServerPort() {
+ return rmiServerPort;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public String getJavaOpts() {
+ return javaOpts;
+ }
+
+ public List<String> getFeatureURLs() {
+ return featureURLs;
+ }
+
+ public List<String> getFeatures() {
+ return features;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof InstanceSettings)) {
+ return false;
+ }
+ InstanceSettings is = (InstanceSettings) o;
+ return is.sshPort == sshPort &&
+ is.rmiRegistryPort == rmiRegistryPort &&
+ is.rmiServerPort == rmiServerPort &&
+ (location == null ? is.location == null : location.equals(is.location)) &&
+ (javaOpts == null ? is.javaOpts == null : javaOpts.equals(is.javaOpts)) &&
+ (featureURLs == null ? is.featureURLs == null : featureURLs.equals(is.featureURLs)) &&
+ (features == null ? is.features == null : features.equals(is.features));
+ }
+
+ @Override
+ public int hashCode() {
+ int result = sshPort + rmiRegistryPort + rmiServerPort;
+ result = 31 * result + (location != null ? location.hashCode() : 0);
+ result = 31 * result + (javaOpts != null ? javaOpts.hashCode() : 0);
+ result = 31 * result + (featureURLs != null ? featureURLs.hashCode() : 0);
+ result = 31 * result + (features != null ? features.hashCode() : 0);
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/core/InstancesMBean.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/core/InstancesMBean.java b/instance/src/main/java/org/apache/karaf/instance/core/InstancesMBean.java
new file mode 100644
index 0000000..f75e099
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/core/InstancesMBean.java
@@ -0,0 +1,55 @@
+/*
+ * 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.instance.core;
+
+import javax.management.MBeanException;
+import javax.management.openmbean.TabularData;
+
+public interface InstancesMBean {
+
+ String INSTANCE_PID = "Pid";
+ String INSTANCE_NAME = "Name";
+ String INSTANCE_IS_ROOT = "Is Root";
+ String INSTANCE_SSH_PORT = "SSH Port";
+ String INSTANCE_RMI_REGISTRY_PORT = "RMI Registry Port";
+ String INSTANCE_RMI_SERVER_PORT = "RMI Server Port";
+ String INSTANCE_STATE = "State";
+ String INSTANCE_LOCATION = "Location";
+ String INSTANCE_JAVAOPTS = "JavaOpts";
+
+ String[] INSTANCE = {INSTANCE_PID, INSTANCE_NAME, INSTANCE_IS_ROOT, INSTANCE_SSH_PORT, INSTANCE_RMI_REGISTRY_PORT,
+ INSTANCE_RMI_SERVER_PORT, INSTANCE_STATE, INSTANCE_LOCATION, INSTANCE_JAVAOPTS };
+
+ // Operations
+ int createInstance(String name, int sshPort, int rmiRegistryPort, int rmiServerPort, String location, String javaOpts, String features, String featureURLs) throws MBeanException;
+ void changeSshPort(String name, int port) throws MBeanException;
+ void changeRmiRegistryPort(String name, int port) throws MBeanException;
+ void changeRmiServerPort(String name, int port) throws MBeanException;
+ void changeJavaOpts(String name, String javaopts) throws MBeanException;
+ void destroyInstance(String name) throws MBeanException;
+ void startInstance(String name) throws MBeanException;
+ void startInstance(String name, String opts) throws MBeanException;
+ void startInstance(String name, String opts, boolean wait, boolean debug) throws MBeanException;
+ void stopInstance(String name) throws MBeanException;
+ void renameInstance(String originalName, String newName) throws MBeanException;
+ void renameInstance(String originalName, String newName, boolean verbose) throws MBeanException;
+ void cloneInstance(String name, String cloneName, int sshPort, int rmiRegistryPort, int rmiServerPort, String location, String javaOpts) throws MBeanException;
+
+ // Attributes
+ TabularData getInstances() throws MBeanException;
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/7c2db062/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceImpl.java
----------------------------------------------------------------------
diff --git a/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceImpl.java b/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceImpl.java
new file mode 100644
index 0000000..edc4ec5
--- /dev/null
+++ b/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceImpl.java
@@ -0,0 +1,110 @@
+/*
+ * 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.instance.core.internal;
+
+import org.apache.karaf.instance.core.Instance;
+
+public class InstanceImpl implements Instance {
+
+ private final InstanceServiceImpl service;
+ private String name;
+
+ public InstanceImpl(InstanceServiceImpl service, String name) {
+ this.service = service;
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ void doSetName(String name) {
+ this.name = name;
+ }
+
+ public boolean isRoot() {
+ return service.isInstanceRoot(name);
+ }
+
+ public String getLocation() {
+ return service.getInstanceLocation(name);
+ }
+
+ public void setLocation(String location) {
+ throw new UnsupportedOperationException();
+ }
+
+ public int getPid() {
+ return service.getInstancePid(name);
+ }
+
+ public int getSshPort() {
+ return service.getInstanceSshPort(name);
+ }
+
+ public void changeSshPort(int port) throws Exception {
+ service.changeInstanceSshPort(name, port);
+ }
+
+ public int getRmiRegistryPort() {
+ return service.getInstanceRmiRegistryPort(name);
+ }
+
+ public void changeRmiRegistryPort(int port) throws Exception {
+ service.changeInstanceRmiRegistryPort(name, port);
+ }
+
+ public int getRmiServerPort() {
+ return service.getInstanceRmiServerPort(name);
+ }
+
+ public void changeRmiServerPort(int port) throws Exception {
+ service.changeInstanceRmiServerPort(name, port);
+ }
+
+ public String getJavaOpts() {
+ return service.getInstanceJavaOpts(name);
+ }
+
+ public void changeJavaOpts(String javaOpts) throws Exception {
+ service.changeInstanceJavaOpts(name, javaOpts);
+ }
+
+ public void start(String javaOpts) throws Exception {
+ service.startInstance(name, javaOpts);
+ }
+
+ public void stop() throws Exception {
+ service.stopInstance(name);
+ }
+
+ public void destroy() throws Exception {
+ service.destroyInstance(name);
+ }
+
+ public String getState() throws Exception {
+ return service.getInstanceState(name);
+ }
+
+ public boolean isAttached() {
+ return getPid() != 0;
+ }
+}
\ No newline at end of file