During my tests I've experienced some performance problems when archiving SignServer responses on a database. In the forum I've discovered that this is a known problem, so I'd like to share this archiver I've made in order to accomplish something similar to the OldDatabaseArchiver but that performs at very fast speeds. The only difference is that the stored data is the Base64 encoding of the data (as byte) and not the serialization of the object.
I've tested successfully with a Time Stamp Signer: on my testing environment (SignServer 3.2.1 on JBoss 5.1.0, remote Oracle 11g) I've passed from 3 seconds to archive the time stamp response to 0.06 seconds! ;-) I've also tested stressing SignServer with 100 threads requesting 10 time stamps in parallel, the test completed in 55 seconds. Instead 10 threads requesting 10 time stamps completed in 7 seconds.
If the project developers want to include it in the project (maybe adjusting it), I'll be very glad. Unfortunately I'm not a Java developer so for me it's very difficult to do unit test classes and source control on sourceforge.
In order to use it you have to put the following properties in the worker configuration:
DIRECTARCHIVER.ISDISABLED is used to dinamically activate or deactivate the new archiver without touching the ARCHIVERS variable. Instead DIRECTARCHIVER.CONNECTIONNAME contain the Java DataSource name as registered on the application server (you can take it inside signserver-ds.xml).
Here is the code:
/****************************************************************************SignServer:TheOpenSourceAutomatedSigningServer****Thissoftwareisfreesoftware;youcanredistributeitand/or**modifyitunderthetermsoftheGNULesserGeneralPublic**LicenseaspublishedbytheFreeSoftwareFoundation;either**version2.1oftheLicense,oranylaterversion.****Seetermsoflicenseatgnu.org.****************************************************************************/packageorg.signserver.server.archive;importjava.security.cert.X509Certificate;importorg.signserver.common.ArchiveDataVO;importorg.signserver.common.RequestContext;importorg.signserver.common.WorkerConfig;importorg.signserver.server.SignServerContext;importorg.signserver.server.archive.Archivable;importorg.signserver.server.archive.ArchiveException;importorg.signserver.server.archive.Archiver;importorg.ejbca.util.Base64;importjava.security.cert.X509Certificate;importjava.util.ArrayList;importjava.util.Date;importjavax.persistence.EntityManager;importorg.apache.log4j.Logger;importorg.ejbca.util.CertTools;importorg.signserver.common.ArchiveData;importorg.signserver.server.archive.olddbarchiver.ArchiveDataArchivable;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;importjavax.naming.Context;importjavax.naming.InitialContext;importjavax.sql.DataSource;importorg.apache.log4j.Logger;importorg.ejbca.core.ejb.ServiceLocator;importorg.ejbca.core.ejb.ServiceLocatorException;/***ArchiveronlyacceptingresponsesandcurrentlyonlysupportsArchivablesof*classArchiveDataArchivable.**Developers:*ThisclasscouldbeimprovedtosupportanyArchivableifthe*DirectDatabaseArchivershouldbeabletobeusedwithworkersnotreturning*ArchiveDataobjectanymore.**@authorDiegodeFelice*/publicclassDirectDatabaseArchiverimplementsArchiver{privatestaticfinalLoggerLOG=Logger.getLogger(DirectDatabaseArchiver.class);privatebooleanm_IsDisabled;privateDataSourcem_datasource=null;@Overridepublicvoidinit(intlistIndex,WorkerConfigconfig,SignServerContextcontext){try{LOG.info("Configuring Direct Archiver "+listIndex);m_IsDisabled=Boolean.parseBoolean(config.getProperty("DIRECTARCHIVER.ISDISABLED","false"));String_ConnectionName=config.getProperty("DIRECTARCHIVER.CONNECTIONNAME");if(_ConnectionName==null){LOG.info("DIRECTARCHIVER.CONNECTIONNAME property not configured");m_IsDisabled=true;}else{LOG.info("Using connection name: "+_ConnectionName);}if(!m_IsDisabled){StringDS_Context="java:"+_ConnectionName;ContextinitialContext=newInitialContext();if(initialContext==null){LOG.info("JNDI problem. Cannot get InitialContext.");thrownewException("JNDI problem. Cannot get InitialContext.");}m_datasource=(DataSource)initialContext.lookup(DS_Context);LOG.info("Configured Direct Archiver "+listIndex);}}catch(Exceptionex){LOG.info("Cannot archive data: "+ex);m_IsDisabled=true;}}@Overridepublicbooleanarchive(Archivablearchivable,RequestContextrequestContext)throwsArchiveException{booleanarchived=false;if(!m_IsDisabled&&Archivable.TYPE_RESPONSE.equals(archivable.getType())&&archivableinstanceofArchiveDataArchivable){finalArchiveDataArchivableada=(ArchiveDataArchivable)archivable;finalIntegerworkerId=(Integer)requestContext.get(RequestContext.WORKER_ID);finalX509Certificatecertificate=(X509Certificate)requestContext.get(RequestContext.CLIENT_CERTIFICATE);finalStringremoteIp=(String)requestContext.get(RequestContext.REMOTE_IP);StringuniqueId=ArchiveDataVO.TYPE_RESPONSE+";"+workerId+";"+ada.getArchiveId();LOG.info("Creating archive data, uniqueId="+uniqueId);PreparedStatement_statement=null;Connection_connection=null;try{if(m_datasource!=null){_connection=m_datasource.getConnection();}else{LOG.info("Failed: datasource was null");thrownewException("Failed: datasource was null");}String_requestIssuerDn=null;String_requestSn=null;if(certificate!=null){_requestIssuerDn=CertTools.getIssuerDN(certificate);_requestSn=certificate.getSerialNumber().toString(16);}String_queryString="INSERT INTO ARCHIVEDATA( UNIQUEID, ARCHIVEDATA, ARCHIVEID, REQUESTCERTSERIALNUMBER, REQUESTIP, REQUESTISSUERDN, SIGNERID, TIME, TYPE ) VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ? )";_connection.setAutoCommit(false);_statement=_connection.prepareStatement(_queryString);_statement.setString(1,uniqueId);_statement.setString(2,newString(Base64.encode(ada.getContentEncoded())));_statement.setString(3,ada.getArchiveId());_statement.setString(4,_requestSn);_statement.setString(5,remoteIp);_statement.setString(6,_requestIssuerDn);_statement.setInt(7,workerId);_statement.setLong(8,newDate().getTime());_statement.setInt(9,(int)ArchiveDataVO.TYPE_RESPONSE);int_nrows=_statement.executeUpdate();_connection.commit();if(_nrows==0){LOG.info("Cannot archive");}LOG.info("Archived data, uniqueId="+uniqueId);archived=true;}catch(Exceptionex){LOG.info("Cannot archive data: "+ex);}finally{try{if(_statement!=null){_statement.close();}if(_connection!=null){_connection.setAutoCommit(true);_connection.close();}}catch(Exceptionex){LOG.info("Cannot finalize: "+ex);}}}returnarchived;}}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello to all,
During my tests I've experienced some performance problems when archiving SignServer responses on a database. In the forum I've discovered that this is a known problem, so I'd like to share this archiver I've made in order to accomplish something similar to the OldDatabaseArchiver but that performs at very fast speeds. The only difference is that the stored data is the Base64 encoding of the data (as byte) and not the serialization of the object.
I've tested successfully with a Time Stamp Signer: on my testing environment (SignServer 3.2.1 on JBoss 5.1.0, remote Oracle 11g) I've passed from 3 seconds to archive the time stamp response to 0.06 seconds! ;-) I've also tested stressing SignServer with 100 threads requesting 10 time stamps in parallel, the test completed in 55 seconds. Instead 10 threads requesting 10 time stamps completed in 7 seconds.
If the project developers want to include it in the project (maybe adjusting it), I'll be very glad. Unfortunately I'm not a Java developer so for me it's very difficult to do unit test classes and source control on sourceforge.
In order to use it you have to put the following properties in the worker configuration:
ARCHIVERS=org.signserver.server.archive.DirectDatabaseArchiver
DIRECTARCHIVER.ISDISABLED=false
DIRECTARCHIVER.CONNECTIONNAME=SignServerDS
DIRECTARCHIVER.ISDISABLED is used to dinamically activate or deactivate the new archiver without touching the ARCHIVERS variable. Instead DIRECTARCHIVER.CONNECTIONNAME contain the Java DataSource name as registered on the application server (you can take it inside signserver-ds.xml).
Here is the code:
Cool, thanks! I created https://jira.primekey.se/browse/DSS-445