FELIX-1391: Unable to create a new ConfigAdmin PID through the Karaf console
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@796348 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/karaf/gshell/gshell-config/pom.xml b/karaf/gshell/gshell-config/pom.xml
index 6b53cf3..b882965 100644
--- a/karaf/gshell/gshell-config/pom.xml
+++ b/karaf/gshell/gshell-config/pom.xml
@@ -54,6 +54,12 @@
<artifactId>org.osgi.compendium</artifactId>
<scope>provided</scope>
</dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-jdk14</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
diff --git a/karaf/gshell/gshell-config/src/main/java/org/apache/felix/karaf/gshell/config/EditCommand.java b/karaf/gshell/gshell-config/src/main/java/org/apache/felix/karaf/gshell/config/EditCommand.java
index 75620d6..268bc63 100644
--- a/karaf/gshell/gshell-config/src/main/java/org/apache/felix/karaf/gshell/config/EditCommand.java
+++ b/karaf/gshell/gshell-config/src/main/java/org/apache/felix/karaf/gshell/config/EditCommand.java
@@ -17,6 +17,7 @@
package org.apache.felix.karaf.gshell.config;
import java.util.Dictionary;
+import java.util.Properties;
import org.apache.felix.gogo.commands.Argument;
import org.apache.felix.gogo.commands.Option;
@@ -37,6 +38,9 @@
return;
}
Dictionary props = admin.getConfiguration(pid).getProperties();
+ if (props == null) {
+ props = new Properties();
+ }
this.session.put(PROPERTY_CONFIG_PID, pid);
this.session.put(PROPERTY_CONFIG_PROPS, props);
}
diff --git a/karaf/gshell/gshell-config/src/test/java/org/apache/felix/karaf/gshell/config/EditCommandTest.java b/karaf/gshell/gshell-config/src/test/java/org/apache/felix/karaf/gshell/config/EditCommandTest.java
new file mode 100644
index 0000000..e01dbb5
--- /dev/null
+++ b/karaf/gshell/gshell-config/src/test/java/org/apache/felix/karaf/gshell/config/EditCommandTest.java
@@ -0,0 +1,155 @@
+/*
+ * 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.felix.karaf.gshell.config;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.command.CommandSession;
+
+/**
+ * Test cases for {@link EditCommand}
+ */
+public class EditCommandTest extends TestCase {
+
+ private static final String PID = "my.test.persistent.id";
+
+ private EditCommand command;
+ private BundleContext context;
+ private ConfigurationAdmin admin;
+ private CommandSession session;
+
+ @Override
+ protected void setUp() throws Exception {
+ command = new EditCommand();
+
+ context = EasyMock.createMock(BundleContext.class);
+ command.setBundleContext(context);
+
+ ServiceReference reference = createMock(ServiceReference.class);
+ expect(context.getServiceReference(ConfigurationAdmin.class.getName())).andReturn(reference);
+
+ admin = createMock(ConfigurationAdmin.class);
+ expect(context.getService(reference)).andReturn(admin);
+ expect(context.ungetService(reference)).andReturn(Boolean.TRUE);
+
+ replay(context);
+
+ session = new MockCommandSession();
+ }
+
+ public void testExecuteOnExistingPid() throws Exception {
+ Configuration config = createMock(Configuration.class);
+ expect(admin.getConfiguration(PID)).andReturn(config);
+ replay(admin);
+
+ // the ConfigAdmin service returns a Dictionary for an existing PID
+ Properties props = new Properties();
+ expect(config.getProperties()).andReturn(props);
+ replay(config);
+
+ command.pid = PID;
+ command.execute(session);
+
+ // the PID and Dictionary should have been set on the session
+ assertEquals("The PID should be set on the session",
+ PID, session.get(ConfigCommandSupport.PROPERTY_CONFIG_PID));
+ assertSame("The Dictionary returned by the ConfigAdmin service should be set on the session",
+ props, session.get(ConfigCommandSupport.PROPERTY_CONFIG_PROPS));
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testExecuteOnNewPid() throws Exception {
+ Configuration config = createMock(Configuration.class);
+ expect(admin.getConfiguration(PID)).andReturn(config);
+ replay(admin);
+
+ // the ConfigAdmin service does not return a Dictionary for a new PID
+ expect(config.getProperties()).andReturn(null);
+ replay(config);
+
+ command.pid = PID;
+ command.execute(session);
+
+ // the PID and an empty Dictionary should have been set on the session
+ assertEquals("The PID should be set on the session",
+ PID, session.get(ConfigCommandSupport.PROPERTY_CONFIG_PID));
+ Dictionary props = (Dictionary) session.get(ConfigCommandSupport.PROPERTY_CONFIG_PROPS);
+ assertNotNull("Should have a Dictionary on the session", props);
+ assertTrue("Should have an empty Dictionary on the session", props.isEmpty());
+ }
+
+ /*
+ * A mock CommandSession implementation that only cares about the properties set on the session
+ */
+ private class MockCommandSession implements CommandSession {
+
+ private Map<String, Object> properties = new HashMap<String, Object>();
+
+ public void close() {
+ // not implemented
+ }
+
+ public Object convert(Class<?> type, Object instance) {
+ // not implemented
+ return null;
+ }
+
+ public Object execute(CharSequence commandline) throws Exception {
+ // not implemented
+ return null;
+ }
+
+ public CharSequence format(Object target, int level) {
+ // not implemented
+ return null;
+ }
+
+ public Object get(String name) {
+ return properties.get(name);
+ }
+
+ public PrintStream getConsole() {
+ // not implemented
+ return null;
+ }
+
+ public InputStream getKeyboard() {
+ // not implemented
+ return null;
+ }
+
+ public void put(String name, Object value) {
+ properties.put(name, value);
+ }
+ }
+}