Merge pull request #25 from jbonofre/KARAF-6389

[KARAF-6389] Add configuration factory support in Cave Deployer
diff --git a/deployer/api/src/main/java/org/apache/karaf/cave/deployer/api/Deployer.java b/deployer/api/src/main/java/org/apache/karaf/cave/deployer/api/Deployer.java
index b9c42a0..a2f5014 100644
--- a/deployer/api/src/main/java/org/apache/karaf/cave/deployer/api/Deployer.java
+++ b/deployer/api/src/main/java/org/apache/karaf/cave/deployer/api/Deployer.java
@@ -189,6 +189,26 @@
     void createConfig(String pid, String connection) throws Exception;
 
     /**
+     * Create an empty configuration factory on a Karaf instance.
+     */
+    String createConfigurationFactory(String factoryPid, String connection) throws Exception;
+
+    /**
+     * Create an empty configuration factory on a Karaf instance.
+     */
+    String createConfigurationFactory(String factoryPid, String alias, String connection) throws Exception;
+
+    /**
+     * Create a configuration factory on a Karaf instance.
+     */
+    String createConfigurationFactory(String factoryPid, Map<String, String> properties, String connection) throws Exception;
+
+    /**
+     * Create a configuration factory on a Karaf instance.
+     */
+    String createConfigurationFactory(String factoryPid, String alias, Map<String, String> properties, String connection) throws Exception;
+
+    /**
      * Simple remote operation to get the properties of a given configuration on a remote Karaf instance.
      */
     Map<String, String> configProperties(String pid, String connection) throws Exception;
diff --git a/deployer/command/src/main/java/org/apache/karaf/cave/deployer/command/ConfigFactoryCreateCommand.java b/deployer/command/src/main/java/org/apache/karaf/cave/deployer/command/ConfigFactoryCreateCommand.java
new file mode 100644
index 0000000..af2ac5c
--- /dev/null
+++ b/deployer/command/src/main/java/org/apache/karaf/cave/deployer/command/ConfigFactoryCreateCommand.java
@@ -0,0 +1,57 @@
+/*
+ * 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.cave.deployer.command;
+
+import org.apache.karaf.cave.deployer.api.Deployer;
+import org.apache.karaf.cave.deployer.command.completers.ConnectionCompleter;
+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.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Service
+@Command(scope = "cave", name = "deployer-config-factory-create", description = "Create a configuration factory on remote instance")
+public class ConfigFactoryCreateCommand implements Action {
+
+    @Reference
+    private Deployer deployer;
+
+    @Argument(index = 0, name = "connection", description = "The connection to use", required = true, multiValued = false)
+    @Completion(ConnectionCompleter.class)
+    String connection;
+
+    @Argument(index = 1, name = "factoryPid", description = "The factory PID to create", required = true, multiValued = false)
+    String factoryPid;
+
+    @Argument(index = 2, name = "alias", description = "The alias", required = false, multiValued = false)
+    String alias = null;
+
+    @Override
+    public Object execute() throws Exception {
+        String configPid;
+        if (alias != null && !alias.isEmpty()) {
+            configPid = deployer.createConfigurationFactory(factoryPid, alias, connection);
+        } else {
+            configPid = deployer.createConfigurationFactory(factoryPid, connection);
+        }
+        System.out.println(configPid);
+        return null;
+    }
+
+}
diff --git a/deployer/management/src/main/java/org/apache/karaf/cave/deployer/management/CaveDeployerMBean.java b/deployer/management/src/main/java/org/apache/karaf/cave/deployer/management/CaveDeployerMBean.java
index b96b7be..ef9d37e 100644
--- a/deployer/management/src/main/java/org/apache/karaf/cave/deployer/management/CaveDeployerMBean.java
+++ b/deployer/management/src/main/java/org/apache/karaf/cave/deployer/management/CaveDeployerMBean.java
@@ -52,6 +52,10 @@
 
     List<String> configs(String connection) throws Exception;
     void createConfig(String pid, String connection) throws Exception;
+    String createConfigFactory(String factoryPid, String connection) throws Exception;
+    String createConfigFactory(String factoryPid, String alias, String connection) throws Exception;
+    String createConfigFactory(String factoryPid, Map<String, String> properties, String connection) throws Exception;
+    String createConfigFactory(String factoryPid, String alias, Map<String, String> properties, String connection) throws Exception;
     Map<String, String> getConfigProperties(String pid, String connection) throws Exception;
     void deleteConfig(String pid, String connection) throws Exception;
     void appendConfigProperty(String pid, String key, String value, String connection) throws Exception;
diff --git a/deployer/management/src/main/java/org/apache/karaf/cave/deployer/management/internal/CaveDeployerMBeanImpl.java b/deployer/management/src/main/java/org/apache/karaf/cave/deployer/management/internal/CaveDeployerMBeanImpl.java
index a9410fd..3f4db03 100644
--- a/deployer/management/src/main/java/org/apache/karaf/cave/deployer/management/internal/CaveDeployerMBeanImpl.java
+++ b/deployer/management/src/main/java/org/apache/karaf/cave/deployer/management/internal/CaveDeployerMBeanImpl.java
@@ -248,6 +248,26 @@
     }
 
     @Override
+    public String createConfigFactory(String factoryPid, String connection) throws Exception {
+        return deployer.createConfigurationFactory(factoryPid, connection);
+    }
+
+    @Override
+    public String createConfigFactory(String factoryPid, String alias, String connection) throws Exception {
+        return deployer.createConfigurationFactory(factoryPid, alias, connection);
+    }
+
+    @Override
+    public String createConfigFactory(String factoryPid, Map<String, String> properties, String connection) throws Exception {
+        return deployer.createConfigurationFactory(factoryPid, properties, connection);
+    }
+
+    @Override
+    public String createConfigFactory(String factoryPid, String alias, Map<String, String> properties, String connection) throws Exception {
+        return deployer.createConfigurationFactory(factoryPid, alias, properties, connection);
+    }
+
+    @Override
     public Map<String, String> getConfigProperties(String pid, String connection) throws Exception {
         return deployer.configProperties(pid, connection);
     }
diff --git a/deployer/service/src/main/java/org/apache/karaf/cave/deployer/service/impl/DeployerImpl.java b/deployer/service/src/main/java/org/apache/karaf/cave/deployer/service/impl/DeployerImpl.java
index eef6d00..46d9fc0 100644
--- a/deployer/service/src/main/java/org/apache/karaf/cave/deployer/service/impl/DeployerImpl.java
+++ b/deployer/service/src/main/java/org/apache/karaf/cave/deployer/service/impl/DeployerImpl.java
@@ -849,6 +849,82 @@
     }
 
     @Override
+    public String createConfigurationFactory(String factoryPid, String connectionName) throws Exception {
+        Connection connection = getConnection(connectionName);
+        JMXConnector jmxConnector = connect(connection.getJmxUrl(),
+                connection.getKarafName(),
+                connection.getUser(),
+                connection.getPassword());
+        try {
+            MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection();
+            ObjectName name = new ObjectName("org.apache.karaf:type=config,name=" + connection.getKarafName());
+            String configPid = (String) mBeanServerConnection.invoke(name, "createFactoryConfiguration", new Object[]{ factoryPid }, new String[]{ String.class.getName() });
+            return configPid;
+        } finally {
+            if (jmxConnector != null) {
+                jmxConnector.close();
+            }
+        }
+    }
+
+    @Override
+    public String createConfigurationFactory(String factoryPid, String alias, String connectionName) throws Exception {
+        Connection connection = getConnection(connectionName);
+        JMXConnector jmxConnector = connect(connection.getJmxUrl(),
+                connection.getKarafName(),
+                connection.getUser(),
+                connection.getPassword());
+        try {
+            MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection();
+            ObjectName name = new ObjectName("org.apache.karaf:type=config,name=" + connection.getKarafName());
+            String configPid = (String) mBeanServerConnection.invoke(name, "createFactoryConfiguration", new Object[] { factoryPid, alias }, new String[]{ String.class.getName(), String.class.getName() });
+            return configPid;
+        } finally {
+            if (jmxConnector != null) {
+                jmxConnector.close();
+            }
+        }
+    }
+
+    @Override
+    public String createConfigurationFactory(String factoryPid, Map<String, String> properties, String connectionName) throws Exception {
+        Connection connection = getConnection(connectionName);
+        JMXConnector jmxConnector = connect(connection.getJmxUrl(),
+                connection.getKarafName(),
+                connection.getUser(),
+                connection.getPassword());
+        try {
+            MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection();
+            ObjectName name = new ObjectName("org.apache.karaf:type=config,name=" + connection.getKarafName());
+            String configPid = (String) mBeanServerConnection.invoke(name, "createFactoryConfiguration", new Object[] { factoryPid, properties }, new String[]{ String.class.getName(), Map.class.getName() });
+            return configPid;
+        } finally {
+            if (jmxConnector != null) {
+                jmxConnector.close();
+            }
+        }
+    }
+
+    @Override
+    public String createConfigurationFactory(String factoryPid, String alias, Map<String, String> properties, String connectionName) throws Exception {
+        Connection connection = getConnection(connectionName);
+        JMXConnector jmxConnector = connect(connection.getJmxUrl(),
+                connection.getKarafName(),
+                connection.getUser(),
+                connection.getPassword());
+        try {
+            MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection();
+            ObjectName name = new ObjectName("org.apache.karaf:type=config,name=" + connection.getKarafName());
+            String configPid = (String) mBeanServerConnection.invoke(name, "createFactoryConfiguration", new Object[] { factoryPid, alias, properties }, new String[]{ String.class.getName(), String.class.getName(), Map.class.getName() });
+            return configPid;
+        } finally {
+            if (jmxConnector != null) {
+                jmxConnector.close();
+            }
+        }
+    }
+
+    @Override
     public void deleteConfig(String pid, String connectionName) throws Exception {
         Connection connection = getConnection(connectionName);
         JMXConnector jmxConnector = connect(connection.getJmxUrl(),
diff --git a/rest/src/main/java/org/apache/karaf/cave/rest/DeployerRest.java b/rest/src/main/java/org/apache/karaf/cave/rest/DeployerRest.java
index 04fa81f..56ba6d2 100644
--- a/rest/src/main/java/org/apache/karaf/cave/rest/DeployerRest.java
+++ b/rest/src/main/java/org/apache/karaf/cave/rest/DeployerRest.java
@@ -405,6 +405,18 @@
         deployer.createConfig(pid, connection);
     }
 
+    @Path("/{connection}/configfactory/{pid}")
+    @POST
+    public void createConfigFactory(@PathParam("connection") String connection, @PathParam("factoryPid") String factoryPid) throws Exception {
+        deployer.createConfigurationFactory(factoryPid, connection);
+    }
+
+    @Path("/{connection}/configfactory/{pid}/{alias}")
+    @POST
+    public void createConfigFactory(@PathParam("connection") String connection, @PathParam("factoryPid") String factoryPid, @PathParam("alias") String alias) throws Exception {
+        deployer.createConfigurationFactory(factoryPid, alias, connection);
+    }
+
     @Path("/{connection}/config/{pid}")
     @DELETE
     public void deleteConfig(@PathParam("connection") String connection, @PathParam("pid") String pid) throws Exception {