diff options
author | Christina Fu <cfu@redhat.com> | 2014-03-03 15:52:55 -0800 |
---|---|---|
committer | Christina Fu <cfu@redhat.com> | 2014-03-06 19:33:35 -0800 |
commit | 61ec5553e416733996be05fda16983d32252000c (patch) | |
tree | 61f7a81cec53df149113d4c73cd1c1836904cb35 | |
parent | 35fcdc2ca9c5ef42ccdddcbfdf484c4f66a720fc (diff) | |
download | pki-61ec5553e416733996be05fda16983d32252000c.tar.gz pki-61ec5553e416733996be05fda16983d32252000c.tar.xz pki-61ec5553e416733996be05fda16983d32252000c.zip |
trac ticket #862 - TPS rewrite: provide connector service for JAVA-based TPS subsystem
17 files changed, 702 insertions, 184 deletions
diff --git a/base/common/src/com/netscape/certsrv/apps/CMS.java b/base/common/src/com/netscape/certsrv/apps/CMS.java index fbcf65ac0..405e99ecf 100644 --- a/base/common/src/com/netscape/certsrv/apps/CMS.java +++ b/base/common/src/com/netscape/certsrv/apps/CMS.java @@ -850,6 +850,19 @@ public final class CMS { * * @param authority remote authority * @param factory socket factory + * @param op operation to determine receiving servlet (multi-uri support) + * @return http connection to the remote authority + */ + public static IHttpConnection getHttpConnection(IRemoteAuthority authority, + ISocketFactory factory, String op) { + return _engine.getHttpConnection(authority, factory, op); + } + + /** + * Retrieves the HTTP Connection for use with connector. + * + * @param authority remote authority + * @param factory socket factory * @param timeout return error if connection cannot be established within * the timeout period * @return http connection to the remote authority @@ -860,6 +873,21 @@ public final class CMS { } /** + * Retrieves the HTTP Connection for use with connector. + * + * @param authority remote authority + * @param factory socket factory + * @param timeout return error if connection cannot be established within + * the timeout period + * @param op operation to determine receiving servlet (multi-uri support) + * @return http connection to the remote authority + */ + public static IHttpConnection getHttpConnection(IRemoteAuthority authority, + ISocketFactory factory, int timeout, String op) { + return _engine.getHttpConnection(authority, factory, timeout, op); + } + + /** * Retrieves the request sender for use with connector. * * @param authority local authority diff --git a/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java b/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java index 74fa09003..fb3881ed3 100644 --- a/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java +++ b/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java @@ -1029,6 +1029,17 @@ public interface ICMSEngine extends ISubsystem { * * @param authority remote authority * @param factory socket factory + * @param op operation to determine receiving servlet (multi-uri support) + * @return http connection to the remote authority + */ + public IHttpConnection getHttpConnection(IRemoteAuthority authority, + ISocketFactory factory, String op); + + /** + * Retrieves the HTTP Connection for use with connector. + * + * @param authority remote authority + * @param factory socket factory * @param timeout return error if connection cannot be established within * the timeout period * @return http connection to the remote authority @@ -1037,6 +1048,19 @@ public interface ICMSEngine extends ISubsystem { ISocketFactory factory, int timeout); /** + * Retrieves the HTTP Connection for use with connector. + * + * @param authority remote authority + * @param factory socket factory + * @param timeout return error if connection cannot be established within + * the timeout period + * @param op operation to determine receiving servlet (multi-uri support) + * @return http connection to the remote authority + */ + public IHttpConnection getHttpConnection(IRemoteAuthority authority, + ISocketFactory factory, int timeout, String op); + + /** * Retrieves the request sender for use with connector. * * @param authority local authority diff --git a/base/common/src/com/netscape/certsrv/base/IConfigStore.java b/base/common/src/com/netscape/certsrv/base/IConfigStore.java index 92bf7b2f6..2f9d95556 100644 --- a/base/common/src/com/netscape/certsrv/base/IConfigStore.java +++ b/base/common/src/com/netscape/certsrv/base/IConfigStore.java @@ -47,11 +47,11 @@ import java.util.Map; * String valx = config.getString("param1"); * // valx is "value1" <p> * - * IConfigStore substore1 = config.getSubstore("configStore1"); + * IConfigStore substore1 = config.getSubStore("configStore1"); * String valy = substore1.getString("param11"); * // valy is "value11" <p> * - * IConfigStore substore2 = config.getSubstore("configStore2"); + * IConfigStore substore2 = config.getSubStore("configStore2"); * String valz = substore2.getString("param21"); * // valz is "value21" <p> * } diff --git a/base/common/src/com/netscape/certsrv/connector/IConnector.java b/base/common/src/com/netscape/certsrv/connector/IConnector.java index 02e7231ab..6eda896c4 100644 --- a/base/common/src/com/netscape/certsrv/connector/IConnector.java +++ b/base/common/src/com/netscape/certsrv/connector/IConnector.java @@ -19,6 +19,7 @@ package com.netscape.certsrv.connector; import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.request.IRequest; +import com.netscape.cmsutil.http.HttpResponse; /** * This interface represents a connector that forwards @@ -55,6 +56,17 @@ public interface IConnector { throws EBaseException; /** + * Sends the request to a remote authority. + * + * @param op operation to determine receiving servlet (multi-uri support) + * @param msg Request to be forwarded to remote authority. + * @return HttpResponse to be parsed by client + * @exception EBaseException Failure to send request to remote authority. + */ + public HttpResponse send(String op, String msg) + throws EBaseException; + + /** * Starts this connector. */ public void start(); diff --git a/base/common/src/com/netscape/certsrv/connector/IHttpConnection.java b/base/common/src/com/netscape/certsrv/connector/IHttpConnection.java index 8adc7da72..2e871851b 100644 --- a/base/common/src/com/netscape/certsrv/connector/IHttpConnection.java +++ b/base/common/src/com/netscape/certsrv/connector/IHttpConnection.java @@ -18,6 +18,7 @@ package com.netscape.certsrv.connector; import com.netscape.certsrv.base.EBaseException; +import com.netscape.cmsutil.http.HttpResponse; /** * This represents a HTTP connection to a remote authority. @@ -38,4 +39,14 @@ public interface IHttpConnection { */ public IPKIMessage send(IPKIMessage tomsg) throws EBaseException; + + /** + * Sends the message to the remote authority. + * + * @param msg Message to forward to authority. + * @return HttpResponse response to be parsed by the client + * @exception EBaseException Failed to send message. + */ + public HttpResponse send(String msg) + throws EBaseException; } diff --git a/base/common/src/com/netscape/certsrv/connector/IRemoteAuthority.java b/base/common/src/com/netscape/certsrv/connector/IRemoteAuthority.java index f02154021..1e66daa81 100644 --- a/base/common/src/com/netscape/certsrv/connector/IRemoteAuthority.java +++ b/base/common/src/com/netscape/certsrv/connector/IRemoteAuthority.java @@ -17,6 +17,8 @@ // --- END COPYRIGHT BLOCK --- package com.netscape.certsrv.connector; +import java.util.Hashtable; + /** * This represents a remote authority that can be * a certificate manager, or key recovery manager or @@ -48,9 +50,30 @@ public interface IRemoteAuthority { public String getURI(); /** + * Retrieves the list of URIs supported by the remote Authority + * (multi-URI support) + */ + public Hashtable<String, String> getURIs(); + + /** + * Retrieves an URI by operation + * (multi-URI support) + * @param op operation to determine the receiving servlet + */ + public String getURI(String op); + + /** * Retrieves the timeout value for the connection to the remote Authority. * * @return In with remote Authority timeout value. */ public int getTimeout(); + + /** + * Retrieves the Content-Type value of the connection to the Remote Authority. + * + * @return String with Content-Type, if it was set + * @return + */ + public String getContentType(); } diff --git a/base/server/cms/src/com/netscape/cms/servlet/base/CMSServlet.java b/base/server/cms/src/com/netscape/cms/servlet/base/CMSServlet.java index 56a37b34d..67cc7d163 100644 --- a/base/server/cms/src/com/netscape/cms/servlet/base/CMSServlet.java +++ b/base/server/cms/src/com/netscape/cms/servlet/base/CMSServlet.java @@ -458,6 +458,17 @@ public abstract class CMSServlet extends HttpServlet { outputHttpParameters(httpReq); } CMS.debug("CMSServlet: " + mId + " start to service."); + /* cfu test + CMS.debug("CMSServlet: content length=" +httpReq.getContentLength()); + Enumeration<String> reqParams = httpReq.getParameterNames(); + while (reqParams.hasMoreElements()) { + String reqName = reqParams.nextElement(); + String reqValue = httpReq.getParameter(reqName); + + CMS.debug("CMSServlet: process() cfu debug: HttpServletRequest "+ + reqName+"="+reqValue); + } + */ // get a cms request CMSRequest cmsRequest = newCMSRequest(); diff --git a/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java b/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java index 68c64824e..456cc7767 100644 --- a/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java +++ b/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java @@ -801,6 +801,16 @@ public class CMSEngine implements ICMSEngine { return new HttpConnection(authority, factory, timeout); } + public IHttpConnection getHttpConnection(IRemoteAuthority authority, + ISocketFactory factory, String op) { + return new HttpConnection(authority, factory, op); + } + + public IHttpConnection getHttpConnection(IRemoteAuthority authority, + ISocketFactory factory, int timeout, String op) { + return new HttpConnection(authority, factory, timeout, op); + } + public IResender getResender(IAuthority authority, String nickname, IRemoteAuthority remote, int interval) { return new Resender(authority, nickname, remote, interval); diff --git a/base/server/cmscore/src/com/netscape/cmscore/connector/HttpConnFactory.java b/base/server/cmscore/src/com/netscape/cmscore/connector/HttpConnFactory.java index a55a186e3..be727a54b 100644 --- a/base/server/cmscore/src/com/netscape/cmscore/connector/HttpConnFactory.java +++ b/base/server/cmscore/src/com/netscape/cmscore/connector/HttpConnFactory.java @@ -75,7 +75,7 @@ public class HttpConnFactory { * initialize parameters obtained from either constructor or * config store * - * @param minConns minimum number of connection handls to have available. + * @param minConns minimum number of connection handles to have available. * @param maxConns maximum total number of connections to ever have. * @param connInfo ldap connection info. * @param authInfo ldap authentication info. @@ -113,7 +113,7 @@ public class HttpConnFactory { CMS.debug("leaving HttpConnFactory init."); } - private IHttpConnection createConnection() throws EBaseException { + private IHttpConnection createConnection(String op) throws EBaseException { IHttpConnection retConn = null; @@ -122,10 +122,18 @@ public class HttpConnFactory { try { ISocketFactory tFactory = new JssSSLSocketFactory(mNickname); - if (mTimeout == 0) { - retConn = CMS.getHttpConnection(mDest, tFactory); + if (op == null) { + if (mTimeout == 0) { + retConn = CMS.getHttpConnection(mDest, tFactory); + } else { + retConn = CMS.getHttpConnection(mDest, tFactory, mTimeout); + } } else { - retConn = CMS.getHttpConnection(mDest, tFactory, mTimeout); + if (mTimeout == 0) { + retConn = CMS.getHttpConnection(mDest, tFactory, op); + } else { + retConn = CMS.getHttpConnection(mDest, tFactory, mTimeout, op); + } } } catch (Exception e) { @@ -142,7 +150,7 @@ public class HttpConnFactory { /** * makes the minumum number of connections */ - private void makeMinimum() throws EBaseException { + private void makeMinimum(String op) throws EBaseException { CMS.debug("In HttpConnFactory.makeMinimum."); int increment; @@ -157,7 +165,7 @@ public class HttpConnFactory { CMS.debug( "increasing minimum connections by " + increment); for (int i = increment - 1; i >= 0; i--) { - mConns[i] = createConnection(); + mConns[i] = createConnection(op); } mTotal += increment; mNumConns += increment; @@ -190,6 +198,15 @@ public class HttpConnFactory { return getConn(true); } + /* + * See getConn() above + * @param op operation to determine the receiving servlet (multi-uri support) + */ + public IHttpConnection getConn(String op) + throws EBaseException { + return getConn(true, op); + } + /** * Returns a Http connection - a clone of the master connection. * All connections should be returned to the factory using returnConn() @@ -214,11 +231,20 @@ public class HttpConnFactory { */ public synchronized IHttpConnection getConn(boolean waitForConn) throws EBaseException { + return getConn(waitForConn, null); + } + + /* + * See getConn() above + * @param op operation to determine the receiving servlet (multi-uri support) + */ + public synchronized IHttpConnection getConn(boolean waitForConn, String op) + throws EBaseException { boolean waited = false; CMS.debug("In HttpConnFactory.getConn"); if (mNumConns == 0) - makeMinimum(); + makeMinimum(op); if (mNumConns == 0) { if (!waitForConn) return null; @@ -251,7 +277,7 @@ public class HttpConnFactory { } /** - * Teturn connection to the factory. + * Return connection to the factory. * This is mandatory after a getConn(). * The best thing to do is to put returnConn in a finally clause so it * always gets called. For example, @@ -296,4 +322,4 @@ public class HttpConnFactory { "In Http (bound) connection pool to" + msg); } -}
\ No newline at end of file +} diff --git a/base/server/cmscore/src/com/netscape/cmscore/connector/HttpConnection.java b/base/server/cmscore/src/com/netscape/cmscore/connector/HttpConnection.java index 7a65c1760..30d70be1b 100644 --- a/base/server/cmscore/src/com/netscape/cmscore/connector/HttpConnection.java +++ b/base/server/cmscore/src/com/netscape/cmscore/connector/HttpConnection.java @@ -61,6 +61,13 @@ public class HttpConnection implements IHttpConnection { } public HttpConnection(IRemoteAuthority dest, ISocketFactory factory) { + this(dest, factory, null); + } + + /* + * @param op operation to determine the receiving servlet (multi-uri support) + */ + public HttpConnection(IRemoteAuthority dest, ISocketFactory factory, String op) { mDest = dest; mReqEncoder = new HttpRequestEncoder(); mHttpClient = new HttpClient(factory); @@ -68,7 +75,18 @@ public class HttpConnection implements IHttpConnection { Debug.trace("Created HttpClient"); try { mHttpreq.setMethod("POST"); - mHttpreq.setURI(mDest.getURI()); + if (op == null) + mHttpreq.setURI(mDest.getURI()); + else { + mHttpreq.setURI(mDest.getURI(op)); + } + + String contentType = dest.getContentType(); + if (contentType != null) { + CMS.debug("HttpConnection: setting Content-Type"); + mHttpreq.setHeader("Content-Type", contentType ); + } + mHttpreq.setHeader("Connection", "Keep-Alive"); CMS.debug("HttpConnection: connecting to " + dest.getHost() + ":" + dest.getPort()); String host = dest.getHost(); @@ -94,13 +112,31 @@ public class HttpConnection implements IHttpConnection { // Inserted by beomsuk public HttpConnection(IRemoteAuthority dest, ISocketFactory factory, int timeout) { + this(dest, factory, timeout, null); + } + + /* + * @param op operation to determine the receiving servlet (multi-uri support) + */ + public HttpConnection(IRemoteAuthority dest, ISocketFactory factory, int timeout, String op) { mDest = dest; mReqEncoder = new HttpRequestEncoder(); mHttpClient = new HttpClient(factory); CMS.debug("HttpConn:Created HttpConnection: factory " + factory + "client " + mHttpClient); try { mHttpreq.setMethod("POST"); - mHttpreq.setURI(mDest.getURI()); + if (op == null) + mHttpreq.setURI(mDest.getURI()); + else { + mHttpreq.setURI(mDest.getURI(op)); + } + + String contentType = dest.getContentType(); + if (contentType != null) { + CMS.debug("HttpConnection: setting Content-Type"); + mHttpreq.setHeader("Content-Type", contentType ); + } + mHttpreq.setHeader("Connection", "Keep-Alive"); CMS.debug("HttpConnection: connecting to " + dest.getHost() + ":" + dest.getPort() + " timeout:" + timeout); mHttpClient.connect(dest.getHost(), dest.getPort(), timeout); @@ -122,6 +158,7 @@ public class HttpConnection implements IHttpConnection { public IPKIMessage send(IPKIMessage tomsg) throws EBaseException { IPKIMessage replymsg = null; + HttpResponse resp = null; CMS.debug("in HttpConnection.send " + this); if (Debug.ON) @@ -139,20 +176,61 @@ public class HttpConnection implements IHttpConnection { Debug.trace(content); Debug.trace("--------------------------"); } + resp = doSend(content); + + // decode reply. + // if reply is bad, error is thrown and request will be resent + String pcontent = resp.getContent(); + + if (Debug.ON) { + Debug.trace("Server returned\n"); + Debug.trace("-------"); + Debug.trace(pcontent); + Debug.trace("-------"); + } + CMS.debug("HttpConnection.send response: " + pcontent); + + try { + replymsg = (IPKIMessage) mReqEncoder.decode(pcontent); + } catch (IOException e) { + throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", "Could not decode content")); + } + CMS.debug("HttpConn:decoded reply"); + return replymsg; + } + + /** + * sends a request to a remote authority, returning the result. + * @author cfu (multi-uri support) + * @throws EBaseException for any failure + */ + public HttpResponse send(String content) + throws EBaseException { + HttpResponse resp = null; + if ((content == null) || content.equals("")) { + CMS.debug("HttpConnection.send: with String content: null or empty"); + throw new EBaseException("HttpConnection.send: with String content: null or empty"); + } + // CMS.debug("HttpConnection.send: with String content: " + content); + + resp = doSend(content); + return resp; + } + + private HttpResponse doSend(String content) + throws EBaseException { + HttpResponse resp = null; boolean reconnect = false; mHttpreq.setHeader("Content-Length", Integer.toString(content.length())); - if (Debug.ON) - Debug.trace("request encoded length " + content.length()); + CMS.debug("HttpConnection.doSend: with String content length: " + Integer.toString(content.length())); mHttpreq.setContent(content); - HttpResponse p = null; - try { if (!mHttpClient.connected()) { mHttpClient.connect(mDest.getHost(), mDest.getPort()); - CMS.debug("HttpConn:reconnected to " + mDest.getHost() + ":" + mDest.getPort()); + CMS.debug("HttpConnection.doSend: reconnected to " + mDest.getHost() + ":" + mDest.getPort()); reconnect = true; } } catch (IOException e) { @@ -167,33 +245,32 @@ public class HttpConnection implements IHttpConnection { } // if remote closed connection want to reconnect and resend. - while (p == null) { + while (resp == null) { try { - if (Debug.ON) - Debug.trace("sending request"); - p = mHttpClient.send(mHttpreq); + CMS.debug("HttpConnection.doSend: sending request"); + resp = mHttpClient.send(mHttpreq); } catch (IOException e) { CMS.debug("HttpConn: mHttpClient.send failed " + e.toString()); if (reconnect) { - CMS.debug("HttpConn:resend failed again. " + e); + CMS.debug("HttpConnection.doSend:resend failed again. " + e); throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED", "resend failed again. " + e)); } try { - CMS.debug("HttpConn: trying a reconnect "); + CMS.debug("HttpConnection.doSend: trying a reconnect "); mHttpClient.connect(mDest.getHost(), mDest.getPort()); } catch (IOException ex) { - CMS.debug("reconnect for resend failed. " + ex); + CMS.debug("HttpConnection.doSend: reconnect for resend failed. " + ex); throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED", "reconnect for resend failed." + ex)); } reconnect = true; } - } + } //while // got reply; check status - String statusStr = p.getStatusCode(); + String statusStr = resp.getStatusCode(); - CMS.debug("HttpConn:server returned status " + statusStr); + CMS.debug("HttpConnection.doSend:server returned status " + statusStr); int statuscode = -1; try { @@ -208,37 +285,18 @@ public class HttpConnection implements IHttpConnection { /* HttpServletResponse.SC_UNAUTHORIZED = 401 */ if (statuscode == 401) { // XXX what to do here. - String msg = "request no good " + statuscode + " " + p.getReasonPhrase(); + String msg = "request no good " + statuscode + " " + resp.getReasonPhrase(); - if (Debug.ON) - Debug.trace(msg); + CMS.debug(msg); throw new EBaseException(CMS.getUserMessage("CMS_BASE_AUTHENTICATE_FAILED", msg)); } else { // XXX what to do here. - String msg = "HttpConn:request no good " + statuscode + " " + p.getReasonPhrase(); + String msg = "HttpConn:request no good " + statuscode + " " + resp.getReasonPhrase(); CMS.debug(msg); throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", msg)); } } - - // decode reply. - // if reply is bad, error is thrown and request will be resent - String pcontent = p.getContent(); - - if (Debug.ON) { - Debug.trace("Server returned\n"); - Debug.trace("-------"); - Debug.trace(pcontent); - Debug.trace("-------"); - } - - try { - replymsg = (IPKIMessage) mReqEncoder.decode(pcontent); - } catch (IOException e) { - throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", "Could not decode content")); - } - CMS.debug("HttpConn:decoded reply"); - return replymsg; + return resp; } } diff --git a/base/server/cmscore/src/com/netscape/cmscore/connector/HttpConnector.java b/base/server/cmscore/src/com/netscape/cmscore/connector/HttpConnector.java index 33b0d62b7..ff0ece148 100644 --- a/base/server/cmscore/src/com/netscape/cmscore/connector/HttpConnector.java +++ b/base/server/cmscore/src/com/netscape/cmscore/connector/HttpConnector.java @@ -34,6 +34,7 @@ import com.netscape.certsrv.request.RequestId; import com.netscape.certsrv.request.RequestStatus; import com.netscape.cmsutil.http.JssSSLSocketFactory; import com.netscape.cmsutil.net.ISocketFactory; +import com.netscape.cmsutil.http.HttpResponse; public class HttpConnector implements IConnector { protected IAuthority mSource = null; @@ -71,7 +72,9 @@ public class HttpConnector implements IConnector { // mConn = CMS.getHttpConnection(dest, mFactory); // this will start resending past requests in parallel. - mResender = CMS.getResender(mSource, nickName, dest, resendInterval); + if (resendInterval >= 0) { + mResender = CMS.getResender(mSource, nickName, dest, resendInterval); + } } // Inserted by beomsuk @@ -95,11 +98,32 @@ public class HttpConnector implements IConnector { } // this will start resending past requests in parallel. - mResender = CMS.getResender(mSource, nickName, dest, resendInterval); + if (resendInterval >= 0) { + mResender = CMS.getResender(mSource, nickName, dest, resendInterval); + } } // Insert end + // cfu + public HttpResponse send(String op, String msg) + throws EBaseException { + CMS.debug("HttpConnector: send(): cfu"); + HttpResponse resp = null; + IHttpConnection curConn = null; + try { + curConn = mConnFactory.getConn(op); + resp = curConn.send(msg); + } catch (EBaseException e) { + CMS.debug("HttpConnector: send():"+ e.toString()); + } finally { + if (curConn != null) { + mConnFactory.returnConn(curConn); + } + } + return resp; + } + public boolean send(IRequest r) throws EBaseException { IHttpConnection curConn = null; @@ -148,9 +172,12 @@ public class HttpConnector implements IConnector { replyStatus == RequestStatus.APPROVED)) { CMS.debug("HttpConn: remote request id still pending " + r.getRequestId() + " state " + replyStatus); + /* mSource.log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_CONNECTOR_REQUEST_NOT_COMPLETED", r.getRequestId().toString())); - mResender.addRequest(r); + */ + if (mResender != null) + mResender.addRequest(r); return false; } @@ -181,12 +208,16 @@ public class HttpConnector implements IConnector { } catch (EBaseException e) { CMS.debug("HttpConn: inside EBaseException " + e.toString()); - if (!r.getRequestType().equals(IRequest.GETREVOCATIONINFO_REQUEST)) - mResender.addRequest(r); + if (!r.getRequestType().equals(IRequest.GETREVOCATIONINFO_REQUEST)) { + if (mResender != null) + mResender.addRequest(r); + } CMS.debug("HttpConn: error sending request to cert " + e.toString()); + /* mSource.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CONNECTOR_SEND_REQUEST", r.getRequestId() .toString(), mDest.getHost(), Integer.toString(mDest.getPort()))); + */ // mSource.log(ILogger.LL_INFO, // "Queing " + r.getRequestId() + " for resend."); return false; @@ -200,12 +231,14 @@ public class HttpConnector implements IConnector { public void start() { CMS.debug("Starting HttpConnector resender thread"); - mResender.start("HttpConnector"); + if (mResender != null) + mResender.start("HttpConnector"); } public void stop() { CMS.debug("Stopping HttpConnector resender thread"); - mResender.stop(); + if (mResender != null) + mResender.stop(); } } diff --git a/base/server/cmscore/src/com/netscape/cmscore/connector/LocalConnector.java b/base/server/cmscore/src/com/netscape/cmscore/connector/LocalConnector.java index ba2db83a1..6c12b2729 100644 --- a/base/server/cmscore/src/com/netscape/cmscore/connector/LocalConnector.java +++ b/base/server/cmscore/src/com/netscape/cmscore/connector/LocalConnector.java @@ -34,6 +34,7 @@ import com.netscape.certsrv.request.IRequestQueue; import com.netscape.certsrv.request.RequestId; import com.netscape.certsrv.request.RequestStatus; import com.netscape.cmscore.util.Debug; +import com.netscape.cmsutil.http.HttpResponse; public class LocalConnector implements IConnector { ICertAuthority mSource = null; @@ -122,6 +123,11 @@ public class LocalConnector implements IConnector { } } + public HttpResponse send(String op, String r) throws EBaseException { + CMS.debug("LocalConnector send() with String. Should not get here."); + return null; + } + public class LocalConnListener implements IRequestListener { public void init(ISubsystem sys, IConfigStore config) diff --git a/base/server/cmscore/src/com/netscape/cmscore/connector/RemoteAuthority.java b/base/server/cmscore/src/com/netscape/cmscore/connector/RemoteAuthority.java index 71d01579f..ff1e7e9e4 100644 --- a/base/server/cmscore/src/com/netscape/cmscore/connector/RemoteAuthority.java +++ b/base/server/cmscore/src/com/netscape/cmscore/connector/RemoteAuthority.java @@ -17,6 +17,8 @@ // --- END COPYRIGHT BLOCK --- package com.netscape.cmscore.connector; +import java.util.Hashtable; + import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.IConfigStore; import com.netscape.certsrv.connector.IRemoteAuthority; @@ -25,6 +27,8 @@ public class RemoteAuthority implements IRemoteAuthority { String mHost = null; int mPort = -1; String mURI = null; + Hashtable<String, String> mURIs = new Hashtable<String, String>(); + String mContentType = null; int mTimeout = 0; /** @@ -40,9 +44,28 @@ public class RemoteAuthority implements IRemoteAuthority { mTimeout = timeout; } + public RemoteAuthority(String host, int port, Hashtable<String, String>uris, int timeout) { + mHost = host; + mPort = port; + mURIs = uris; + mTimeout = timeout; + } + + public RemoteAuthority(String host, int port, Hashtable<String, String>uris, int timeout, String contentType) { + mHost = host; + mPort = port; + mURIs = uris; + mTimeout = timeout; + if (contentType.equals("")) + mContentType = null; + else + mContentType = contentType; + } + public RemoteAuthority() { } +/*cfu what TODO?*/ public void init(IConfigStore c) throws EBaseException { mHost = c.getString("host"); @@ -63,7 +86,19 @@ public class RemoteAuthority implements IRemoteAuthority { return mURI; } + public String getURI(String name) { + return mURIs.get(name); + } + + public Hashtable<String, String> getURIs() { + return mURIs; + } + public int getTimeout() { return mTimeout; } + + public String getContentType() { + return mContentType; + } } diff --git a/base/server/test/com/netscape/cmscore/app/CMSEngineDefaultStub.java b/base/server/test/com/netscape/cmscore/app/CMSEngineDefaultStub.java index 1e0310e5c..db39964f2 100644 --- a/base/server/test/com/netscape/cmscore/app/CMSEngineDefaultStub.java +++ b/base/server/test/com/netscape/cmscore/app/CMSEngineDefaultStub.java @@ -494,10 +494,18 @@ public class CMSEngineDefaultStub implements ICMSEngine { return null; } + public IHttpConnection getHttpConnection(IRemoteAuthority authority, ISocketFactory factory, String op) { + return null; + } + public IHttpConnection getHttpConnection(IRemoteAuthority authority, ISocketFactory factory, int timeout) { return null; } + public IHttpConnection getHttpConnection(IRemoteAuthority authority, ISocketFactory factory, int timeout, String op) { + return null; + } + public IResender getResender(IAuthority authority, String nickname, IRemoteAuthority remote, int interval) { return null; } diff --git a/base/tps-tomcat/shared/conf/CS.cfg.in b/base/tps-tomcat/shared/conf/CS.cfg.in index 0458bc5cc..f8ce2ae88 100644 --- a/base/tps-tomcat/shared/conf/CS.cfg.in +++ b/base/tps-tomcat/shared/conf/CS.cfg.in @@ -93,125 +93,6 @@ cms.version=@APPLICATION_VERSION_MAJOR@.@APPLICATION_VERSION_MINOR@ config.Generals.General.state=Enabled config.Generals.General.timestamp=1280283607424406 configurationRoot=/[PKI_SUBSYSTEM_TYPE]/conf/ -conn.ca1._000=######################################### -conn.ca1._001=# CA connection -conn.ca1._002=# -conn.ca1._003=# conn.ca<n>.hostport: -conn.ca1._004=# - host name and port number of your CA, format is host:port -conn.ca1._005=# conn.ca<n>.clientNickname: -conn.ca1._006=# - nickname of the client certificate for -conn.ca1._007=# authentication -conn.ca1._008=# conn.ca<n>.servlet.enrollment: -conn.ca1._009=# - servlet to contact in CA -conn.ca1._010=# - must be '/ca/profileSubmitSSLClient' -conn.ca1._011=# conn.ca<n>.retryConnect: -conn.ca1._012=# - number of reconnection attempts on failure -conn.ca1._013=# conn.ca<n>.timeout: -conn.ca1._014=# - connection timeout -conn.ca1._015=# conn.ca<n>.SSLOn: -conn.ca1._016=# - enable SSL or not -conn.ca1._017=# conn.ca<n>.keepAlive: -conn.ca1._018=# - enable keep alive or not -conn.ca1._019=# conn.ca<n>.caNickname: -conn.ca1._020=# - nickname of the ca certificate -conn.ca1._021=# conn.ca<n>.caSKI: -conn.ca1._022=# - Subject Key Identifier (in Base64) of the ca certificate -conn.ca1._023=# (automatically calculated by the system) -conn.ca1._024=# -conn.ca1._025=# conn.ca.list=ca1,ca2...ca<n> -conn.ca1._026=# - list of ca connection IDs for revocation routing -conn.ca1._027=# -conn.ca1._028=# where -conn.ca1._029=# <n> - CA connection ID -conn.ca1._030=######################################### -conn.ca1.clientNickname=[HSM_LABEL][NICKNAME] -conn.ca1.hostport=[PKI_CA_HOSTNAME]:[PKI_CA_PORT] -conn.ca1.keepAlive=true -conn.ca1.retryConnect=3 -conn.ca1.servlet.enrollment=/ca/ee/ca/profileSubmitSSLClient -conn.ca1.servlet.renewal=/ca/ee/ca/profileSubmitSSLClient -conn.ca1.servlet.revoke=/ca/ee/subsystem/ca/doRevoke -conn.ca1.servlet.unrevoke=/ca/ee/subsystem/ca/doUnrevoke -conn.ca1.SSLOn=true -conn.ca1.timeout=100 -conn.drm1._000=######################################### -conn.drm1._001=# DRM connection -conn.drm1._002=# -conn.drm1._003=#conn.drm.totalConns -conn.drm1._004=# - # of DRM connections -conn.drm1._005=#conn.drm<n>.hostport -conn.drm1._006=# - host name and port number of your DRM, the format is host:port -conn.drm1._007=#conn.drm<n>.clientNickname -conn.drm1._008=# - nickname of the client certificate for -conn.drm1._009=# authentication -conn.drm1._010=#conn.drm<n>.servlet.GenerateKeyPair -conn.drm1._011=# - servlet to generate key pairs and archive keys on DRM -conn.drm1._012=# - must be '/kra/GenerateKeyPair' -conn.drm1._013=#conn.drm<n>.servlet.TokenKeyRecovery=/kra/TokenKeyRecovery -conn.drm1._014=# - servlet to handle key recovery -conn.drm1._015=# - must be '/kra/TokenKeyRecovery' -conn.drm1._016=#conn.drm<n>.retryConnect=3 -conn.drm1._017=# - number of reconnection attempts on failure -conn.drm1._018=#conn.drm<n>.SSLOn=true -conn.drm1._019=# - enable SSL or not -conn.drm1._020=#conn.drm<n>.keepAlive=false -conn.drm1._021=# - enable keep alive or not -conn.drm1._022=# -conn.drm1._023=# where -conn.drm1._024=# <n> - DRM connection ID -conn.drm1._025=######################################### -conn.drm1.clientNickname=[HSM_LABEL][NICKNAME] -conn.drm1.hostport=[DRM_HOST]:[DRM_PORT] -conn.drm1.keepAlive=false -conn.drm1.retryConnect=3 -conn.drm1.servlet.GenerateKeyPair=/kra/agent/kra/GenerateKeyPair -conn.drm1.servlet.TokenKeyRecovery=/kra/agent/kra/TokenKeyRecovery -conn.drm1.SSLOn=true -conn.drm1.timeout=100 -conn.drm.totalConns=1 -conn.tks1._000=######################################### -conn.tks1._001=# TKS connection -conn.tks1._002=# -conn.tks1._003=# conn.tks<n>.hostport: -conn.tks1._004=# - host name and port number of your TKS, the format is host:port -conn.tks1._005=# conn.tks<n>.clientNickname: -conn.tks1._006=# - nickname of the client certificate for -conn.tks1._007=# authentication -conn.tks1._008=# conn.tks<n>.servlet.computeSessionKey: -conn.tks1._009=# - servlet to compute session key -conn.tks1._010=# - must be '/tks/computeSessionKey' -conn.tks1._011=# conn.tks<n>.servlet.encryptData: -conn.tks1._012=# - servlet to encrypt data -conn.tks1._013=# - must be '/tks/encryptData' -conn.tks1._014=# conn.tks<n>.servlet.createKeySetData: -conn.tks1._015=# - servlet to create key set data -conn.tks1._016=# - must be '/tks/createKeySetData' -conn.tks1._017=# conn.tks<n>.retryConnect: -conn.tks1._018=# - number of reconnection attempts on failure -conn.tks1._019=# conn.tks<n>.SSLOn -conn.tks1._020=# - enable SSL or not -conn.tks1._021=# conn.tks<n>.keepAlive: -conn.tks1._022=# - enable keep alive or not -conn.tks1._023=# -conn.tks1._024=# where -conn.tks1._025=# <n> - TKS connection ID -conn.tks1._026=# conn.tks<n>.tksSharedSymKeyName: -conn.tks1._027=# - set shared secret key name -conn.tks1._028=######################################### -conn.tks1.clientNickname=[HSM_LABEL][NICKNAME] -conn.tks1.generateHostChallenge=true -conn.tks1.hostport=[TKS_HOST]:[TKS_PORT] -conn.tks1.keepAlive=false -conn.tks1.keySet=defKeySet -conn.tks1.retryConnect=3 -conn.tks1.serverKeygen=[SERVER_KEYGEN] -conn.tks1.servlet.computeRandomData=/tks/agent/tks/computeRandomData -conn.tks1.servlet.computeSessionKey=/tks/agent/tks/computeSessionKey -conn.tks1.servlet.createKeySetData=/tks/agent/tks/createKeySetData -conn.tks1.servlet.encryptData=/tks/agent/tks/encryptData -conn.tks1.SSLOn=true -conn.tks1.timeout=100 -conn.tks1.tksSharedSymKeyName=sharedSecret cs.state=0 cs.type=TPS dbs.ldap=internaldb @@ -437,7 +318,7 @@ op.enroll.soKey.keyGen.encryption.recovery.onHold.revokeCert.reason=6 op.enroll.soKey.keyGen.encryption.recovery.onHold.revokeCert=true op.enroll.soKey.keyGen.encryption.recovery.onHold.scheme=GenerateNewKey op.enroll.soKey.keyGen.encryption.serverKeygen.archive=true -op.enroll.soKey.keyGen.encryption.serverKeygen.drm.conn=drm1 +op.enroll.soKey.keyGen.encryption.serverKeygen.drm.conn=kra1 op.enroll.soKey.keyGen.encryption.serverKeygen.enable=[SERVER_KEYGEN] op.enroll.soKey.keyGen.keyType.num=2 op.enroll.soKey.keyGen.keyType.value.0=signing @@ -589,7 +470,7 @@ op.enroll.soKeyTemporary.keyGen.encryption.recovery.onHold.revokeCert.reason=0 op.enroll.soKeyTemporary.keyGen.encryption.recovery.onHold.revokeCert=true op.enroll.soKeyTemporary.keyGen.encryption.recovery.onHold.scheme=RecoverLast op.enroll.soKeyTemporary.keyGen.encryption.serverKeygen.archive=true -op.enroll.soKeyTemporary.keyGen.encryption.serverKeygen.drm.conn=drm1 +op.enroll.soKeyTemporary.keyGen.encryption.serverKeygen.drm.conn=kra1 op.enroll.soKeyTemporary.keyGen.encryption.serverKeygen.enable=true op.enroll.soKeyTemporary.keyGen.keyType.num=3 op.enroll.soKeyTemporary.keyGen.keyType.value.0=auth @@ -811,7 +692,7 @@ op.enroll.userKey.keyGen.encryption.recovery.onHold.revokeCert.reason=6 op.enroll.userKey.keyGen.encryption.recovery.onHold.revokeCert=true op.enroll.userKey.keyGen.encryption.recovery.onHold.scheme=GenerateNewKey op.enroll.userKey.keyGen.encryption.serverKeygen.archive=true -op.enroll.userKey.keyGen.encryption.serverKeygen.drm.conn=drm1 +op.enroll.userKey.keyGen.encryption.serverKeygen.drm.conn=kra1 op.enroll.userKey.keyGen.encryption.serverKeygen.enable=[SERVER_KEYGEN] op.enroll.userKey.keyGen.keyType.num=2 op.enroll.userKey.keyGen.keyType.value.0=signing @@ -1000,7 +881,7 @@ op.enroll.userKeyTemporary.keyGen.encryption.recovery.onHold.revokeCert.reason=0 op.enroll.userKeyTemporary.keyGen.encryption.recovery.onHold.revokeCert=true op.enroll.userKeyTemporary.keyGen.encryption.recovery.onHold.scheme=RecoverLast op.enroll.userKeyTemporary.keyGen.encryption.serverKeygen.archive=true -op.enroll.userKeyTemporary.keyGen.encryption.serverKeygen.drm.conn=drm1 +op.enroll.userKeyTemporary.keyGen.encryption.serverKeygen.drm.conn=kra1 op.enroll.userKeyTemporary.keyGen.encryption.serverKeygen.enable=true op.enroll.userKeyTemporary.keyGen.keyType.num=3 op.enroll.userKeyTemporary.keyGen.keyType.value.0=auth @@ -1449,8 +1330,8 @@ target.Profiles.displayname=Profile target.Profiles.list=userKey,soKey,soCleanUserToken,soUserKey,cleanToken,soCleanSoToken,tokenKey target.Profiles.pattern=op\..*\.$name\..* target.Subsystem_Connections.displayname=Subsystem Connection -target.Subsystem_Connections.list=ca1,drm1,tks1 -target.Subsystem_Connections.pattern=conn\.$name\..* +target.Subsystem_Connections.list=ca1,kra1,tks1 +target.Subsystem_Connections.pattern=tps.connector\.$name\..* tokendb._000=######################################### tokendb._001=# tokendb.auditLog: tokendb._002=# - audit log path @@ -1602,6 +1483,122 @@ tps.cert.audit_signing.nickname=[HSM_LABEL][NICKNAME] tps.cert.list=sslserver,subsystem,audit_signing tps.cert.sslserver.certusage=SSLServer tps.cert.subsystem.certusage=SSLClient +tps.connector.ca1._001=######################################### +tps.connector.ca1._002=# CA connector +tps.connector.ca1._003=# +tps.connector.ca1._004=# tps.connector.ca<n>.enable: +tps.connector.ca1._005=# - enable this connector or not +tps.connector.ca1._006=# tps.connector.ca<n>.host: +tps.connector.ca1._007=# - for no Failover, host name of the CA +tps.connector.ca1._008=# - for Failover setup, host name and port number +tps.connector.ca1._009=# of your CA, format is host:port separated by a space +tps.connector.ca1._010=# tps.connector.ca<n>.port: +tps.connector.ca1._011=# - for no Failover, port number of the CA +tps.connector.ca1._012=# tps.connector.ca<n>.nickName: +tps.connector.ca1._013=# - nickname of the TPS subsystem certificate for +tps.connector.ca1._014=# SSL client authentication to the CA +tps.connector.ca1._015=# tps.connector.ca<n>.minHttpConns: +tps.connector.ca1._016=# - minimum HTTP connections +tps.connector.ca1._017=# tps.connector.ca<n>.maxHttpConns: +tps.connector.ca1._018=# - maximum HTTP connections +tps.connector.ca1._019=# tps.connector.ca<n>.uri.<op>: +tps.connector.ca1._020=# - uri to contact CA for the operation <op> +tps.connector.ca1._021=# - example ops: enrollment, renewal, revoke, unrevoke +tps.connector.ca1._022=# tps.connector.ca<n>.timeout: +tps.connector.ca1._023=# - connection timeout +tps.connector.ca1._024=######################################### +tps.connector.ca1.enable=false +tps.connector.ca1.host=[PKI_CA_HOSTNAME] +tps.connector.ca1.port=[PKI_CA_PORT] +tps.connector.ca1.minHttpConns=1 +tps.connector.ca1.maxHttpConns=15 +tps.connector.ca1.nickName=[HSM_LABEL]:[NICKNAME] +tps.connector.ca1.timeout=30 +tps.connector.ca1.uri.enrollment=/ca/ee/ca/profileSubmitSSLClient +tps.connector.ca1.uri.renewal=/ca/ee/ca/profileSubmitSSLClient +tps.connector.ca1.uri.revoke=/ca/ee/subsystem/ca/doRevoke +tps.connector.ca1.uri.unrevoke=/ca/ee/subsystem/ca/doUnrevoke +tps.connector.kra1._001=######################################### +tps.connector.kra1._002=# KRA connector +tps.connector.kra1._003=# +tps.connector.kra1._004=# tps.connector.kra<n>.enable: +tps.connector.kra1._005=# - enable this connector or not +tps.connector.kra1._006=# tps.connector.kra<n>.host: +tps.connector.kra1._007=# - for no Failover, host name of the KRA +tps.connector.kra1._008=# - for Failover setup, host name and port number +tps.connector.kra1._009=# of your KRA, format is host:port separated by a space +tps.connector.kra1._010=# tps.connector.kra<n>.port: +tps.connector.kra1._011=# - for no Failover, port number of the KRA +tps.connector.kra1._012=# tps.connector.kra<n>.nickName: +tps.connector.kra1._013=# - nickname of the TPS subsystem certificate for +tps.connector.kra1._014=# SSL client authentication to the KRA +tps.connector.kra1._015=# tps.connector.kra<n>.minHttpConns: +tps.connector.kra1._016=# - minimum HTTP connections +tps.connector.kra1._017=# tps.connector.kra<n>.maxHttpConns: +tps.connector.kra1._018=# - maximum HTTP connections +tps.connector.kra1._019=# tps.connector.kra<n>.uri.<op>: +tps.connector.kra1._020=# - uri to contact KRA for the operation <op> +tps.connector.kra1._021=# - example ops: GenerateKeyPair, TokenKeyRecovery +tps.connector.kra1._022=# tps.connector.kra<n>.timeout: +tps.connector.kra1._023=# - connection timeout +tps.connector.kra1._024=######################################### +tps.connector.kra1.enable=false +tps.connector.kra1.host=[DRM_HOST] +tps.connector.kra1.port=[DRM_PORT] +tps.connector.kra1.minHttpConns=1 +tps.connector.kra1.maxHttpConns=15 +tps.connector.kra1.nickName=[HSM_LABEL]:[NICKNAME] +tps.connector.kra1.timeout=30 +tps.connector.kra1.uri.GenerateKeyPair=/kra/agent/kra/connector +tps.connector.kra1.uri.TokenKeyRecovery=/kra/agent/kra/TokenKeyRecovery +tps.connector.tks1._001=######################################### +tps.connector.tks1._002=# TKS connector +tps.connector.tks1._003=# +tps.connector.tks1._004=# tps.connector.tks<n>.enable: +tps.connector.tks1._005=# - enable this connector or not +tps.connector.tks1._006=# tps.connector.tks<n>.host: +tps.connector.tks1._007=# - for no Failover, host name of the TKS +tps.connector.tks1._008=# - for Failover setup, host name and port number +tps.connector.tks1._009=# of your TKS, format is host:port separated by a space +tps.connector.tks1._010=# tps.connector.tks<n>.port: +tps.connector.tks1._011=# - for no Failover, port number of the TKS +tps.connector.tks1._012=# tps.connector.tks<n>.nickName: +tps.connector.tks1._013=# - nickname of the TPS subsystem certificate for +tps.connector.tks1._014=# SSL client authentication to the TKS +tps.connector.tks1._015=# tps.connector.tks<n>.minHttpConns: +tps.connector.tks1._016=# - minimum HTTP connections +tps.connector.tks1._017=# tps.connector.tks<n>.maxHttpConns: +tps.connector.tks1._018=# - maximum HTTP connections +tps.connector.tks1._019=# tps.connector.tks<n>.uri.<op>: +tps.connector.tks1._020=# - uri to contact TKS for the operation <op> +tps.connector.tks1._021=# - example ops: computeRandomData, computeSessionKey, +tps.connector.tks1._022=# createKeySetData, encryptData +tps.connector.tks1._023=# tps.connector.tks<n>.timeout: +tps.connector.tks1._024=# - connection timeout +tps.connector.tks1._025=# tps.connector.tks<n>.generateHostChallenge: +tps.connector.tks1._026=# - generate host challenge or not +tps.connector.tks1._027=# tps.connector.tks<n>.serverKeygen: +tps.connector.tks1._028=# - generate keys on server side or not +tps.connector.tks1._029=# tps.connector.tks<n>.keySet: +tps.connector.tks1._030=# - keySet to be used on tks +tps.connector.tks1._031=# tps.connector.tks<n>.tksSharedSymKeyName +tps.connector.tks1._032=# - shared secret key name +tps.connector.tks1._033=######################################### +tps.connector.tks1.enable=false +tps.connector.tks1.host=[TKS_HOST] +tps.connector.tks1.port=[TKS_PORT] +tps.connector.tks1.minHttpConns=1 +tps.connector.tks1.maxHttpConns=15 +tps.connector.tks1.nickName=[HSM_LABEL]:[NICKNAME] +tps.connector.tks1.timeout=30 +tps.connector.tks1.generateHostChallenge=true +tps.connector.tks1.serverKeygen=[SERVER_KEYGEN] +tps.connector.tks1.keySet=defKeySet +tps.connector.tks1.tksSharedSymKeyName=sharedSecret +tps.connector.tks1.uri.computeRandomData=/tks/agent/tks/computeRandomData +tps.connector.tks1.uri.computeSessionKey=/tks/agent/tks/computeSessionKey +tps.connector.tks1.uri.createKeySetData=/tks/agent/tks/createKeySetData +tps.connector.tks1.uri.encryptData=/tks/agent/tks/encryptData tps.operations.allowedTransitions=0:0,0:4,4:0 usrgrp._000=## usrgrp._001=## User/Group diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSSubsystem.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSSubsystem.java index eb279d819..c8386bf8e 100644 --- a/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSSubsystem.java +++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSSubsystem.java @@ -21,6 +21,7 @@ import org.dogtagpki.server.tps.config.ConfigDatabase; import org.dogtagpki.server.tps.config.ConnectionDatabase; import org.dogtagpki.server.tps.config.ProfileDatabase; import org.dogtagpki.server.tps.config.ProfileMappingDatabase; +import org.dogtagpki.server.tps.cms.ConnectionManager; import org.dogtagpki.server.tps.dbs.ActivityDatabase; import org.dogtagpki.server.tps.dbs.AuthenticatorDatabase; import org.dogtagpki.server.tps.dbs.TPSCertDatabase; @@ -63,6 +64,7 @@ public class TPSSubsystem implements IAuthority, ISubsystem { public ProfileDatabase profileDatabase; public ProfileMappingDatabase profileMappingDatabase; public TokenDatabase tokenDatabase; + public ConnectionManager connManager; @Override public String getId() { @@ -100,6 +102,10 @@ public class TPSSubsystem implements IAuthority, ISubsystem { @Override public void startup() throws EBaseException { + CMS.debug("TPSSubsystem: startup() begins"); + connManager = new ConnectionManager(); + connManager.initConnectors(); + CMS.debug("TPSSubsystem: startup() ends."); } @Override @@ -175,6 +181,10 @@ public class TPSSubsystem implements IAuthority, ISubsystem { return tokenDatabase; } + public ConnectionManager getConnectionManager() { + return connManager; + } + public org.mozilla.jss.crypto.X509Certificate getSubsystemCert() throws EBaseException, NotInitializedException, ObjectNotFoundException, TokenException { IConfigStore cs = CMS.getConfigStore(); diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/cms/ConnectionManager.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/cms/ConnectionManager.java new file mode 100644 index 000000000..c9b88f178 --- /dev/null +++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/cms/ConnectionManager.java @@ -0,0 +1,226 @@ +// --- 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 org.dogtagpki.server.tps.cms; + +import java.io.ByteArrayInputStream; +import java.util.Enumeration; +import java.util.Hashtable; +import javax.ws.rs.core.MediaType; + +import org.dogtagpki.server.tps.TPSSubsystem; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IConfigStore; +import com.netscape.certsrv.connector.IConnector; +import com.netscape.cmscore.connector.HttpConnector; +import com.netscape.cmscore.connector.RemoteAuthority; +import com.netscape.cmsutil.xml.XMLObject; + +/** + * ConnectionManager is a class for connection management + * of its Remote Authorities + * @author cfu + */ +public class ConnectionManager +{ + private Hashtable<String, IConnector> connectors; + + public ConnectionManager() { + } + + /* + * connector establishment with multi-uri support + * + * Initialize all connectors + * tps.connector.<connID>.xxx + * + * e.g. (with Failover list under "host", separated by a space) + * + * tps.connector.ca1.enable=true + * tps.connector.ca1.minHttpConns=1 + * tps.connector.ca1.maxHttpConns=15 + * tps.connector.ca1.host=host1.EXAMPLE.com:8445 host2.EXAMPLE.com:8445 + * tps.connector.ca1.port=<port number; unused if for failover case> + * tps.connector.ca1.nickName=subsystemCert cert-pki-tomcat TPS + * tps.connector.ca1.timeout=30 + * # In the example below, + * # "enrollment", "renewal", "revoke", and "unrevoke" + * # are what's being referred to as "op" in the multi-uri support code + * tps.connector.ca1.uri.enrollment=/ca/ee/ca/profileSubmitSSLClient + * tps.connector.ca1.uri.renewal=/ca/ee/ca/profileSubmitSSLClient + * tps.connector.ca1.uri.revoke=/ca/ee/subsystem/ca/doRevoke + * tps.connector.ca1.uri.unrevoke=/ca/ee/subsystem/ca/doUnrevoke + */ + public void initConnectors() throws EBaseException { + CMS.debug("ConnectionManager: initConnectors(): begins."); + TPSSubsystem subsystem = + (TPSSubsystem)CMS.getSubsystem(TPSSubsystem.ID); + IConfigStore conf = subsystem.getConfigStore(); + IConfigStore connectorSubstore = conf.getSubStore("connector"); + Enumeration<String> connector_enu = connectorSubstore.getSubStoreNames(); + connectors = new Hashtable<String, IConnector>(); + while (connector_enu.hasMoreElements()) { + String connectorID = connector_enu.nextElement(); + CMS.debug("ConnectionManager: initConnectors(): initializing connector "+connectorID); + IConfigStore connectorConfig = + connectorSubstore.getSubStore(connectorID); + IConnector conn = null; + boolean enable = connectorConfig.getBoolean("enable", false); + if (!enable) { + CMS.debug("ConnectionManager: initConnectors(): connector disabled."); + continue; + } + CMS.debug("ConnectionManager: initConnectors(): connector enabled."); + conn = createConnector(connectorConfig); + + connectors.put(connectorID, conn); + CMS.debug("ConnectionManager: initConnectors(): connector " + +connectorID+ + " initialized."); + } + CMS.debug("ConnectionManager: initConnectors(): ends."); + } + + /* + * Creates and returns a connector + * + * @param conf config store of the connector + * @return IConnector the connector if created successfully; null if not + */ + private IConnector createConnector(IConfigStore conf) + throws EBaseException { + IConnector connector = null; + + CMS.debug("ConnectionManager: createConnector(): begins."); + if (conf== null || conf.size() <= 0) { + CMS.debug("ConnectionManager: createConnector(): conf null or empty."); + throw new EBaseException("called with null config store"); + } + + String host = conf.getString("host"); + if (host == null) { + CMS.debug("ConnectionManager: createConnector(): host not found in config."); + throw new EBaseException("host not found in config"); + } + // port doesn't have to contain anything if failover supplied in host + int port = conf.getInteger("port"); + + Hashtable<String, String> uris = new Hashtable<String, String>(); + IConfigStore uriSubstore = conf.getSubStore("uri"); + if (uriSubstore == null) { + CMS.debug("ConnectionManager: createConnector(): uri(s) not found in config."); + throw new EBaseException("uri(s) not found in config"); + } + CMS.debug("ConnectionManager: createConnector(): uriSubstore name="+uriSubstore.getName()+" size =" +uriSubstore.size()); + + Enumeration<String> uri_enu = uriSubstore.getPropertyNames(); + while (uri_enu.hasMoreElements()) { + String op = uri_enu.nextElement(); + if ((op != null) && !op.equals("")) + CMS.debug("ConnectionManager: createConnector(): op name="+op); + else + continue; + + String uriValue = uriSubstore.getString(op); + if ((uriValue != null) && !uriValue.equals("")) + CMS.debug("ConnectionManager: createConnector(): uri value="+uriValue); + else + continue; + uris.put(op, uriValue); + } + + String nickname = conf.getString("nickName", null); + if (nickname != null) + CMS.debug("ConnectionManager: createConnector(): nickName="+nickname); + else { + CMS.debug("ConnectionManager: createConnector(): nickName not found in config"); + throw new EBaseException("nickName not found in config"); + } + + // "resendInterval" is for Request Queue, and not supported in TPS + int resendInterval = -1; + int timeout = conf.getInteger("timeout", 0); + RemoteAuthority remauthority = + new RemoteAuthority(host, port, uris, timeout, MediaType.APPLICATION_FORM_URLENCODED); + + CMS.debug("ConnectionManager: createConnector(): establishing HttpConnector"); + if (timeout == 0) { + connector = + new HttpConnector(null, nickname, remauthority, resendInterval, conf); + } else { + connector = + new HttpConnector(null, nickname, remauthority, resendInterval, conf, timeout); + } + + CMS.debug("ConnectionManager: createConnector(): ends."); + return connector; + } + + /* + * Gets an established connector to be used to send requests + * to a remote Authority (Note that Failover is supported in the + * underlying connector framework. + * + * Example usage (with example config for "ca1" defined above + * in initConnectors(): + * + * TPSSubsystem subsystem = (TPSSubsystem)CMS.getSubsystem(TPSSubsystem.ID); + * HttpConnector testConn = + * (HttpConnector) subsystem.getConnectionManager().getConnector(connectionID); + * HttpResponse resp = + * testConn.send("renewal", + * "serial_num=6&profileId=caTokenUserEncryptionKeyRenewal&renewal=true"); + * if (resp != null) { + * CMS.debug("Connector test: HttpResponse content:"+ + * resp.getContent()); + * } else { + * CMS.debug("Connector test: HttpResponse content null"); + * } + * + * @param connID connection id per defined in the configuration + * @return IConnector the connector matching the connection id + */ + public IConnector getConnector(String connID) { + return connectors.get(connID); + } + + /* + * Get the XML parser for XML in text + * + * @param text XML in text + * @return XMLObject the parser + */ + public XMLObject getXMLParser(String text) { + if (text == null) { + return null; + } else { + CMS.debug("ConnectionManager: getXMLparser(): parsing: "+ text); + } + try { + ByteArrayInputStream bis = + new ByteArrayInputStream(text.getBytes()); + return new XMLObject(bis); + } catch (Exception e) { + CMS.debug("ConnectionManager: getXMLparser(): failed: "+ e); + throw new RuntimeException(e); + } + } + +} |