summaryrefslogtreecommitdiffstats
path: root/base/tks
diff options
context:
space:
mode:
authorEndi S. Dewata <edewata@redhat.com>2014-02-20 16:58:34 -0500
committerEndi S. Dewata <edewata@redhat.com>2014-02-28 12:54:05 -0500
commitd6d197d1a4513a3262a59c3989845f69285a38ad (patch)
tree4c9becb4c5dc3ef66cf4be6c0bdd2406ab779f03 /base/tks
parent819fd31d34b3159e895f15bfad41bf483adca79e (diff)
downloadpki-d6d197d1a4513a3262a59c3989845f69285a38ad.tar.gz
pki-d6d197d1a4513a3262a59c3989845f69285a38ad.tar.xz
pki-d6d197d1a4513a3262a59c3989845f69285a38ad.zip
Reorganized REST service classes.
The REST service classes have been moved into org.dogtagpki.server namespace. A new upgrade script has been added to update existing instances. Ticket #114
Diffstat (limited to 'base/tks')
-rw-r--r--base/tks/shared/webapps/tks/WEB-INF/web.xml2
-rw-r--r--base/tks/src/CMakeLists.txt61
-rw-r--r--base/tks/src/org/dogtagpki/server/tks/rest/TKSApplication.java (renamed from base/tks/src/com/netscape/tks/TKSApplication.java)22
-rw-r--r--base/tks/src/org/dogtagpki/server/tks/rest/TPSConnectorService.java494
4 files changed, 556 insertions, 23 deletions
diff --git a/base/tks/shared/webapps/tks/WEB-INF/web.xml b/base/tks/shared/webapps/tks/WEB-INF/web.xml
index 652736217..e4650475d 100644
--- a/base/tks/shared/webapps/tks/WEB-INF/web.xml
+++ b/base/tks/shared/webapps/tks/WEB-INF/web.xml
@@ -295,7 +295,7 @@
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
- <param-value>com.netscape.tks.TKSApplication</param-value>
+ <param-value>org.dogtagpki.server.tks.rest.TKSApplication</param-value>
</init-param>
</servlet>
diff --git a/base/tks/src/CMakeLists.txt b/base/tks/src/CMakeLists.txt
index 9d0d3a70a..d1ebbb13d 100644
--- a/base/tks/src/CMakeLists.txt
+++ b/base/tks/src/CMakeLists.txt
@@ -46,14 +46,6 @@ find_file(LDAPJDK_JAR
/usr/share/java
)
-find_file(JAXRS_API_JAR
- NAMES
- jaxrs-api.jar
- PATHS
- ${RESTEASY_LIB}
-)
-
-
# '${JAVA_LIB_INSTALL_DIR}' jars
find_file(JSS_JAR
NAMES
@@ -69,6 +61,34 @@ find_file(COMMONS_CODEC_JAR
/usr/share/java
)
+find_file(COMMONS_LANG_JAR
+ NAMES
+ commons-lang.jar
+ PATHS
+ /usr/share/java
+)
+
+find_file(JAXRS_API_JAR
+ NAMES
+ jaxrs-api.jar
+ PATHS
+ ${RESTEASY_LIB}
+)
+
+find_file(RESTEASY_JAXRS_JAR
+ NAMES
+ resteasy-jaxrs.jar
+ PATHS
+ ${RESTEASY_LIB}
+)
+
+find_file(RESTEASY_ATOM_PROVIDER_JAR
+ NAMES
+ resteasy-atom-provider.jar
+ PATHS
+ ${RESTEASY_LIB}
+)
+
find_file(SYMKEY_JAR
NAMES
symkey.jar
@@ -76,16 +96,34 @@ find_file(SYMKEY_JAR
${JAVA_LIB_INSTALL_DIR}
)
+find_file(SERVLET_JAR
+ NAMES
+ servlet.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
+find_file(TOMCAT_CATALINA_JAR
+ NAMES
+ catalina.jar
+ PATHS
+ /usr/share/java/tomcat
+)
# build pki-tks
javac(pki-tks-classes
SOURCES
com/netscape/tks/*.java
+ org/dogtagpki/server/tks/*.java
CLASSPATH
- ${PKI_CERTSRV_JAR} ${PKI_CMS_JAR} ${PKI_CMSCORE_JAR}
+ ${COMMONS_CODEC_JAR} ${COMMONS_LANG_JAR}
+ ${LDAPJDK_JAR}
+ ${JSS_JAR} ${SYMKEY_JAR}
+ ${SERVLET_JAR} ${TOMCAT_CATALINA_JAR}
+ ${JAXRS_API_JAR} ${RESTEASY_JAXRS_JAR} ${RESTEASY_ATOM_PROVIDER_JAR}
${PKI_CMSUTIL_JAR} ${PKI_NSUTIL_JAR}
- ${LDAPJDK_JAR} ${JAXRS_API_JAR}
- ${JSS_JAR} ${COMMONS_CODEC_JAR} ${SYMKEY_JAR}
+ ${PKI_CERTSRV_JAR} ${PKI_CMS_JAR} ${PKI_CMSCORE_JAR}
OUTPUT_DIR
${CMAKE_BINARY_DIR}/classes
DEPENDS
@@ -108,6 +146,7 @@ jar(pki-tks-jar
${CMAKE_BINARY_DIR}/classes
FILES
com/netscape/tks/*.class
+ org/dogtagpki/server/tks/*.class
DEPENDS
pki-tks-classes
)
diff --git a/base/tks/src/com/netscape/tks/TKSApplication.java b/base/tks/src/org/dogtagpki/server/tks/rest/TKSApplication.java
index f4a8730d9..976b9bd9f 100644
--- a/base/tks/src/com/netscape/tks/TKSApplication.java
+++ b/base/tks/src/org/dogtagpki/server/tks/rest/TKSApplication.java
@@ -1,21 +1,21 @@
-package com.netscape.tks;
+package org.dogtagpki.server.tks.rest;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
+import org.dogtagpki.server.rest.ACLInterceptor;
+import org.dogtagpki.server.rest.AccountService;
+import org.dogtagpki.server.rest.AuditService;
+import org.dogtagpki.server.rest.AuthMethodInterceptor;
+import org.dogtagpki.server.rest.GroupService;
+import org.dogtagpki.server.rest.SelfTestService;
+import org.dogtagpki.server.rest.SystemCertService;
+import org.dogtagpki.server.rest.SystemConfigService;
+import org.dogtagpki.server.rest.UserService;
+
import com.netscape.certsrv.base.PKIException;
-import com.netscape.cms.authorization.ACLInterceptor;
-import com.netscape.cms.authorization.AuthMethodInterceptor;
-import com.netscape.cms.servlet.account.AccountService;
-import com.netscape.cms.servlet.admin.GroupService;
-import com.netscape.cms.servlet.admin.SystemCertService;
-import com.netscape.cms.servlet.admin.UserService;
-import com.netscape.cms.servlet.csadmin.SystemConfigService;
-import com.netscape.cms.servlet.tks.TPSConnectorService;
-import com.netscape.cmscore.logging.AuditService;
-import com.netscape.cmscore.selftests.SelfTestService;
public class TKSApplication extends Application {
diff --git a/base/tks/src/org/dogtagpki/server/tks/rest/TPSConnectorService.java b/base/tks/src/org/dogtagpki/server/tks/rest/TPSConnectorService.java
new file mode 100644
index 000000000..36512690a
--- /dev/null
+++ b/base/tks/src/org/dogtagpki/server/tks/rest/TPSConnectorService.java
@@ -0,0 +1,494 @@
+package org.dogtagpki.server.tks.rest;
+
+import java.io.IOException;
+import java.net.URI;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.TreeSet;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
+import org.jboss.resteasy.plugins.providers.atom.Link;
+import org.mozilla.jss.CryptoManager.NotInitializedException;
+import org.mozilla.jss.crypto.InvalidKeyFormatException;
+import org.mozilla.jss.crypto.TokenException;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.BadRequestException;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.PKIException;
+import com.netscape.certsrv.base.ResourceNotFoundException;
+import com.netscape.certsrv.base.UnauthorizedException;
+import com.netscape.certsrv.key.KeyData;
+import com.netscape.certsrv.system.TPSConnectorCollection;
+import com.netscape.certsrv.system.TPSConnectorData;
+import com.netscape.certsrv.system.TPSConnectorResource;
+import com.netscape.certsrv.tps.cert.TPSCertResource;
+import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.certsrv.usrgrp.IUser;
+import com.netscape.cms.realm.PKIPrincipal;
+import com.netscape.cms.servlet.base.PKIService;
+import com.netscape.cmsutil.crypto.CryptoUtil;
+import com.netscape.cmsutil.util.Utils;
+
+public class TPSConnectorService extends PKIService implements TPSConnectorResource {
+
+ private static final String TPS_LIST = "tps.list";
+
+ IConfigStore cs = CMS.getConfigStore();
+
+ @Context
+ private UriInfo uriInfo;
+
+ @Context
+ private HttpServletRequest servletRequest;
+
+ public final static int DEFAULT_SIZE = 20;
+
+ public IUGSubsystem userGroupManager = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+
+ @Override
+ public Response findConnectors(Integer start, Integer size) {
+ try {
+ String tpsList = cs.getString(TPS_LIST, "");
+ Iterator<String> entries = Arrays.asList(StringUtils.split(tpsList,",")).iterator();
+
+ TPSConnectorCollection response = new TPSConnectorCollection();
+ int i = 0;
+
+ // skip to the start of the page
+ for ( ; i<start && entries.hasNext(); i++) entries.next();
+
+ // return entries up to the page size
+ for ( ; i<start+size && entries.hasNext(); i++) {
+ response.addEntry(createTPSConnectorData(entries.next()));
+ }
+
+ // count the total entries
+ for ( ; entries.hasNext(); i++) entries.next();
+ response.setTotal(i);
+
+ if (start > 0) {
+ URI uri = uriInfo.getRequestUriBuilder().replaceQueryParam("start", Math.max(start-size, 0)).build();
+ response.addLink(new Link("prev", uri));
+ }
+
+ if (start+size < i) {
+ URI uri = uriInfo.getRequestUriBuilder().replaceQueryParam("start", start+size).build();
+ response.addLink(new Link("next", uri));
+ }
+
+ return createOKResponse(response);
+
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ throw new PKIException("Unable to get TPS connection data: " + e);
+ }
+ }
+
+ private TPSConnectorData createTPSConnectorData(String tpsID) throws EBaseException {
+ TPSConnectorData data = new TPSConnectorData();
+ data.setID(tpsID);
+ data.setHost(cs.getString("tps." + tpsID + ".host", ""));
+ data.setPort(cs.getString("tps." + tpsID + ".port", ""));
+ data.setUserID(cs.getString("tps." + tpsID + ".userid", ""));
+ data.setNickname(cs.getString("tps." + tpsID + ".nickname", ""));
+ URI uri = uriInfo.getBaseUriBuilder().path(TPSCertResource.class).path("{id}").build(tpsID);
+ data.setLink(new Link("self", uri));
+ return data;
+ }
+
+ @Override
+ public Response getConnector(String id) {
+ return createOKResponse(getConnectorData(id));
+ }
+
+ public TPSConnectorData getConnectorData(String id) {
+
+ if (id == null) throw new BadRequestException("TPS connector ID is null.");
+
+ try {
+ if (!connectorExists(id))
+ throw new ResourceNotFoundException("Connector " + id + " not found.");
+
+ return createTPSConnectorData(id);
+
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ throw new PKIException("Unable to get TPS connection data" + e);
+ }
+ }
+
+ @Override
+ public Response getConnector(String host, String port) {
+
+ if (host == null) throw new BadRequestException("TPS connector host is null.");
+ if (port == null) throw new BadRequestException("TPS connector port is null.");
+
+ try {
+ String id = getConnectorID(host, port);
+ if (id == null)
+ throw new ResourceNotFoundException(
+ "Connector not found for " + host + ":" + port);
+
+ return createOKResponse(createTPSConnectorData(id));
+
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ throw new PKIException("Unable to get TPS connection data" + e);
+ }
+ }
+
+ @Override
+ public Response createConnector(String tpsHost, String tpsPort) {
+
+ if (tpsHost == null) throw new BadRequestException("TPS connector host is null.");
+ if (tpsPort == null) throw new BadRequestException("TPS connector port is null.");
+
+ try {
+ String id = getConnectorID(tpsHost, tpsPort);
+ if (id != null) {
+ URI uri = uriInfo.getBaseUriBuilder().path(TPSCertResource.class)
+ .path("{id}").build(id);
+ throw new BadRequestException("TPS connection already exists at " + uri.toString());
+ }
+ String newID = findNextConnectorID();
+
+ TPSConnectorData newData = new TPSConnectorData();
+ newData.setID(newID);
+ newData.setHost(tpsHost);
+ newData.setPort(tpsPort);
+ newData.setUserID("TPS-" + tpsHost + "-" + tpsPort);
+ URI uri = uriInfo.getBaseUriBuilder().path(TPSCertResource.class).path("{id}").build(newID);
+ newData.setLink(new Link("self", uri));
+ saveClientData(newData);
+
+ addToConnectorList(newID);
+ cs.commit(true);
+
+ return createCreatedResponse(newData, newData.getLink().getHref());
+
+ } catch (EBaseException e) {
+ CMS.debug("Unable to create new TPS Connector: " + e);
+ e.printStackTrace();
+ throw new PKIException("Unable to create new TPS connector: " + e);
+ }
+ }
+
+ @Override
+ public Response modifyConnector(String id, TPSConnectorData data) {
+ try {
+ if (id == null) {
+ throw new BadRequestException("Invalid connector ID");
+ }
+
+ if (data == null) {
+ throw new BadRequestException("Invalid connector data");
+ }
+
+ if (!connectorExists(id)) {
+ throw new ResourceNotFoundException("TPS connection does not exist");
+ }
+
+ // Note: we are deliberately NOT allowing the userid to be modified by the
+ // admin here, because this is what maps to a user cert to retrieve the shared
+ // secret
+ if ((data.getUserID() != null) || (data.getNickname() != null)) {
+ throw new UnauthorizedException("Cannot change userid or nickname using this interface");
+ }
+ TPSConnectorData curData = getConnectorData(id);
+ curData.setHost(data.getHost());
+ curData.setPort(data.getPort());
+
+ saveClientData(curData);
+ cs.commit(true);
+
+ return createOKResponse(curData);
+
+ } catch (EBaseException e) {
+ CMS.debug("Unable to modify TPS Connector: " + e);
+ e.printStackTrace();
+ throw new PKIException("Unable to modify TPS Connector: " + e);
+ }
+ }
+
+ private void saveClientData(TPSConnectorData newData) throws EBaseException {
+ String id = newData.getID();
+ if (StringUtils.isEmpty(id)) {
+ CMS.debug("saveClientData: Attempt to save tps connection with null or empty id");
+ return;
+ }
+ String prefix = "tps." + id + ".";
+
+ if (newData.getHost() != null)
+ cs.putString(prefix + "host", newData.getHost());
+ if (newData.getPort() != null)
+ cs.putString(prefix + "port", newData.getPort());
+ if (newData.getUserID() != null)
+ cs.putString(prefix + "userid", newData.getUserID());
+ if (newData.getNickname() != null)
+ cs.putString(prefix + "nickname", newData.getNickname());
+ }
+
+ @Override
+ public Response deleteConnector(String id) {
+ try {
+ if (StringUtils.isEmpty(id))
+ throw new BadRequestException("Attempt to delete TPS connection with null or empty id");
+
+ if (!connectorExists(id)) return createNoContentResponse();
+
+ deleteSharedSecret(id);
+ cs.removeSubStore("tps." + id);
+ removeFromConnectorList(id);
+ cs.commit(true);
+
+ return createNoContentResponse();
+
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ throw new PKIException("Failed to delete TPS connection" + e);
+ }
+ }
+
+ @Override
+ public Response deleteConnector(String host, String port) {
+
+ if (host == null) throw new BadRequestException("TPS connector host is null.");
+ if (port == null) throw new BadRequestException("TPS connector port is null.");
+
+ String id;
+ try {
+ id = getConnectorID(host, port);
+ deleteConnector(id);
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ throw new PKIException("Failed to delete TPS connector: " + e);
+ }
+
+ return createNoContentResponse();
+ }
+
+ @Override
+ public Response createSharedSecret(String id) {
+
+ if (id == null) throw new BadRequestException("TPS connector ID is null.");
+
+ try {
+ if (!connectorExists(id)) {
+ throw new ResourceNotFoundException("TPS connection does not exist");
+ }
+
+ // get and validate user
+ String userid = validateUser(id);
+
+ // get user cert
+ IUser user = userGroupManager.getUser(userid);
+ X509Certificate[] certs = user.getX509Certificates();
+
+ String nickname = userid + " sharedSecret";
+ if (CryptoUtil.sharedSecretExists(nickname)) {
+ throw new BadRequestException("Shared secret already exists");
+ }
+
+ CryptoUtil.createSharedSecret(nickname);
+
+ cs.putString("tps." + id + ".nickname", nickname);
+ cs.commit(true);
+
+ byte[] wrappedKey = CryptoUtil.exportSharedSecret(nickname, certs[0]);
+ KeyData keyData = new KeyData();
+ keyData.setWrappedPrivateData(Utils.base64encode(wrappedKey));
+
+ return createOKResponse(keyData);
+
+ } catch (InvalidKeyException | IllegalStateException | NoSuchAlgorithmException
+ | InvalidAlgorithmParameterException | EBaseException
+ | NotInitializedException | TokenException | IOException | InvalidKeyFormatException e) {
+ e.printStackTrace();
+ CMS.debug("Error in generating and exporting shared secret: " + e);
+ throw new PKIException("Error in generating and exporting shared secret: " + e);
+ }
+ }
+
+ private String validateUser(String id) throws EBaseException {
+ String userid = cs.getString("tps." + id + ".userid", "");
+ if (userid.isEmpty()) {
+ throw new PKIException("Bad TPS connection configuration: userid not defined");
+ }
+
+ PKIPrincipal principal = (PKIPrincipal) servletRequest.getUserPrincipal();
+ if (principal == null) {
+ throw new UnauthorizedException("User credentials not provided");
+ }
+
+ String uid = principal.getName();
+ if (!uid.equals(userid)) {
+ throw new UnauthorizedException("TPS Connection belongs to another user");
+ }
+ return userid;
+ }
+
+ @Override
+ public Response replaceSharedSecret(String id) {
+
+ if (id == null) throw new BadRequestException("TPS connector ID is null.");
+
+ try {
+ if (!connectorExists(id)) {
+ throw new ResourceNotFoundException("TPS connection does not exist");
+ }
+
+ // get and validate user
+ String userid = validateUser(id);
+
+ String nickname = userid + " sharedSecret";
+ if (!CryptoUtil.sharedSecretExists(nickname)) {
+ throw new BadRequestException("Cannot replace. Shared secret does not exist");
+ }
+
+ // get user cert
+ IUser user = userGroupManager.getUser(userid);
+ X509Certificate[] certs = user.getX509Certificates();
+
+ CryptoUtil.deleteSharedSecret(nickname);
+ CryptoUtil.createSharedSecret(nickname);
+ byte[] wrappedKey = CryptoUtil.exportSharedSecret(nickname, certs[0]);
+ KeyData keyData = new KeyData();
+ keyData.setWrappedPrivateData(Utils.base64encode(wrappedKey));
+
+ return createOKResponse(keyData);
+
+ } catch (InvalidKeyException | IllegalStateException | NoSuchAlgorithmException
+ | InvalidAlgorithmParameterException | EBaseException
+ | NotInitializedException | TokenException | IOException | InvalidKeyFormatException e) {
+ e.printStackTrace();
+ CMS.debug("Error in replacing shared secret: " + e);
+ throw new PKIException("Error in replacing shared secret: " + e);
+ }
+ }
+
+ @Override
+ public Response deleteSharedSecret(String id) {
+
+ if (id == null) throw new BadRequestException("TPS connector ID is null.");
+
+ try {
+ if (!connectorExists(id)) {
+ throw new ResourceNotFoundException("TPS connection does not exist");
+ }
+
+ // get user
+ String userid = cs.getString("tps." + id + ".userid", "");
+ if (userid.isEmpty()) {
+ throw new PKIException("Bad TPS connection configuration: userid not defined");
+ }
+
+ String nickname = userid + " sharedSecret";
+ if (!CryptoUtil.sharedSecretExists(nickname)) {
+ return createNoContentResponse();
+ }
+ CryptoUtil.deleteSharedSecret(nickname);
+
+ cs.putString("tps." + id + ".nickname", "");
+ cs.commit(true);
+
+ return createNoContentResponse();
+
+ } catch (InvalidKeyException | IllegalStateException | EBaseException
+ | NotInitializedException | TokenException e) {
+ e.printStackTrace();
+ CMS.debug("Error in deleting shared secret: " + e);
+ throw new PKIException("Error in deleting shared secret: " + e);
+ }
+ }
+
+ @Override
+ public Response getSharedSecret(String id) {
+
+ if (id == null) throw new BadRequestException("TPS connector ID is null.");
+
+ try {
+ if (!connectorExists(id)) {
+ throw new ResourceNotFoundException("TPS connection does not exist");
+ }
+
+ // get and validate user
+ String userid = validateUser(id);
+
+ String nickname = userid + " sharedSecret";
+ if (!CryptoUtil.sharedSecretExists(nickname)) {
+ return createNoContentResponse();
+ }
+
+ // get user cert
+ IUser user = userGroupManager.getUser(userid);
+ X509Certificate[] certs = user.getX509Certificates();
+
+ byte[] wrappedKey = CryptoUtil.exportSharedSecret(nickname, certs[0]);
+ KeyData keyData = new KeyData();
+ keyData.setWrappedPrivateData(Utils.base64encode(wrappedKey));
+
+ return createOKResponse(keyData);
+
+ } catch (InvalidKeyException | IllegalStateException | NoSuchAlgorithmException
+ | InvalidAlgorithmParameterException | EBaseException
+ | NotInitializedException | TokenException | IOException | InvalidKeyFormatException e) {
+ e.printStackTrace();
+ CMS.debug("Error in obtaining shared secret: " + e);
+ throw new PKIException("Error in obtaining shared secret: " + e);
+ }
+ }
+
+ private boolean connectorExists(String id) throws EBaseException {
+ String tpsList = cs.getString(TPS_LIST, "");
+ return ArrayUtils.contains(StringUtils.split(tpsList, ","), id);
+ }
+
+ private String getConnectorID(String host, String port) throws EBaseException {
+ String tpsList = cs.getString(TPS_LIST, "");
+ for (String tpsID : StringUtils.split(tpsList,",")) {
+ TPSConnectorData data = createTPSConnectorData(tpsID);
+ if (data.getHost().equals(host) && data.getPort().equals(port))
+ return tpsID;
+ }
+ return null;
+ }
+
+ private void addToConnectorList(String id) throws EBaseException {
+ String tpsList = cs.getString(TPS_LIST, "");
+ Collection<String> sorted = new TreeSet<String>();
+ sorted.addAll(Arrays.asList(StringUtils.split(tpsList, ",")));
+ sorted.add(id);
+ cs.putString(TPS_LIST, StringUtils.join(sorted, ","));
+ }
+
+ private void removeFromConnectorList(String id) throws EBaseException {
+ String tpsList = cs.getString(TPS_LIST, "");
+ Collection<String> sorted = new TreeSet<String>();
+ sorted.addAll(Arrays.asList(StringUtils.split(tpsList, ",")));
+ sorted.remove(id);
+ cs.putString(TPS_LIST, StringUtils.join(sorted, ","));
+ }
+
+ private String findNextConnectorID() throws EBaseException {
+ String tpsList = cs.getString(TPS_LIST, "");
+ Collection<String> sorted = new TreeSet<String>();
+ sorted.addAll(Arrays.asList(StringUtils.split(tpsList, ",")));
+
+ int index = 0;
+ while (sorted.contains(Integer.toString(index))) index++;
+ return Integer.toString(index);
+ }
+}