From 253b0811441e691f285889b2e69a998ac91f7466 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Tue, 24 Sep 2013 10:11:15 -0400
Subject: [PATCH] Added TPS connection service implementation.

The implementation of the TPS connection service has been modified to
use the configuration database to read and write the configuration file.

Ticket #652
---
 .../certsrv/tps/connection/ConnectionClient.java   |   6 -
 .../tps/connection/ConnectionCollection.java       |   4 +-
 .../certsrv/tps/connection/ConnectionData.java     |  89 +++++++++--
 .../certsrv/tps/connection/ConnectionInfo.java     | 152 ------------------
 .../tps/connection/ConnectionModification.java     | 169 ---------------------
 .../certsrv/tps/connection/ConnectionResource.java |   9 --
 .../cmstools/tps/connection/ConnectionAddCLI.java  |  39 ++---
 .../cmstools/tps/connection/ConnectionCLI.java     |  53 ++-----
 .../cmstools/tps/connection/ConnectionFindCLI.java |  14 +-
 .../tps/connection/ConnectionModifyCLI.java        |  30 ++--
 .../cmstools/tps/connection/ConnectionShowCLI.java |  20 +--
 .../server/tps/connection/ConnectionDatabase.java  | 111 +++++++++++---
 .../server/tps/connection/ConnectionRecord.java    |  43 ++++--
 .../server/tps/connection/ConnectionService.java   |  78 +---------
 14 files changed, 261 insertions(+), 556 deletions(-)
 delete mode 100644 base/common/src/com/netscape/certsrv/tps/connection/ConnectionInfo.java
 delete mode 100644 base/common/src/com/netscape/certsrv/tps/connection/ConnectionModification.java

diff --git a/base/common/src/com/netscape/certsrv/tps/connection/ConnectionClient.java b/base/common/src/com/netscape/certsrv/tps/connection/ConnectionClient.java
index 74ec14616e000c8c93adcb941fdd33cc76a04e85..08f71b32a4f2fc7b795e11bf49fa5858b4c058f0 100644
--- a/base/common/src/com/netscape/certsrv/tps/connection/ConnectionClient.java
+++ b/base/common/src/com/netscape/certsrv/tps/connection/ConnectionClient.java
@@ -64,12 +64,6 @@ public class ConnectionClient extends Client {
         return client.getEntity(response);
     }
 
-    public ConnectionData modifyConnection(String connectionID, ConnectionModification connectionModification) {
-        @SuppressWarnings("unchecked")
-        ClientResponse<ConnectionData> response = (ClientResponse<ConnectionData>)resource.modifyConnection(connectionID, connectionModification);
-        return client.getEntity(response);
-    }
-
     public void removeConnection(String connectionID) {
         resource.removeConnection(connectionID);
     }
diff --git a/base/common/src/com/netscape/certsrv/tps/connection/ConnectionCollection.java b/base/common/src/com/netscape/certsrv/tps/connection/ConnectionCollection.java
index b26a7308d758077fa3d8197143833a427e4b0383..9d94ee08bb5553f0716b5c029b85a3017af04a72 100644
--- a/base/common/src/com/netscape/certsrv/tps/connection/ConnectionCollection.java
+++ b/base/common/src/com/netscape/certsrv/tps/connection/ConnectionCollection.java
@@ -29,10 +29,10 @@ import com.netscape.certsrv.base.DataCollection;
  * @author Endi S. Dewata
  */
 @XmlRootElement(name="Connections")
-public class ConnectionCollection extends DataCollection<ConnectionInfo> {
+public class ConnectionCollection extends DataCollection<ConnectionData> {
 
     @XmlElementRef
-    public Collection<ConnectionInfo> getEntries() {
+    public Collection<ConnectionData> getEntries() {
         return super.getEntries();
     }
 }
diff --git a/base/common/src/com/netscape/certsrv/tps/connection/ConnectionData.java b/base/common/src/com/netscape/certsrv/tps/connection/ConnectionData.java
index 573bb9543bdf38e604a078b2a87f94da40e019fc..50b0f6b519f738444fe1b761d586b72388a4f6fe 100644
--- a/base/common/src/com/netscape/certsrv/tps/connection/ConnectionData.java
+++ b/base/common/src/com/netscape/certsrv/tps/connection/ConnectionData.java
@@ -20,6 +20,11 @@ package com.netscape.certsrv.tps.connection;
 
 import java.io.StringReader;
 import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
 
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.Marshaller;
@@ -27,6 +32,9 @@ import javax.xml.bind.Unmarshaller;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlValue;
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 
 import org.jboss.resteasy.plugins.providers.atom.Link;
 
@@ -51,7 +59,7 @@ public class ConnectionData {
 
     String id;
     String status;
-    String contents;
+    Map<String, String> properties = new LinkedHashMap<String, String>();
 
     Link link;
 
@@ -73,13 +81,67 @@ public class ConnectionData {
         this.status = status;
     }
 
-    @XmlElement(name="Contents")
-    public String getContents() {
-        return contents;
+    @XmlElement(name="Properties")
+    @XmlJavaTypeAdapter(MapAdapter.class)
+    public Map<String, String> getProperties() {
+        return properties;
     }
 
-    public void setContents(String contents) {
-        this.contents = contents;
+    public void setProperties(Map<String, String> properties) {
+        this.properties.clear();
+        this.properties.putAll(properties);
+    }
+
+    public Collection<String> getPropertyNames() {
+        return properties.keySet();
+    }
+
+    public String getProperty(String name) {
+        return properties.get(name);
+    }
+
+    public void setProperty(String name, String value) {
+        properties.put(name, value);
+    }
+
+    public String removeProperty(String name) {
+        return properties.remove(name);
+    }
+
+    public static class MapAdapter extends XmlAdapter<PropertyList, Map<String, String>> {
+
+        public PropertyList marshal(Map<String, String> map) {
+            PropertyList list = new PropertyList();
+            for (Map.Entry<String, String> entry : map.entrySet()) {
+                Property property = new Property();
+                property.name = entry.getKey();
+                property.value = entry.getValue();
+                list.properties.add(property);
+            }
+            return list;
+        }
+
+        public Map<String, String> unmarshal(PropertyList list) {
+            Map<String, String> map = new LinkedHashMap<String, String>();
+            for (Property property : list.properties) {
+                map.put(property.name, property.value);
+            }
+            return map;
+        }
+    }
+
+    public static class PropertyList {
+        @XmlElement(name="Property")
+        public List<Property> properties = new ArrayList<Property>();
+    }
+
+    public static class Property {
+
+        @XmlAttribute
+        public String name;
+
+        @XmlValue
+        public String value;
     }
 
     @XmlElement(name="Link")
@@ -95,9 +157,9 @@ public class ConnectionData {
     public int hashCode() {
         final int prime = 31;
         int result = 1;
-        result = prime * result + ((contents == null) ? 0 : contents.hashCode());
         result = prime * result + ((id == null) ? 0 : id.hashCode());
         result = prime * result + ((link == null) ? 0 : link.hashCode());
+        result = prime * result + ((properties == null) ? 0 : properties.hashCode());
         result = prime * result + ((status == null) ? 0 : status.hashCode());
         return result;
     }
@@ -111,11 +173,6 @@ public class ConnectionData {
         if (getClass() != obj.getClass())
             return false;
         ConnectionData other = (ConnectionData) obj;
-        if (contents == null) {
-            if (other.contents != null)
-                return false;
-        } else if (!contents.equals(other.contents))
-            return false;
         if (id == null) {
             if (other.id != null)
                 return false;
@@ -126,6 +183,11 @@ public class ConnectionData {
                 return false;
         } else if (!link.equals(other.link))
             return false;
+        if (properties == null) {
+            if (other.properties != null)
+                return false;
+        } else if (!properties.equals(other.properties))
+            return false;
         if (status == null) {
             if (other.status != null)
                 return false;
@@ -158,7 +220,8 @@ public class ConnectionData {
         ConnectionData before = new ConnectionData();
         before.setID("connection1");
         before.setStatus("ENABLED");
-        before.setContents("name=connection1\nparam=value");
+        before.setProperty("param1", "value1");
+        before.setProperty("param2", "value2");
 
         String string = before.toString();
         System.out.println(string);
diff --git a/base/common/src/com/netscape/certsrv/tps/connection/ConnectionInfo.java b/base/common/src/com/netscape/certsrv/tps/connection/ConnectionInfo.java
deleted file mode 100644
index d9d93517ec0dcd35bc28540e5da4b53948ce756a..0000000000000000000000000000000000000000
--- a/base/common/src/com/netscape/certsrv/tps/connection/ConnectionInfo.java
+++ /dev/null
@@ -1,152 +0,0 @@
-// --- BEGIN COPYRIGHT BLOCK ---
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// (C) 2013 Red Hat, Inc.
-// All rights reserved.
-// --- END COPYRIGHT BLOCK ---
-
-package com.netscape.certsrv.tps.connection;
-
-import java.io.StringReader;
-import java.io.StringWriter;
-
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-
-import org.jboss.resteasy.plugins.providers.atom.Link;
-
-/**
- * @author Endi S. Dewata
- */
-@XmlRootElement(name="Connection")
-public class ConnectionInfo {
-
-    public static Marshaller marshaller;
-    public static Unmarshaller unmarshaller;
-
-    static {
-        try {
-            marshaller = JAXBContext.newInstance(ConnectionInfo.class).createMarshaller();
-            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
-            unmarshaller = JAXBContext.newInstance(ConnectionInfo.class).createUnmarshaller();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    String id;
-    String status;
-
-    Link link;
-
-    @XmlAttribute(name="id")
-    public String getID() {
-        return id;
-    }
-
-    public void setID(String id) {
-        this.id = id;
-    }
-
-    @XmlElement(name="Status")
-    public String getStatus() {
-        return status;
-    }
-
-    public void setStatus(String status) {
-        this.status = status;
-    }
-
-    @XmlElement(name="Link")
-    public Link getLink() {
-        return link;
-    }
-
-    public void setLink(Link link) {
-        this.link = link;
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((id == null) ? 0 : id.hashCode());
-        result = prime * result + ((link == null) ? 0 : link.hashCode());
-        result = prime * result + ((status == null) ? 0 : status.hashCode());
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
-            return true;
-        if (obj == null)
-            return false;
-        if (getClass() != obj.getClass())
-            return false;
-        ConnectionInfo other = (ConnectionInfo) obj;
-        if (id == null) {
-            if (other.id != null)
-                return false;
-        } else if (!id.equals(other.id))
-            return false;
-        if (link == null) {
-            if (other.link != null)
-                return false;
-        } else if (!link.equals(other.link))
-            return false;
-        if (status == null) {
-            if (other.status != null)
-                return false;
-        } else if (!status.equals(other.status))
-            return false;
-        return true;
-    }
-
-    public String toString() {
-        try {
-            StringWriter sw = new StringWriter();
-            marshaller.marshal(this, sw);
-            return sw.toString();
-
-        } catch (Exception e) {
-            return super.toString();
-        }
-    }
-
-    public static ConnectionInfo valueOf(String string) throws Exception {
-        try {
-            return (ConnectionInfo)unmarshaller.unmarshal(new StringReader(string));
-        } catch (Exception e) {
-            return null;
-        }
-    }
-
-    public static void main(String args[]) throws Exception {
-
-        ConnectionInfo before = new ConnectionInfo();
-        before.setID("connection1");
-        before.setStatus("ENABLED");
-
-        String string = before.toString();
-        System.out.println(string);
-
-        ConnectionInfo after = ConnectionInfo.valueOf(string);
-        System.out.println(before.equals(after));
-    }
-}
diff --git a/base/common/src/com/netscape/certsrv/tps/connection/ConnectionModification.java b/base/common/src/com/netscape/certsrv/tps/connection/ConnectionModification.java
deleted file mode 100644
index 7e48074b2c41c2fb4547ec81614d784bb0d6ca9a..0000000000000000000000000000000000000000
--- a/base/common/src/com/netscape/certsrv/tps/connection/ConnectionModification.java
+++ /dev/null
@@ -1,169 +0,0 @@
-// --- BEGIN COPYRIGHT BLOCK ---
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// (C) 2013 Red Hat, Inc.
-// All rights reserved.
-// --- END COPYRIGHT BLOCK ---
-
-package com.netscape.certsrv.tps.connection;
-
-import java.io.StringReader;
-import java.io.StringWriter;
-
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-
-import org.jboss.resteasy.plugins.providers.atom.Link;
-
-/**
- * @author Endi S. Dewata
- */
-@XmlRootElement(name="ConnectionModifyRequest")
-public class ConnectionModification {
-
-    public static Marshaller marshaller;
-    public static Unmarshaller unmarshaller;
-
-    static {
-        try {
-            marshaller = JAXBContext.newInstance(ConnectionModification.class).createMarshaller();
-            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
-            unmarshaller = JAXBContext.newInstance(ConnectionModification.class).createUnmarshaller();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    String id;
-    String status;
-    String contents;
-
-    Link link;
-
-    @XmlAttribute(name="id")
-    public String getID() {
-        return id;
-    }
-
-    public void setID(String id) {
-        this.id = id;
-    }
-
-    @XmlElement(name="Status")
-    public String getStatus() {
-        return status;
-    }
-
-    public void setStatus(String status) {
-        this.status = status;
-    }
-
-    @XmlElement(name="Contents")
-    public String getContents() {
-        return contents;
-    }
-
-    public void setContents(String contents) {
-        this.contents = contents;
-    }
-
-    @XmlElement(name="Link")
-    public Link getLink() {
-        return link;
-    }
-
-    public void setLink(Link link) {
-        this.link = link;
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((contents == null) ? 0 : contents.hashCode());
-        result = prime * result + ((id == null) ? 0 : id.hashCode());
-        result = prime * result + ((link == null) ? 0 : link.hashCode());
-        result = prime * result + ((status == null) ? 0 : status.hashCode());
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
-            return true;
-        if (obj == null)
-            return false;
-        if (getClass() != obj.getClass())
-            return false;
-        ConnectionModification other = (ConnectionModification) obj;
-        if (contents == null) {
-            if (other.contents != null)
-                return false;
-        } else if (!contents.equals(other.contents))
-            return false;
-        if (id == null) {
-            if (other.id != null)
-                return false;
-        } else if (!id.equals(other.id))
-            return false;
-        if (link == null) {
-            if (other.link != null)
-                return false;
-        } else if (!link.equals(other.link))
-            return false;
-        if (status == null) {
-            if (other.status != null)
-                return false;
-        } else if (!status.equals(other.status))
-            return false;
-        return true;
-    }
-
-    public String toString() {
-        try {
-            StringWriter sw = new StringWriter();
-            marshaller.marshal(this, sw);
-            return sw.toString();
-
-        } catch (Exception e) {
-            return super.toString();
-        }
-    }
-
-    public static ConnectionModification valueOf(String string) throws Exception {
-        try {
-            return (ConnectionModification)unmarshaller.unmarshal(new StringReader(string));
-        } catch (Exception e) {
-            return null;
-        }
-    }
-
-    public static void main(String args[]) throws Exception {
-
-        ConnectionModification before = new ConnectionModification();
-        before.setID("connection1");
-        before.setStatus("ENABLED");
-        before.setContents("name=connection1\nparam=value");
-
-        String string = before.toString();
-        System.out.println(string);
-
-        ConnectionModification after = ConnectionModification.valueOf(string);
-        System.out.println(before.equals(after));
-    }
-}
diff --git a/base/common/src/com/netscape/certsrv/tps/connection/ConnectionResource.java b/base/common/src/com/netscape/certsrv/tps/connection/ConnectionResource.java
index ee971b052e4e8f50e935d571632248ab8f84c392..928dabae72da84c4d6dee108581c418e9ba69b7a 100644
--- a/base/common/src/com/netscape/certsrv/tps/connection/ConnectionResource.java
+++ b/base/common/src/com/netscape/certsrv/tps/connection/ConnectionResource.java
@@ -64,15 +64,6 @@ public interface ConnectionResource {
             @PathParam("connectionID") String connectionID,
             ConnectionData connectionData);
 
-    @POST
-    @Path("{connectionID}")
-    @ClientResponseType(entityType=ConnectionData.class)
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    public Response modifyConnection(
-            @PathParam("connectionID") String connectionID,
-            ConnectionModification request);
-
     @DELETE
     @Path("{connectionID}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
diff --git a/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionAddCLI.java b/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionAddCLI.java
index bb2beda13c1bbfe732eda952733eefca32cd4aff..f01823a4a3177542807cf67d4fdb4192e28a30e4 100644
--- a/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionAddCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionAddCLI.java
@@ -48,12 +48,7 @@ public class ConnectionAddCLI extends CLI {
 
     public void execute(String[] args) throws Exception {
 
-        Option option = new Option(null, "status", true, "Status: ENABLED, DISABLED.");
-        option.setArgName("status");
-        option.setRequired(true);
-        options.addOption(option);
-
-        option = new Option(null, "contents", true, "Input file containing connection attributes.");
+        Option option = new Option(null, "input", true, "Input file containing connection properties.");
         option.setArgName("file");
         option.setRequired(true);
         options.addOption(option);
@@ -71,37 +66,31 @@ public class ConnectionAddCLI extends CLI {
 
         String[] cmdArgs = cmd.getArgs();
 
-        if (cmdArgs.length != 1) {
+        if (cmdArgs.length != 0) {
             printHelp();
             System.exit(1);
         }
 
-        String connectionID = cmdArgs[0];
-        String status = cmd.getOptionValue("status");
-        String contents = cmd.getOptionValue("contents");
+        String input = cmd.getOptionValue("input");
 
-        ConnectionData connectionData = new ConnectionData();
-        connectionData.setID(connectionID);
-        connectionData.setStatus(status);
+        ConnectionData connectionData;
 
-        if (contents != null) {
-            try (BufferedReader in = new BufferedReader(new FileReader(contents));
-                StringWriter sw = new StringWriter();
-                PrintWriter out = new PrintWriter(sw, true)) {
+        try (BufferedReader in = new BufferedReader(new FileReader(input));
+            StringWriter sw = new StringWriter();
+            PrintWriter out = new PrintWriter(sw, true)) {
 
-                String line;
-                while ((line = in.readLine()) != null) {
-                    out.println(line);
-                }
-
-                connectionData.setContents(sw.toString());
+            String line;
+            while ((line = in.readLine()) != null) {
+                out.println(line);
             }
+
+            connectionData = ConnectionData.valueOf(sw.toString());
         }
 
         connectionData = connectionCLI.connectionClient.addConnection(connectionData);
 
-        MainCLI.printMessage("Added connection \"" + connectionID + "\"");
+        MainCLI.printMessage("Added connection \"" + connectionData.getID() + "\"");
 
-        ConnectionCLI.printConnectionData(connectionData);
+        ConnectionCLI.printConnectionData(connectionData, true);
     }
 }
diff --git a/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionCLI.java b/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionCLI.java
index 5371dbe9d0a4241d14696889932845718055c18b..1159a20128471f07fe3cba4a8f9b726080eb3f4a 100644
--- a/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionCLI.java
@@ -18,16 +18,13 @@
 
 package com.netscape.cmstools.tps.connection;
 
-import java.io.BufferedReader;
 import java.io.IOException;
-import java.io.StringReader;
-import java.util.Arrays;
+import java.util.Map;
 
 import org.jboss.resteasy.plugins.providers.atom.Link;
 
 import com.netscape.certsrv.tps.connection.ConnectionClient;
 import com.netscape.certsrv.tps.connection.ConnectionData;
-import com.netscape.certsrv.tps.connection.ConnectionInfo;
 import com.netscape.cmstools.cli.CLI;
 
 /**
@@ -52,51 +49,19 @@ public class ConnectionCLI extends CLI {
         client = parent.getClient();
         connectionClient = (ConnectionClient)parent.getClient("connection");
 
-        if (args.length == 0) {
-            printHelp();
-            System.exit(1);
-        }
-
-        String command = args[0];
-        String[] commandArgs = Arrays.copyOfRange(args, 1, args.length);
-
-        if (command == null) {
-            printHelp();
-            System.exit(1);
-        }
-
-        CLI module = getModule(command);
-        if (module != null) {
-            module.execute(commandArgs);
-
-        } else {
-            System.err.println("Error: Invalid command \"" + command + "\"");
-            printHelp();
-            System.exit(1);
-        }
-    }
-
-    public static void printConnectionInfo(ConnectionInfo connectionInfo) {
-        System.out.println("  Connection ID: " + connectionInfo.getID());
-        if (connectionInfo.getStatus() != null) System.out.println("  Status: " + connectionInfo.getStatus());
-
-        Link link = connectionInfo.getLink();
-        if (verbose && link != null) {
-            System.out.println("  Link: " + link.getHref());
-        }
+        super.execute(args);
     }
 
-    public static void printConnectionData(ConnectionData connectionData) throws IOException {
+    public static void printConnectionData(ConnectionData connectionData, boolean showProperties) throws IOException {
         System.out.println("  Connection ID: " + connectionData.getID());
         if (connectionData.getStatus() != null) System.out.println("  Status: " + connectionData.getStatus());
 
-        System.out.println("  Contents:");
-        String contents = connectionData.getContents();
-        if (contents != null) {
-            BufferedReader in = new BufferedReader(new StringReader(contents));
-            String line;
-            while ((line = in.readLine()) != null) {
-                System.out.println("    " + line);
+        if (showProperties) {
+            System.out.println("  Properties:");
+            Map<String, String> properties = connectionData.getProperties();
+            for (String name : properties.keySet()) {
+                String value = properties.get(name);
+                System.out.println("    " + name + ": " + value);
             }
         }
 
diff --git a/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionFindCLI.java b/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionFindCLI.java
index 9218edee4ff357c9ef0a65b0e59bdcb4aa0c965b..6112db4ff2b733d923111f5416d137da462080a1 100644
--- a/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionFindCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionFindCLI.java
@@ -24,7 +24,7 @@ import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Option;
 
 import com.netscape.certsrv.tps.connection.ConnectionCollection;
-import com.netscape.certsrv.tps.connection.ConnectionInfo;
+import com.netscape.certsrv.tps.connection.ConnectionData;
 import com.netscape.cmstools.cli.CLI;
 import com.netscape.cmstools.cli.MainCLI;
 
@@ -35,9 +35,9 @@ public class ConnectionFindCLI extends CLI {
 
     public ConnectionCLI connectionCLI;
 
-    public ConnectionFindCLI(ConnectionCLI tokenCLI) {
-        super("find", "Find connections", tokenCLI);
-        this.connectionCLI = tokenCLI;
+    public ConnectionFindCLI(ConnectionCLI connectionCLI) {
+        super("find", "Find connections", connectionCLI);
+        this.connectionCLI = connectionCLI;
     }
 
     public void printHelp() {
@@ -72,13 +72,13 @@ public class ConnectionFindCLI extends CLI {
         Integer size = s == null ? null : Integer.valueOf(s);
 
         ConnectionCollection result = connectionCLI.connectionClient.findConnections(start, size);
-        Collection<ConnectionInfo> connections = result.getEntries();
+        Collection<ConnectionData> connections = result.getEntries();
 
         MainCLI.printMessage(connections.size() + " connection(s) matched");
 
         boolean first = true;
 
-        for (ConnectionInfo connectionInfo : connections) {
+        for (ConnectionData connectionData : connections) {
 
             if (first) {
                 first = false;
@@ -86,7 +86,7 @@ public class ConnectionFindCLI extends CLI {
                 System.out.println();
             }
 
-            ConnectionCLI.printConnectionInfo(connectionInfo);
+            ConnectionCLI.printConnectionData(connectionData, false);
         }
 
         MainCLI.printMessage("Number of entries returned " + connections.size());
diff --git a/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionModifyCLI.java b/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionModifyCLI.java
index f3e44913214e818fd893ebeca4e1c53f45786a48..704410daa29dd05bc588d9ace5046ec055e7f796 100644
--- a/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionModifyCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionModifyCLI.java
@@ -27,7 +27,6 @@ import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Option;
 
 import com.netscape.certsrv.tps.connection.ConnectionData;
-import com.netscape.certsrv.tps.connection.ConnectionModification;
 import com.netscape.cmstools.cli.CLI;
 import com.netscape.cmstools.cli.MainCLI;
 
@@ -53,7 +52,7 @@ public class ConnectionModifyCLI extends CLI {
         option.setArgName("status");
         options.addOption(option);
 
-        option = new Option(null, "contents", true, "Input file containing connection attributes.");
+        option = new Option(null, "input", true, "Input file containing connection properties.");
         option.setArgName("file");
         options.addOption(option);
 
@@ -77,31 +76,26 @@ public class ConnectionModifyCLI extends CLI {
 
         String connectionID = cmdArgs[0];
         String status = cmd.getOptionValue("status");
-        String contents = cmd.getOptionValue("contents");
+        String input = cmd.getOptionValue("input");
 
-        ConnectionModification connectionModification = new ConnectionModification();
-        connectionModification.setID(connectionID);
-        connectionModification.setStatus(status);
+        ConnectionData connectionData;
 
-        if (contents != null) {
-            // load contents from file
+        try (BufferedReader in = new BufferedReader(new FileReader(input));
             StringWriter sw = new StringWriter();
-            try (BufferedReader in = new BufferedReader(new FileReader(contents));
-                PrintWriter out = new PrintWriter(sw, true)) {
+            PrintWriter out = new PrintWriter(sw, true)) {
 
-                String line;
-                while ((line = in.readLine()) != null) {
-                    out.println(line);
-                }
-
-                connectionModification.setContents(sw.toString());
+            String line;
+            while ((line = in.readLine()) != null) {
+                out.println(line);
             }
+
+            connectionData = ConnectionData.valueOf(sw.toString());
         }
 
-        ConnectionData connectionData = connectionCLI.connectionClient.modifyConnection(connectionID, connectionModification);
+        connectionData = connectionCLI.connectionClient.updateConnection(connectionID, connectionData);
 
         MainCLI.printMessage("Modified connection \"" + connectionID + "\"");
 
-        ConnectionCLI.printConnectionData(connectionData);
+        ConnectionCLI.printConnectionData(connectionData, true);
     }
 }
diff --git a/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionShowCLI.java b/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionShowCLI.java
index 7e660d3946ce4169ee1ad0574874da1669ce7555..455518e47869208302a3a6a88c06dde3fd48f12e 100644
--- a/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionShowCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/tps/connection/ConnectionShowCLI.java
@@ -46,7 +46,7 @@ public class ConnectionShowCLI extends CLI {
 
     public void execute(String[] args) throws Exception {
 
-        Option option = new Option(null, "contents", true, "Output file to store connection attributes.");
+        Option option = new Option(null, "output", true, "Output file to store connection properties.");
         option.setArgName("file");
         options.addOption(option);
 
@@ -69,19 +69,19 @@ public class ConnectionShowCLI extends CLI {
         }
 
         String connectionID = args[0];
-        String file = cmd.getOptionValue("contents");
+        String output = cmd.getOptionValue("output");
 
         ConnectionData connectionData = connectionCLI.connectionClient.getConnection(connectionID);
 
-        MainCLI.printMessage("Connection \"" + connectionID + "\"");
-        ConnectionCLI.printConnectionData(connectionData);
+        if (output == null) {
+            MainCLI.printMessage("Connection \"" + connectionID + "\"");
+            ConnectionCLI.printConnectionData(connectionData, true);
 
-        if (file != null) {
-            // store contents to file
-            PrintWriter out = new PrintWriter(new FileWriter(file));
-            String contents = connectionData.getContents();
-            if (contents != null) out.print(contents);
-            out.close();
+        } else {
+            try (PrintWriter out = new PrintWriter(new FileWriter(output))) {
+                out.println(connectionData);
+            }
+            MainCLI.printMessage("Stored connection \"" + connectionID + "\" into " + output);
         }
     }
 }
diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/connection/ConnectionDatabase.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/connection/ConnectionDatabase.java
index cb7fb981f848119b4dd8d2d32b8431587cf7403a..5ffdbdd6745961eb31300f48b638f641321f4846 100644
--- a/base/tps-tomcat/src/org/dogtagpki/server/tps/connection/ConnectionDatabase.java
+++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/connection/ConnectionDatabase.java
@@ -18,11 +18,18 @@
 
 package org.dogtagpki.server.tps.connection;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+import org.dogtagpki.server.tps.config.ConfigDatabase;
+import org.dogtagpki.server.tps.config.ConfigRecord;
+
+import com.netscape.certsrv.apps.CMS;
 import com.netscape.cmscore.dbs.Database;
 
 /**
- * This class implements in-memory connection database. In the future this
- * will be replaced with LDAP database.
+ * This class provides access to the connections in CS.cfg.
  *
  * @author Endi S. Dewata
  */
@@ -30,31 +37,95 @@ public class ConnectionDatabase extends Database<ConnectionRecord> {
 
     public ConnectionDatabase() {
         super("Connection");
+    }
 
-        // add sample records
-        try {
-            ConnectionRecord record1 = new ConnectionRecord();
-            record1.setID("connection1");
-            record1.setStatus("ENABLED");
-            record1.setContents("name=connection1\nparam=value");
-            addRecord(record1);
+    public ConnectionRecord createConnectionRecord(ConfigDatabase configDatabase, ConfigRecord configRecord, String connectionID) {
+        ConnectionRecord connectionRecord = new ConnectionRecord();
+        connectionRecord.setID(connectionID);
+        Map<String, String> properties = configDatabase.getProperties(configRecord, connectionID);
+        connectionRecord.setProperties(properties);
+        return connectionRecord;
+    }
 
-            ConnectionRecord record2 = new ConnectionRecord();
-            record2.setID("connection2");
-            record2.setStatus("DISABLED");
-            record2.setContents("name=connection2\nparam=value");
-            addRecord(record2);
+    @Override
+    public Collection<ConnectionRecord> getRecords() throws Exception {
 
-        } catch (Exception e) {
-            e.printStackTrace();
+        Collection<ConnectionRecord> result = new ArrayList<ConnectionRecord>();
+        ConfigDatabase configDatabase = new ConfigDatabase();
+        ConfigRecord configRecord = configDatabase.getRecord("Subsystem_Connections");
+
+        for (String connectionID : configRecord.getKeys()) {
+            ConnectionRecord connectionRecord = createConnectionRecord(configDatabase, configRecord, connectionID);
+            result.add(connectionRecord);
         }
+
+        return result;
     }
 
-    public void addRecord(ConnectionRecord connectionRecord) throws Exception {
-        addRecord(connectionRecord.getID(), connectionRecord);
+    @Override
+    public ConnectionRecord getRecord(String connectionID) throws Exception {
+
+        ConfigDatabase configDatabase = new ConfigDatabase();
+        ConfigRecord configRecord = configDatabase.getRecord("Subsystem_Connections");
+
+        return createConnectionRecord(configDatabase, configRecord, connectionID);
     }
 
-    public void updateRecord(ConnectionRecord connectionRecord) throws Exception {
-        updateRecord(connectionRecord.getID(), connectionRecord);
+    @Override
+    public void addRecord(String connectionID, ConnectionRecord connectionRecord) throws Exception {
+
+        CMS.debug("ConnectionDatabase.addRecord(\"" + connectionID + "\")");
+        ConfigDatabase configDatabase = new ConfigDatabase();
+        ConfigRecord configRecord = configDatabase.getRecord("Subsystem_Connections");
+
+        // validate new properties
+        Map<String, String> properties = connectionRecord.getProperties();
+        configDatabase.validateProperties(configRecord, connectionID, properties);
+
+        // add new connection
+        configRecord.addKey(connectionID);
+        configDatabase.updateRecord("Subsystem_Connections", configRecord);
+
+        // store new properties
+        configDatabase.addProperties(configRecord, connectionID, properties);
+
+        configDatabase.commit();
+    }
+
+    @Override
+    public void updateRecord(String connectionID, ConnectionRecord connectionRecord) throws Exception {
+
+        CMS.debug("ConnectionDatabase.updateRecord(\"" + connectionID + "\")");
+        ConfigDatabase configDatabase = new ConfigDatabase();
+        ConfigRecord configRecord = configDatabase.getRecord("Subsystem_Connections");
+
+        // validate new properties
+        Map<String, String> properties = connectionRecord.getProperties();
+        configDatabase.validateProperties(configRecord, connectionID, properties);
+
+        // remove old properties
+        configDatabase.removeProperties(configRecord, connectionID);
+
+        // add new properties
+        configDatabase.addProperties(configRecord, connectionID, properties);
+
+        configDatabase.commit();
+    }
+
+    @Override
+    public void removeRecord(String connectionID) throws Exception {
+
+        CMS.debug("ConnectionDatabase.removeRecord(\"" + connectionID + "\")");
+        ConfigDatabase configDatabase = new ConfigDatabase();
+        ConfigRecord configRecord = configDatabase.getRecord("Subsystem_Connections");
+
+        // remove properties
+        configDatabase.removeProperties(configRecord, connectionID);
+
+        // remove connection
+        configRecord.removeKey(connectionID);
+        configDatabase.updateRecord("Subsystem_Connections", configRecord);
+
+        configDatabase.commit();
     }
 }
diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/connection/ConnectionRecord.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/connection/ConnectionRecord.java
index c4bcc1ded5ff95fe015a70a99e4fdf9bf3e5298a..1219af98149d2c7e09db4165a58022ded240f1a9 100644
--- a/base/tps-tomcat/src/org/dogtagpki/server/tps/connection/ConnectionRecord.java
+++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/connection/ConnectionRecord.java
@@ -18,6 +18,10 @@
 
 package org.dogtagpki.server.tps.connection;
 
+import java.util.Collection;
+import java.util.Map;
+import java.util.TreeMap;
+
 
 /**
  * @author Endi S. Dewata
@@ -26,7 +30,7 @@ public class ConnectionRecord {
 
     String id;
     String status;
-    String contents;
+    Map<String, String> properties = new TreeMap<String, String>();
 
     public String getID() {
         return id;
@@ -44,20 +48,37 @@ public class ConnectionRecord {
         this.status = status;
     }
 
-    public String getContents() {
-        return contents;
+    public Map<String, String> getProperties() {
+        return properties;
     }
 
-    public void setContents(String contents) {
-        this.contents = contents;
+    public void setProperties(Map<String, String> properties) {
+        this.properties.clear();
+        this.properties.putAll(properties);
+    }
+
+    public Collection<String> getPropertyNames() {
+        return properties.keySet();
+    }
+
+    public String getProperty(String name) {
+        return properties.get(name);
+    }
+
+    public void setProperty(String name, String value) {
+        properties.put(name, value);
+    }
+
+    public String removeProperty(String name) {
+        return properties.remove(name);
     }
 
     @Override
     public int hashCode() {
         final int prime = 31;
         int result = 1;
-        result = prime * result + ((contents == null) ? 0 : contents.hashCode());
         result = prime * result + ((id == null) ? 0 : id.hashCode());
+        result = prime * result + ((properties == null) ? 0 : properties.hashCode());
         result = prime * result + ((status == null) ? 0 : status.hashCode());
         return result;
     }
@@ -71,16 +92,16 @@ public class ConnectionRecord {
         if (getClass() != obj.getClass())
             return false;
         ConnectionRecord other = (ConnectionRecord) obj;
-        if (contents == null) {
-            if (other.contents != null)
-                return false;
-        } else if (!contents.equals(other.contents))
-            return false;
         if (id == null) {
             if (other.id != null)
                 return false;
         } else if (!id.equals(other.id))
             return false;
+        if (properties == null) {
+            if (other.properties != null)
+                return false;
+        } else if (!properties.equals(other.properties))
+            return false;
         if (status == null) {
             if (other.status != null)
                 return false;
diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/connection/ConnectionService.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/connection/ConnectionService.java
index 805ea452dfc4de61f4a7d392f79f940660fe051a..034af5afdb54fc30e87f1a6ce75cb22a89960601 100644
--- a/base/tps-tomcat/src/org/dogtagpki/server/tps/connection/ConnectionService.java
+++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/connection/ConnectionService.java
@@ -38,8 +38,6 @@ import com.netscape.certsrv.apps.CMS;
 import com.netscape.certsrv.base.PKIException;
 import com.netscape.certsrv.tps.connection.ConnectionCollection;
 import com.netscape.certsrv.tps.connection.ConnectionData;
-import com.netscape.certsrv.tps.connection.ConnectionInfo;
-import com.netscape.certsrv.tps.connection.ConnectionModification;
 import com.netscape.certsrv.tps.connection.ConnectionResource;
 import com.netscape.cms.servlet.base.PKIService;
 
@@ -66,41 +64,16 @@ public class ConnectionService extends PKIService implements ConnectionResource
         CMS.debug("ConnectionService.<init>()");
     }
 
-    public ConnectionInfo createConnectionInfo(ConnectionRecord connectionRecord) {
-
-        ConnectionInfo connectionInfo = new ConnectionInfo();
-        connectionInfo.setID(connectionRecord.getID());
-        connectionInfo.setStatus(connectionRecord.getStatus());
+    public ConnectionData createConnectionData(ConnectionRecord connectionRecord) throws UnsupportedEncodingException {
 
         String connectionID = connectionRecord.getID();
-        try {
-            connectionID = URLEncoder.encode(connectionID, "UTF-8");
-        } catch (UnsupportedEncodingException e) {
-            e.printStackTrace();
-            throw new PKIException(e.getMessage());
-        }
-
-        URI uri = uriInfo.getBaseUriBuilder().path(ConnectionResource.class).path("{connectionID}").build(connectionID);
-        connectionInfo.setLink(new Link("self", uri));
-
-        return connectionInfo;
-    }
-
-    public ConnectionData createConnectionData(ConnectionRecord connectionRecord) {
 
         ConnectionData connectionData = new ConnectionData();
-        connectionData.setID(connectionRecord.getID());
+        connectionData.setID(connectionID);
         connectionData.setStatus(connectionRecord.getStatus());
-        connectionData.setContents(connectionRecord.getContents());
-
-        String connectionID = connectionRecord.getID();
-        try {
-            connectionID = URLEncoder.encode(connectionID, "UTF-8");
-        } catch (UnsupportedEncodingException e) {
-            e.printStackTrace();
-            throw new PKIException(e.getMessage());
-        }
+        connectionData.setProperties(connectionRecord.getProperties());
 
+        connectionID = URLEncoder.encode(connectionID, "UTF-8");
         URI uri = uriInfo.getBaseUriBuilder().path(ConnectionResource.class).path("{connectionID}").build(connectionID);
         connectionData.setLink(new Link("self", uri));
 
@@ -112,7 +85,7 @@ public class ConnectionService extends PKIService implements ConnectionResource
         ConnectionRecord connectionRecord = new ConnectionRecord();
         connectionRecord.setID(connectionData.getID());
         connectionRecord.setStatus(connectionData.getStatus());
-        connectionRecord.setContents(connectionData.getContents());
+        connectionRecord.setProperties(connectionData.getProperties());
 
         return connectionRecord;
     }
@@ -140,7 +113,7 @@ public class ConnectionService extends PKIService implements ConnectionResource
 
             // return entries up to the page size
             for ( ; i<start+size && connections.hasNext(); i++) {
-                response.addEntry(createConnectionInfo(connections.next()));
+                response.addEntry(createConnectionData(connections.next()));
             }
 
             // count the total entries
@@ -190,7 +163,7 @@ public class ConnectionService extends PKIService implements ConnectionResource
             TPSSubsystem subsystem = (TPSSubsystem)CMS.getSubsystem(TPSSubsystem.ID);
             ConnectionDatabase database = subsystem.getConnectionDatabase();
 
-            database.addRecord(createConnectionRecord(connectionData));
+            database.addRecord(connectionData.getID(), createConnectionRecord(connectionData));
             connectionData = createConnectionData(database.getRecord(connectionData.getID()));
 
             return Response
@@ -214,7 +187,7 @@ public class ConnectionService extends PKIService implements ConnectionResource
             TPSSubsystem subsystem = (TPSSubsystem)CMS.getSubsystem(TPSSubsystem.ID);
             ConnectionDatabase database = subsystem.getConnectionDatabase();
 
-            database.updateRecord(createConnectionRecord(connectionData));
+            database.updateRecord(connectionData.getID(), createConnectionRecord(connectionData));
             connectionData = createConnectionData(database.getRecord(connectionID));
 
             return Response
@@ -229,41 +202,6 @@ public class ConnectionService extends PKIService implements ConnectionResource
     }
 
     @Override
-    public Response modifyConnection(String connectionID, ConnectionModification request) {
-
-        CMS.debug("ConnectionService.modifyConnection(\"" + connectionID + "\", request");
-
-        try {
-            TPSSubsystem subsystem = (TPSSubsystem)CMS.getSubsystem(TPSSubsystem.ID);
-            ConnectionDatabase database = subsystem.getConnectionDatabase();
-
-            ConnectionRecord connectionRecord = database.getRecord(connectionID);
-
-            String status = request.getStatus();
-            if (status != null) {
-                connectionRecord.setStatus(status);
-            }
-
-            String contents = request.getContents();
-            if (contents != null) {
-                connectionRecord.setContents(contents);
-            }
-
-            database.updateRecord(connectionRecord);
-            ConnectionData connectionData = createConnectionData(database.getRecord(connectionID));
-
-            return Response
-                    .ok(connectionData)
-                    .type(MediaType.APPLICATION_XML)
-                    .build();
-
-        } catch (Exception e) {
-            e.printStackTrace();
-            throw new PKIException(e.getMessage());
-        }
-    }
-
-    @Override
     public void removeConnection(String connectionID) {
 
         CMS.debug("ConnectionService.removeConnection(\"" + connectionID + "\")");
-- 
1.8.1.4

