aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2015-02-23 11:27:59 +0100
committerAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2015-02-23 11:27:59 +0100
commit4973b940cc8ce0885653ed7c0223cbedd3dde3bc (patch)
treed711ed5b272631c9a24cd346a19e2c0b6426f83e
parentfee3c9a59945a2ee74029dfe63c074c753a51dbf (diff)
downloadpdf-as-4-4973b940cc8ce0885653ed7c0223cbedd3dde3bc.tar.gz
pdf-as-4-4973b940cc8ce0885653ed7c0223cbedd3dde3bc.tar.bz2
pdf-as-4-4973b940cc8ce0885653ed7c0223cbedd3dde3bc.zip
added Statistics Facilities to PDF-AS Web
-rw-r--r--pdf-as-web-statistic-api/build.gradle39
-rw-r--r--pdf-as-web-statistic-api/src/main/java/at/gv/egiz/pdfas/web/stats/StatisticBackend.java6
-rw-r--r--pdf-as-web-statistic-api/src/main/java/at/gv/egiz/pdfas/web/stats/StatisticEvent.java206
-rw-r--r--pdf-as-web/build.gradle1
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java16
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/UserAgentFilter.java59
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java14
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java2
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ErrorPage.java18
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java70
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java14
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/UIEntryPointServlet.java16
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/VerifyServlet.java62
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/stats/StatisticFrontend.java111
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/stats/impl/StatisticFileBackend.java56
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/store/IRequestStore.java4
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/store/InMemoryRequestStore.java14
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ws/PDFASSigningImpl.java44
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ws/PDFASVerificationImpl.java36
-rw-r--r--pdf-as-web/src/main/resources/META-INF/services/at.gv.egiz.pdfas.web.stats.StatisticBackend1
-rw-r--r--pdf-as-web/src/main/webapp/WEB-INF/web.xml11
-rw-r--r--settings.gradle2
22 files changed, 785 insertions, 17 deletions
diff --git a/pdf-as-web-statistic-api/build.gradle b/pdf-as-web-statistic-api/build.gradle
new file mode 100644
index 00000000..5de4630a
--- /dev/null
+++ b/pdf-as-web-statistic-api/build.gradle
@@ -0,0 +1,39 @@
+apply plugin: 'java'
+apply plugin: 'war'
+apply plugin: 'eclipse'
+apply plugin: 'java-library-distribution'
+
+jar {
+ manifest {
+ attributes 'Implementation-Title': 'PDF-AS-4 Web Statistic Library', 'JARMANIFEST': 'PDF-AS-LIB'
+ }
+}
+
+repositories {
+ mavenLocal()
+ mavenCentral()
+}
+
+configurations { providedCompile }
+
+sourceSets.main.compileClasspath += configurations.providedCompile
+sourceSets.test.compileClasspath += configurations.providedCompile
+sourceSets.test.runtimeClasspath += configurations.providedCompile
+
+dependencies {
+ compile group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion
+ compile 'org.apache.commons:commons-lang3:3.3.2'
+ testCompile group: 'junit', name: 'junit', version: '4.+'
+}
+
+task releases(type: Copy) {
+ from jar.outputs
+ from distZip.outputs
+ from distTar.outputs
+ into rootDir.toString() + "/releases/" + version
+}
+
+releases.dependsOn jar
+releases.dependsOn sourcesJar
+releases.dependsOn distZip
+releases.dependsOn distTar
diff --git a/pdf-as-web-statistic-api/src/main/java/at/gv/egiz/pdfas/web/stats/StatisticBackend.java b/pdf-as-web-statistic-api/src/main/java/at/gv/egiz/pdfas/web/stats/StatisticBackend.java
new file mode 100644
index 00000000..0d38f2d7
--- /dev/null
+++ b/pdf-as-web-statistic-api/src/main/java/at/gv/egiz/pdfas/web/stats/StatisticBackend.java
@@ -0,0 +1,6 @@
+package at.gv.egiz.pdfas.web.stats;
+
+public interface StatisticBackend {
+ public String getName();
+ public void storeEvent(StatisticEvent statisticEvent);
+}
diff --git a/pdf-as-web-statistic-api/src/main/java/at/gv/egiz/pdfas/web/stats/StatisticEvent.java b/pdf-as-web-statistic-api/src/main/java/at/gv/egiz/pdfas/web/stats/StatisticEvent.java
new file mode 100644
index 00000000..b1c5de11
--- /dev/null
+++ b/pdf-as-web-statistic-api/src/main/java/at/gv/egiz/pdfas/web/stats/StatisticEvent.java
@@ -0,0 +1,206 @@
+package at.gv.egiz.pdfas.web.stats;
+
+import java.util.Date;
+
+
+/**
+ * Timestamp; [Der Zeitpunkt des Signaturvorgangs]
+Operation; [Die Operation des Signaturvorgangs (SIGN | VERIFY) ]
+Signaturemode; [Der Siganturemode (BINARY | TEXTUAL) default BINARY]
+Device; [Das Signaturgeraet (bku (lokale BKU) | moa (configured moa instance) | moc (online bku MOCCA) | mobile (Handy Signatur))]
+ProfileId; [Das verwendete Signaturprofil ein Beispiel waere: SIGNATURBLOCK_DE]
+Filesize; [Die Dateigroesse des PDF Dokuments]
+User Agent; [Der User-Agent (wenn verfuegbar)]
+Status; [Der Status der Operation: (OK | ERROR)]
+Exception Class; [Exception Klasse falls ein Fehler vorliegt]
+ErrorCode; [Exception Code falls ein Fehler vorliegt]
+External Errorcode; [Exception Code von externer Componente falls vorhanden]
+Duration [Verbrauchte Zeit fuer diese Operation in Millisekunden, wenn feststellbar]
+ * @author Andreas Fitzek
+ *
+ */
+public class StatisticEvent {
+
+ public enum Operation {
+ SIGN("sign"),
+ VERIFY("verify");
+
+ private String name;
+
+ private Operation(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+ }
+
+ public enum Source {
+ WEB("web"),
+ SOAP("soap");
+
+ private String name;
+
+ private Source(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+ }
+
+ public enum Status {
+ OK("ok"),
+ ERROR("error");
+
+ private String name;
+
+ private Status(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+ }
+
+ private long timestamp;
+ private Operation operation;
+ private String device;
+ private String profileId;
+ private long filesize;
+ private String userAgent;
+ private Status status;
+ private Throwable exception;
+ private long errorCode;
+ private long start;
+ private long end;
+ private Source source;
+ private boolean logged = false;
+
+ public StatisticEvent() {
+
+ }
+
+ public long getStart() {
+ return start;
+ }
+
+ public void setStart(long start) {
+ this.start = start;
+ }
+
+ public void setStartNow() {
+ this.start = (new Date()).getTime();
+ }
+
+ public long getEnd() {
+ return end;
+ }
+
+ public void setEnd(long end) {
+ this.end = end;
+ }
+
+ public void setEndNow() {
+ this.end = (new Date()).getTime();
+ }
+
+ public Source getSource() {
+ return source;
+ }
+
+ public void setSource(Source source) {
+ this.source = source;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public void setTimestampNow() {
+ this.timestamp = (new Date()).getTime();
+ }
+
+ public Operation getOperation() {
+ return operation;
+ }
+
+ public void setOperation(Operation operation) {
+ this.operation = operation;
+ }
+
+ public String getDevice() {
+ return device;
+ }
+
+ public void setDevice(String device) {
+ this.device = device;
+ }
+
+ public String getProfileId() {
+ return profileId;
+ }
+
+ public void setProfileId(String profileId) {
+ this.profileId = profileId;
+ }
+
+ public long getFilesize() {
+ return filesize;
+ }
+
+ public void setFilesize(long filesize) {
+ this.filesize = filesize;
+ }
+
+ public String getUserAgent() {
+ return userAgent;
+ }
+
+ public void setUserAgent(String userAgent) {
+ this.userAgent = userAgent;
+ }
+
+ public Status getStatus() {
+ return status;
+ }
+
+ public void setStatus(Status status) {
+ this.status = status;
+ }
+
+ public Throwable getException() {
+ return exception;
+ }
+
+ public void setException(Throwable exception) {
+ this.exception = exception;
+ }
+
+ public long getErrorCode() {
+ return errorCode;
+ }
+
+ public void setErrorCode(long errorCode) {
+ this.errorCode = errorCode;
+ }
+
+ public long getDuration() {
+ return this.end - this.start;
+ }
+
+ public boolean isLogged() {
+ return logged;
+ }
+
+ public void setLogged(boolean logged) {
+ this.logged = logged;
+ }
+}
diff --git a/pdf-as-web/build.gradle b/pdf-as-web/build.gradle
index 908a8d41..31c34ac6 100644
--- a/pdf-as-web/build.gradle
+++ b/pdf-as-web/build.gradle
@@ -28,6 +28,7 @@ dependencies {
compile project (':signature-standards:sigs-pades')
compile project (':pdf-as-pdfbox')
compile project (':pdf-as-web-status')
+ compile project (':pdf-as-web-statistic-api')
compile group: 'commons-fileupload', name: 'commons-fileupload', version: '1.3.1'
compile group: 'opensymphony', name: 'sitemesh', version: '2.4.2'
compile "commons-codec:commons-codec:1.9"
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java
index 46430724..8404fa65 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java
@@ -47,7 +47,8 @@ public class WebConfiguration implements IConfigurationConstants {
public static final String MOBILE_BKU_URL = "bku.mobile.url";
public static final String ERROR_DETAILS = "error.showdetails";
public static final String PDF_AS_WORK_DIR = "pdfas.dir";
-
+ public static final String STATISTIC_BACKEND_LIST = "statistic.backends";
+
public static final String MOA_SS_ENABLED = "moa.enabled";
public static final String SOAP_SIGN_ENABLED = "soap.sign.enabled";
public static final String SOAP_VERIFY_ENABLED = "soap.verify.enabled";
@@ -252,6 +253,19 @@ public class WebConfiguration implements IConfigurationConstants {
return properties.getProperty(KEYSTORE_LIST + "." + keyIdentifier + "." + KEYSTORE_KEY_PASS);
}
+ public static List<String> getStatisticBackends() {
+ List<String> statisticBackends = new ArrayList<String>();
+ String commaList = properties.getProperty(STATISTIC_BACKEND_LIST);
+ if(commaList != null) {
+ String[] commaLists = commaList.split(",");
+ for(int i = 0; i < commaLists.length; i++) {
+ statisticBackends.add(commaLists[i].trim());
+ }
+ return statisticBackends;
+ }
+ return null;
+ }
+
public static boolean getMOASSEnabled() {
String value = properties.getProperty(MOA_SS_ENABLED);
if (value != null) {
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/UserAgentFilter.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/UserAgentFilter.java
new file mode 100644
index 00000000..504cf472
--- /dev/null
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/UserAgentFilter.java
@@ -0,0 +1,59 @@
+package at.gv.egiz.pdfas.web.filter;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class UserAgentFilter implements Filter {
+
+ private static final Logger logger = LoggerFactory
+ .getLogger(UserAgentFilter.class);
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ // TODO Auto-generated method stub
+
+ }
+
+ private static final ThreadLocal<String> requestUserAgent = new ThreadLocal<String>() {
+
+ @Override
+ protected String initialValue() {
+ return "unkown";
+ }
+
+ };
+
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response,
+ FilterChain chain) throws IOException, ServletException {
+ if(request instanceof HttpServletRequest) {
+ logger.debug("Processing Parameters into Attributes");
+ HttpServletRequest httpRequest = (HttpServletRequest)request;
+ requestUserAgent.set(httpRequest.getHeader("User-Agent"));
+ }
+ try {
+ chain.doFilter(request, response);
+ } finally {
+ requestUserAgent.remove();
+ }
+ }
+
+ @Override
+ public void destroy() {
+ }
+
+ public static String getUserAgent() {
+ return requestUserAgent.get();
+ }
+
+}
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java
index 93faf99a..5f8bfdcb 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java
@@ -75,6 +75,7 @@ import at.gv.egiz.pdfas.sigs.pades.PAdESSignerKeystore;
import at.gv.egiz.pdfas.web.config.WebConfiguration;
import at.gv.egiz.pdfas.web.exception.PdfAsWebException;
import at.gv.egiz.pdfas.web.servlets.UIEntryPointServlet;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent;
import at.gv.egiz.sl.schema.CreateCMSSignatureResponseType;
import at.gv.egiz.sl.schema.InfoboxAssocArrayPairType;
import at.gv.egiz.sl.schema.InfoboxReadRequestType;
@@ -90,6 +91,7 @@ public class PdfAsHelper {
private static final String PDF_STATUS = "PDF_STATUS";
private static final String PDF_OUTPUT = "PDF_OUTPUT";
private static final String PDF_SL_CONNECTOR = "PDF_SL_CONNECTOR";
+ private static final String PDF_STATISTICS = "PDF_STATISTICS";
private static final String PDF_SIGNER = "PDF_SIGNER";
private static final String PDF_SL_INTERACTIVE = "PDF_SL_INTERACTIVE";
private static final String PDF_SIGNED_DATA = "PDF_SIGNED_DATA";
@@ -876,6 +878,18 @@ public class PdfAsHelper {
HttpSession session = request.getSession();
session.setAttribute(PDF_SIGNED_DATA, signedData);
}
+
+ public static void setStatisticEvent(HttpServletRequest request,
+ HttpServletResponse response, StatisticEvent event) {
+ HttpSession session = request.getSession();
+ session.setAttribute(PDF_STATISTICS, event);
+ }
+
+ public static StatisticEvent getStatisticEvent(HttpServletRequest request,
+ HttpServletResponse response) {
+ HttpSession session = request.getSession();
+ return (StatisticEvent)session.getAttribute(PDF_STATISTICS);
+ }
public static void setLocale(HttpServletRequest request,
HttpServletResponse response, String locale) {
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java
index 86bef9f3..5b3fe82a 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java
@@ -26,6 +26,7 @@ package at.gv.egiz.pdfas.web.servlets;
import java.io.IOException;
import javax.servlet.ServletException;
+import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -44,6 +45,7 @@ import at.gv.egiz.sl.util.SLMarschaller;
/**
* Servlet implementation class DataURL
*/
+@MultipartConfig
public class DataURLServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ErrorPage.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ErrorPage.java
index 8e59ff1c..4be3d7dd 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ErrorPage.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ErrorPage.java
@@ -35,10 +35,14 @@ import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import at.gv.egiz.pdfas.common.exceptions.PDFASError;
import at.gv.egiz.pdfas.web.config.WebConfiguration;
import at.gv.egiz.pdfas.web.helper.HTMLFormater;
import at.gv.egiz.pdfas.web.helper.PdfAsHelper;
import at.gv.egiz.pdfas.web.helper.UrlParameterExtractor;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent;
+import at.gv.egiz.pdfas.web.stats.StatisticFrontend;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent.Status;
/**
* Servlet implementation class ErrorPage
@@ -88,6 +92,20 @@ public class ErrorPage extends HttpServlet {
String errorURL = PdfAsHelper.getErrorURL(request, response);
Throwable e = PdfAsHelper
.getSessionException(request, response);
+
+ StatisticEvent statisticEvent = PdfAsHelper.getStatisticEvent(request, response);
+ if(!statisticEvent.isLogged()) {
+ statisticEvent.setStatus(Status.ERROR);
+ statisticEvent.setException(e);
+ if(e instanceof PDFASError) {
+ statisticEvent.setErrorCode(((PDFASError)e).getCode());
+ }
+ statisticEvent.setEndNow();
+ statisticEvent.setTimestampNow();
+ StatisticFrontend.getInstance().storeEvent(statisticEvent);
+ statisticEvent.setLogged(true);
+ }
+
String message = PdfAsHelper.getSessionErrMessage(request,
response);
if (errorURL != null && WebConfiguration.isProvidePdfURLinWhitelist(errorURL)) {
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java
index 120b9811..bd0bd935 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java
@@ -38,14 +38,21 @@ import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import at.gv.egiz.pdfas.common.exceptions.PDFASError;
import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter.SignatureVerificationLevel;
import at.gv.egiz.pdfas.web.config.WebConfiguration;
import at.gv.egiz.pdfas.web.exception.PdfAsWebException;
+import at.gv.egiz.pdfas.web.filter.UserAgentFilter;
import at.gv.egiz.pdfas.web.helper.DigestHelper;
import at.gv.egiz.pdfas.web.helper.PdfAsHelper;
import at.gv.egiz.pdfas.web.helper.PdfAsParameterExtractor;
import at.gv.egiz.pdfas.web.helper.RemotePDFFetcher;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent;
+import at.gv.egiz.pdfas.web.stats.StatisticFrontend;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent.Operation;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent.Source;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent.Status;
/**
* Servlet implementation class Sign
@@ -90,6 +97,12 @@ public class ExternSignServlet extends HttpServlet {
String errorUrl = PdfAsParameterExtractor.getInvokeErrorURL(request);
PdfAsHelper.setErrorURL(request, response, errorUrl);
+ StatisticEvent statisticEvent = new StatisticEvent();
+ statisticEvent.setStartNow();
+ statisticEvent.setSource(Source.WEB);
+ statisticEvent.setOperation(Operation.SIGN);
+ statisticEvent.setUserAgent(UserAgentFilter.getUserAgent());
+
try {
// Mandatory Parameters on Get Request:
String invokeUrl = PdfAsParameterExtractor.getInvokeURL(request);
@@ -106,8 +119,19 @@ public class ExternSignServlet extends HttpServlet {
}
byte[] pdfData = RemotePDFFetcher.fetchPdfFile(pdfUrl);
- doSignature(request, response, pdfData);
+ doSignature(request, response, pdfData, statisticEvent);
} catch (Exception e) {
+
+ statisticEvent.setStatus(Status.ERROR);
+ statisticEvent.setException(e);
+ if(e instanceof PDFASError) {
+ statisticEvent.setErrorCode(((PDFASError)e).getCode());
+ }
+ statisticEvent.setEndNow();
+ statisticEvent.setTimestampNow();
+ StatisticFrontend.getInstance().storeEvent(statisticEvent);
+ statisticEvent.setLogged(true);
+
PdfAsHelper.setSessionException(request, response, e.getMessage(),
e);
PdfAsHelper.gotoError(getServletContext(), request, response);
@@ -128,6 +152,12 @@ public class ExternSignServlet extends HttpServlet {
String errorUrl = PdfAsParameterExtractor.getInvokeErrorURL(request);
PdfAsHelper.setErrorURL(request, response, errorUrl);
+ StatisticEvent statisticEvent = new StatisticEvent();
+ statisticEvent.setStartNow();
+ statisticEvent.setSource(Source.WEB);
+ statisticEvent.setOperation(Operation.SIGN);
+ statisticEvent.setUserAgent(UserAgentFilter.getUserAgent());
+
try {
byte[] filecontent = null;
@@ -225,14 +255,33 @@ public class ExternSignServlet extends HttpServlet {
if(source.equals("internal")) {
request.setAttribute("FILEERR", true);
request.getRequestDispatcher("index.jsp").forward(request, response);
+
+ statisticEvent.setStatus(Status.ERROR);
+ statisticEvent.setException(new Exception("No file uploaded"));
+ statisticEvent.setEndNow();
+ statisticEvent.setTimestampNow();
+ StatisticFrontend.getInstance().storeEvent(statisticEvent);
+ statisticEvent.setLogged(true);
+
return;
}
}
throw new PdfAsException("No Signature data available");
}
- doSignature(request, response, filecontent);
+ doSignature(request, response, filecontent, statisticEvent);
} catch (Exception e) {
+
+ statisticEvent.setStatus(Status.ERROR);
+ statisticEvent.setException(e);
+ if(e instanceof PDFASError) {
+ statisticEvent.setErrorCode(((PDFASError)e).getCode());
+ }
+ statisticEvent.setEndNow();
+ statisticEvent.setTimestampNow();
+ StatisticFrontend.getInstance().storeEvent(statisticEvent);
+ statisticEvent.setLogged(true);
+
PdfAsHelper.setSessionException(request, response, e.getMessage(),
e);
PdfAsHelper.gotoError(getServletContext(), request, response);
@@ -240,11 +289,15 @@ public class ExternSignServlet extends HttpServlet {
}
protected void doSignature(HttpServletRequest request,
- HttpServletResponse response, byte[] pdfData) throws Exception {
+ HttpServletResponse response, byte[] pdfData, StatisticEvent statisticEvent) throws Exception {
// Get Connector
String connector = PdfAsParameterExtractor.getConnector(request);
String transactionId = PdfAsParameterExtractor.getTransactionId(request);
+
+ statisticEvent.setFilesize(pdfData.length);
+ statisticEvent.setProfileId(null);
+ statisticEvent.setDevice(connector);
String invokeUrl = PdfAsParameterExtractor.getInvokeURL(request);
PdfAsHelper.setInvokeURL(request, response, invokeUrl);
@@ -300,6 +353,8 @@ public class ExternSignServlet extends HttpServlet {
}
}
+ PdfAsHelper.setStatisticEvent(request, response, statisticEvent);
+
PdfAsHelper.startSignature(request, response, getServletContext(), pdfData, connector,
PdfAsHelper.buildPosString(request, response), transactionId, PdfAsParameterExtractor
.getSigType(request), PdfAsParameterExtractor.getPreProcessorMap(request));
@@ -334,9 +389,18 @@ public class ExternSignServlet extends HttpServlet {
}
}
+
+
byte[] pdfSignedData = PdfAsHelper.synchornousSignature(request,
response, pdfData);
PdfAsHelper.setSignedPdf(request, response, pdfSignedData);
+
+ statisticEvent.setStatus(Status.OK);
+ statisticEvent.setEndNow();
+ statisticEvent.setTimestampNow();
+ StatisticFrontend.getInstance().storeEvent(statisticEvent);
+ statisticEvent.setLogged(true);
+
PdfAsHelper.gotoProvidePdf(getServletContext(), request, response);
return;
} else {
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java
index 483b9707..64bae47e 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java
@@ -37,6 +37,9 @@ import org.slf4j.LoggerFactory;
import at.gv.egiz.pdfas.api.ws.PDFASVerificationResponse;
import at.gv.egiz.pdfas.web.helper.PdfAsHelper;
import at.gv.egiz.pdfas.web.helper.PdfAsParameterExtractor;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent.Status;
+import at.gv.egiz.pdfas.web.stats.StatisticFrontend;
/**
* Servlet implementation class PDFData
@@ -79,6 +82,8 @@ public class PDFData extends HttpServlet {
HttpServletResponse response) throws ServletException, IOException {
byte[] signedData = PdfAsHelper.getSignedPdf(request, response);
+ StatisticEvent statisticEvent = PdfAsHelper.getStatisticEvent(request, response);
+
String plainPDFDigest = PdfAsParameterExtractor.getOrigDigest(request);
if (signedData != null) {
@@ -101,6 +106,15 @@ public class PDFData extends HttpServlet {
response.setHeader("Signer-Certificate", pdfCert);
}
+ if(!statisticEvent.isLogged()) {
+ statisticEvent.setStatus(Status.OK);
+
+ statisticEvent.setEndNow();
+ statisticEvent.setTimestampNow();
+ StatisticFrontend.getInstance().storeEvent(statisticEvent);
+ statisticEvent.setLogged(true);
+ }
+
PDFASVerificationResponse resp = PdfAsHelper.getPDFASVerificationResponse(request);
if(resp != null) {
response.setHeader("CertificateCheckCode", String.valueOf(resp.getCertificateCode()));
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/UIEntryPointServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/UIEntryPointServlet.java
index 53be36da..7100af3b 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/UIEntryPointServlet.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/UIEntryPointServlet.java
@@ -43,6 +43,7 @@ import at.gv.egiz.pdfas.web.exception.PdfAsStoreException;
import at.gv.egiz.pdfas.web.exception.PdfAsWebException;
import at.gv.egiz.pdfas.web.helper.DigestHelper;
import at.gv.egiz.pdfas.web.helper.PdfAsHelper;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent;
import at.gv.egiz.pdfas.web.store.RequestStore;
public class UIEntryPointServlet extends HttpServlet {
@@ -85,6 +86,11 @@ public class UIEntryPointServlet extends HttpServlet {
+ " value");
}
+ StatisticEvent statisticEvent = RequestStore.getInstance()
+ .fetchStatisticEntry(storeId);
+
+ PdfAsHelper.setStatisticEvent(req, resp, statisticEvent);
+
Connector connector = pdfAsRequest.getParameters().getConnector();
String invokeUrl = pdfAsRequest.getParameters().getInvokeURL();
@@ -149,16 +155,16 @@ public class UIEntryPointServlet extends HttpServlet {
}
}
Map<String, String> map = null;
- if(pdfAsRequest.getParameters().getPreprocessor() != null) {
- map = pdfAsRequest.getParameters().getPreprocessor().getMap();
+ if (pdfAsRequest.getParameters().getPreprocessor() != null) {
+ map = pdfAsRequest.getParameters().getPreprocessor()
+ .getMap();
}
-
+
PdfAsHelper.startSignature(req, resp, getServletContext(),
pdfAsRequest.getInputData(), connector.toString(),
pdfAsRequest.getParameters().getPosition(),
pdfAsRequest.getParameters().getTransactionId(),
- pdfAsRequest.getParameters().getProfile(),
- map);
+ pdfAsRequest.getParameters().getProfile(), map);
} else {
throw new PdfAsWebException("Invalid connector ("
+ Connector.BKU + " | " + Connector.ONLINEBKU + " | "
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/VerifyServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/VerifyServlet.java
index 32bb41ac..a8beffeb 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/VerifyServlet.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/VerifyServlet.java
@@ -38,15 +38,22 @@ import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import at.gv.egiz.pdfas.common.exceptions.PDFASError;
import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter.SignatureVerificationLevel;
import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;
import at.gv.egiz.pdfas.web.exception.PdfAsWebException;
+import at.gv.egiz.pdfas.web.filter.UserAgentFilter;
import at.gv.egiz.pdfas.web.helper.PdfAsHelper;
import at.gv.egiz.pdfas.web.helper.PdfAsParameterExtractor;
import at.gv.egiz.pdfas.web.helper.RemotePDFFetcher;
import at.gv.egiz.pdfas.web.helper.VerifyEncoder;
import at.gv.egiz.pdfas.web.helper.VerifyResultEncoder;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent;
+import at.gv.egiz.pdfas.web.stats.StatisticFrontend;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent.Operation;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent.Source;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent.Status;
/**
* Servlet implementation class VerifyServlet
@@ -81,6 +88,13 @@ public class VerifyServlet extends HttpServlet {
String errorUrl = PdfAsParameterExtractor.getInvokeErrorURL(request);
PdfAsHelper.setErrorURL(request, response, errorUrl);
+
+ StatisticEvent statisticEvent = new StatisticEvent();
+ statisticEvent.setStartNow();
+ statisticEvent.setSource(Source.WEB);
+ statisticEvent.setOperation(Operation.VERIFY);
+ statisticEvent.setUserAgent(UserAgentFilter.getUserAgent());
+
try {
// Mandatory Parameters on Get Request:
String invokeUrl = PdfAsParameterExtractor.getInvokeURL(request);
@@ -97,8 +111,19 @@ public class VerifyServlet extends HttpServlet {
}
byte[] pdfData = RemotePDFFetcher.fetchPdfFile(pdfUrl);
- doVerify(request, response, pdfData);
+ doVerify(request, response, pdfData, statisticEvent);
} catch (Throwable e) {
+
+ statisticEvent.setStatus(Status.ERROR);
+ statisticEvent.setException(e);
+ if(e instanceof PDFASError) {
+ statisticEvent.setErrorCode(((PDFASError)e).getCode());
+ }
+ statisticEvent.setEndNow();
+ statisticEvent.setTimestampNow();
+ StatisticFrontend.getInstance().storeEvent(statisticEvent);
+ statisticEvent.setLogged(true);
+
logger.warn("Generic Error: ", e);
PdfAsHelper.setSessionException(request, response, e.getMessage(),
e);
@@ -118,6 +143,12 @@ public class VerifyServlet extends HttpServlet {
String errorUrl = PdfAsParameterExtractor.getInvokeErrorURL(request);
PdfAsHelper.setErrorURL(request, response, errorUrl);
+ StatisticEvent statisticEvent = new StatisticEvent();
+ statisticEvent.setStartNow();
+ statisticEvent.setSource(Source.WEB);
+ statisticEvent.setOperation(Operation.VERIFY);
+ statisticEvent.setUserAgent(UserAgentFilter.getUserAgent());
+
try {
byte[] filecontent = null;
@@ -225,14 +256,33 @@ public class VerifyServlet extends HttpServlet {
request.setAttribute("FILEERR", true);
request.getRequestDispatcher("index.jsp").forward(
request, response);
+
+ statisticEvent.setStatus(Status.ERROR);
+ statisticEvent.setException(new Exception("No file uploaded"));
+ statisticEvent.setEndNow();
+ statisticEvent.setTimestampNow();
+ StatisticFrontend.getInstance().storeEvent(statisticEvent);
+ statisticEvent.setLogged(true);
+
return;
}
}
throw new PdfAsException("No Signature data available");
}
- doVerify(request, response, filecontent);
+ doVerify(request, response, filecontent, statisticEvent);
} catch (Throwable e) {
+
+ statisticEvent.setStatus(Status.ERROR);
+ statisticEvent.setException(e);
+ if(e instanceof PDFASError) {
+ statisticEvent.setErrorCode(((PDFASError)e).getCode());
+ }
+ statisticEvent.setEndNow();
+ statisticEvent.setTimestampNow();
+ StatisticFrontend.getInstance().storeEvent(statisticEvent);
+ statisticEvent.setLogged(true);
+
logger.warn("Generic Error: ", e);
PdfAsHelper.setSessionException(request, response, e.getMessage(),
e);
@@ -241,7 +291,7 @@ public class VerifyServlet extends HttpServlet {
}
protected void doVerify(HttpServletRequest request,
- HttpServletResponse response, byte[] pdfData) throws Exception {
+ HttpServletResponse response, byte[] pdfData, StatisticEvent statisticEvent) throws Exception {
SignatureVerificationLevel lvl = PdfAsParameterExtractor
.getVerificationLevel(request);
@@ -270,6 +320,12 @@ public class VerifyServlet extends HttpServlet {
encoder = VerifyEncoder.getEncoder(PdfAsParameterExtractor.PARAM_HTML);
}
+ statisticEvent.setStatus(Status.OK);
+ statisticEvent.setEndNow();
+ statisticEvent.setTimestampNow();
+ StatisticFrontend.getInstance().storeEvent(statisticEvent);
+ statisticEvent.setLogged(true);
+
encoder.produce(request, response, results);
}
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/stats/StatisticFrontend.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/stats/StatisticFrontend.java
new file mode 100644
index 00000000..3c59a7cc
--- /dev/null
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/stats/StatisticFrontend.java
@@ -0,0 +1,111 @@
+package at.gv.egiz.pdfas.web.stats;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ServiceLoader;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.pdfas.web.config.WebConfiguration;
+
+public class StatisticFrontend implements StatisticBackend {
+
+ private static StatisticFrontend _instance;
+
+ private static ServiceLoader<StatisticBackend> backendLoader = ServiceLoader
+ .load(StatisticBackend.class);
+
+ private static final Logger logger = LoggerFactory
+ .getLogger(StatisticFrontend.class);
+
+ private List<StatisticBackend> statisticBackends = new ArrayList<StatisticBackend>();
+
+ private StatisticFrontend() {
+ Iterator<StatisticBackend> statisticIterator = backendLoader.iterator();
+ List<String> enabledBackends = WebConfiguration.getStatisticBackends();
+
+ if (enabledBackends == null) {
+ logger.info("No statitistic backends configured using all available.");
+ } else {
+ Iterator<String> enabledBackendsIterator = enabledBackends
+ .iterator();
+ logger.info("Allowing the following statistic backends:");
+ while (enabledBackendsIterator.hasNext()) {
+ logger.info(" - {}", enabledBackendsIterator.next());
+ }
+ }
+
+ while (statisticIterator.hasNext()) {
+ StatisticBackend statisticBackend = statisticIterator.next();
+
+ if(enabledBackends == null || enabledBackends.contains(statisticBackend
+ .getName())) {
+ logger.info("adding Statistic Logger {} [{}]", statisticBackend
+ .getName(), statisticBackend.getClass().getName());
+
+ statisticBackends.add(statisticBackend);
+ } else {
+ logger.info("skipping Statistic Logger {} [{}]", statisticBackend
+ .getName(), statisticBackend.getClass().getName());
+ }
+ }
+
+
+ Iterator<String> enabledBackendsIterator = enabledBackends
+ .iterator();
+ while (enabledBackendsIterator.hasNext()) {
+ String enabledBackend = enabledBackendsIterator.next();
+ statisticIterator = statisticBackends.iterator();
+ boolean found = false;
+ while (statisticIterator.hasNext()) {
+ StatisticBackend statisticBackend = statisticIterator.next();
+ if(statisticBackend.getName().equals(enabledBackend)) {
+ found = true;
+ break;
+ }
+ }
+
+ if(!found) {
+ logger.warn("Failed to load statistic backend {}. Not in classpath?", enabledBackend);
+ }
+ }
+ }
+
+ public static StatisticFrontend getInstance() {
+ if (_instance == null) {
+ _instance = new StatisticFrontend();
+ }
+ return _instance;
+ }
+
+
+ @Override
+ public String getName() {
+ return StatisticFrontend.class.getSimpleName();
+ }
+
+
+ @Override
+ public void storeEvent(StatisticEvent statisticEvent) {
+
+ if(statisticEvent == null) {
+ logger.warn("Tried to log null as statisticEvent!");
+ return;
+ }
+
+ if(statisticEvent.isLogged()) {
+ logger.warn("Tried to relog statisticEvent!");
+ return;
+ }
+
+ Iterator<StatisticBackend> statisticBackendIterator = statisticBackends.iterator();
+
+ while(statisticBackendIterator.hasNext()) {
+ StatisticBackend statisticBackend = statisticBackendIterator.next();
+ statisticBackend.storeEvent(statisticEvent);
+ }
+ }
+
+}
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/stats/impl/StatisticFileBackend.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/stats/impl/StatisticFileBackend.java
new file mode 100644
index 00000000..531c47bf
--- /dev/null
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/stats/impl/StatisticFileBackend.java
@@ -0,0 +1,56 @@
+package at.gv.egiz.pdfas.web.stats.impl;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.pdfas.web.stats.StatisticBackend;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent;
+
+public class StatisticFileBackend implements StatisticBackend {
+
+ public static final String NAME = "StatisticFileBackend";
+
+ public static final String STATISTIC_LOGGER = "at.gv.egiz.pdfas.web.statistics";
+
+ private static final Logger technical_logger = LoggerFactory
+ .getLogger(StatisticFileBackend.class);
+ private static final Logger statistic_logger = LoggerFactory
+ .getLogger(STATISTIC_LOGGER);
+
+ private void addCSVValue(String value, StringBuilder sb) {
+ if (value != null) {
+ value = value.replace(';', ',');
+ sb.append(value);
+ }
+ sb.append(";");
+ }
+
+ private String getLogEntry(StatisticEvent statisticEvent) {
+ StringBuilder sb = new StringBuilder();
+ addCSVValue(String.valueOf(statisticEvent.getTimestamp()), sb);
+ addCSVValue(statisticEvent.getOperation().getName(), sb);
+ addCSVValue(statisticEvent.getDevice(), sb);
+ addCSVValue(statisticEvent.getProfileId(), sb);
+ addCSVValue(String.valueOf(statisticEvent.getFilesize()), sb);
+ addCSVValue(statisticEvent.getUserAgent(), sb);
+ addCSVValue(statisticEvent.getStatus().getName(), sb);
+ addCSVValue((statisticEvent.getException() != null) ? statisticEvent
+ .getException().getMessage() : null, sb);
+ addCSVValue(String.valueOf(statisticEvent.getErrorCode()), sb);
+ addCSVValue(String.valueOf(statisticEvent.getDuration()), sb);
+ return sb.toString();
+ }
+
+ @Override
+ public void storeEvent(StatisticEvent statisticEvent) {
+ String entry = getLogEntry(statisticEvent);
+ technical_logger.trace("Stat log entry: {}", entry);
+ statistic_logger.info("{}", entry);
+ }
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+}
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/store/IRequestStore.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/store/IRequestStore.java
index 82534aa3..f07a36ce 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/store/IRequestStore.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/store/IRequestStore.java
@@ -24,8 +24,10 @@
package at.gv.egiz.pdfas.web.store;
import at.gv.egiz.pdfas.api.ws.PDFASSignRequest;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent;
public interface IRequestStore {
- public String createNewStoreEntry(PDFASSignRequest request);
+ public StatisticEvent fetchStatisticEntry(String id);
+ public String createNewStoreEntry(PDFASSignRequest request, StatisticEvent event);
public PDFASSignRequest fetchStoreEntry(String id);
}
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/store/InMemoryRequestStore.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/store/InMemoryRequestStore.java
index 6ec61292..f712a894 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/store/InMemoryRequestStore.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/store/InMemoryRequestStore.java
@@ -27,6 +27,7 @@ import java.util.HashMap;
import java.util.UUID;
import at.gv.egiz.pdfas.api.ws.PDFASSignRequest;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent;
public class InMemoryRequestStore implements IRequestStore {
@@ -34,14 +35,25 @@ public class InMemoryRequestStore implements IRequestStore {
}
private HashMap<String, PDFASSignRequest> store = new HashMap<String, PDFASSignRequest>();
+ private HashMap<String, StatisticEvent> statEvents = new HashMap<String, StatisticEvent>();
- public String createNewStoreEntry(PDFASSignRequest request) {
+ public String createNewStoreEntry(PDFASSignRequest request, StatisticEvent event) {
UUID id = UUID.randomUUID();
String sid = id.toString();
this.store.put(sid, request);
+ this.statEvents.put(sid, event);
return sid;
}
+ public StatisticEvent fetchStatisticEntry(String id) {
+ if(statEvents.containsKey(id)) {
+ StatisticEvent event = statEvents.get(id);
+ statEvents.remove(id);
+ return event;
+ }
+ return null;
+ }
+
public PDFASSignRequest fetchStoreEntry(String id) {
if(store.containsKey(id)) {
PDFASSignRequest request = store.get(id);
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ws/PDFASSigningImpl.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ws/PDFASSigningImpl.java
index 91aec279..e3b57b28 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ws/PDFASSigningImpl.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ws/PDFASSigningImpl.java
@@ -41,10 +41,17 @@ import at.gv.egiz.pdfas.api.ws.PDFASSignRequest;
import at.gv.egiz.pdfas.api.ws.PDFASSignResponse;
import at.gv.egiz.pdfas.api.ws.PDFASSigning;
import at.gv.egiz.pdfas.api.ws.VerificationLevel;
+import at.gv.egiz.pdfas.common.exceptions.PDFASError;
import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter.SignatureVerificationLevel;
import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;
import at.gv.egiz.pdfas.web.config.WebConfiguration;
+import at.gv.egiz.pdfas.web.filter.UserAgentFilter;
import at.gv.egiz.pdfas.web.helper.PdfAsHelper;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent.Operation;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent.Source;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent.Status;
+import at.gv.egiz.pdfas.web.stats.StatisticFrontend;
import at.gv.egiz.pdfas.web.store.RequestStore;
@MTOM
@@ -72,6 +79,11 @@ public class PDFASSigningImpl implements PDFASSigning {
return null;
}
+ StatisticEvent statisticEvent = new StatisticEvent();
+ statisticEvent.setSource(Source.SOAP);
+ statisticEvent.setOperation(Operation.SIGN);
+ statisticEvent.setUserAgent(UserAgentFilter.getUserAgent());
+ statisticEvent.setStartNow();
PDFASSignResponse response = new PDFASSignResponse();
try {
if(request.getParameters().getConnector() == null) {
@@ -79,6 +91,10 @@ public class PDFASSigningImpl implements PDFASSigning {
"Invalid connector value!");
}
+ statisticEvent.setFilesize(request.getInputData().length);
+ statisticEvent.setProfileId(request.getParameters().getProfile());
+ statisticEvent.setDevice(request.getParameters().getConnector().toString());
+
Map<String, String> preProcessor = null;
if(request.getParameters().getPreprocessor() != null) {
preProcessor = request.getParameters().getPreprocessor().getMap();
@@ -122,6 +138,21 @@ public class PDFASSigningImpl implements PDFASSigning {
verifyResult = verResults.get(0);
}
+ if(verifyResult.getValueCheckCode().getCode() == 0) {
+ statisticEvent.setStatus(Status.OK);
+ statisticEvent.setEndNow();
+ statisticEvent.setTimestampNow();
+ StatisticFrontend.getInstance().storeEvent(statisticEvent);
+ statisticEvent.setLogged(true);
+ } else {
+ statisticEvent.setStatus(Status.ERROR);
+ statisticEvent.setErrorCode(verifyResult.getValueCheckCode().getCode());
+ statisticEvent.setEndNow();
+ statisticEvent.setTimestampNow();
+ StatisticFrontend.getInstance().storeEvent(statisticEvent);
+ statisticEvent.setLogged(true);
+ }
+
response.getVerificationResponse().setCertificateCode(
verifyResult.getCertificateCheck().getCode());
response.getVerificationResponse().setValueCode(
@@ -130,7 +161,7 @@ public class PDFASSigningImpl implements PDFASSigning {
} else {
// Signatures with user interaction!!
String id = RequestStore.getInstance().createNewStoreEntry(
- request);
+ request, statisticEvent);
if (id == null) {
throw new WebServiceException("Failed to store request");
@@ -149,6 +180,17 @@ public class PDFASSigningImpl implements PDFASSigning {
response.setRedirectUrl(userEntryURL);
}
} catch (Throwable e) {
+
+ statisticEvent.setStatus(Status.ERROR);
+ statisticEvent.setException(e);
+ if(e instanceof PDFASError) {
+ statisticEvent.setErrorCode(((PDFASError)e).getCode());
+ }
+ statisticEvent.setEndNow();
+ statisticEvent.setTimestampNow();
+ StatisticFrontend.getInstance().storeEvent(statisticEvent);
+ statisticEvent.setLogged(true);
+
logger.warn("Error in Soap Service", e);
if (e.getCause() != null) {
response.setError(e.getCause().getMessage());
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ws/PDFASVerificationImpl.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ws/PDFASVerificationImpl.java
index e46da89e..fcfe2a42 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ws/PDFASVerificationImpl.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/ws/PDFASVerificationImpl.java
@@ -18,10 +18,17 @@ import at.gv.egiz.pdfas.api.ws.PDFASVerifyRequest;
import at.gv.egiz.pdfas.api.ws.PDFASVerifyResponse;
import at.gv.egiz.pdfas.api.ws.PDFASVerifyResult;
import at.gv.egiz.pdfas.api.ws.VerificationLevel;
+import at.gv.egiz.pdfas.common.exceptions.PDFASError;
import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter.SignatureVerificationLevel;
import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;
import at.gv.egiz.pdfas.web.config.WebConfiguration;
+import at.gv.egiz.pdfas.web.filter.UserAgentFilter;
import at.gv.egiz.pdfas.web.helper.PdfAsHelper;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent;
+import at.gv.egiz.pdfas.web.stats.StatisticFrontend;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent.Operation;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent.Source;
+import at.gv.egiz.pdfas.web.stats.StatisticEvent.Status;
@MTOM
@WebService(endpointInterface = "at.gv.egiz.pdfas.api.ws.PDFASVerification")
@@ -37,6 +44,12 @@ public class PDFASVerificationImpl implements PDFASVerification {
return null;
}
+ StatisticEvent statisticEvent = new StatisticEvent();
+ statisticEvent.setSource(Source.SOAP);
+ statisticEvent.setOperation(Operation.VERIFY);
+ statisticEvent.setUserAgent(UserAgentFilter.getUserAgent());
+ statisticEvent.setStartNow();
+
PDFASVerifyResponse response = new PDFASVerifyResponse();
response.setVerifyResults(new ArrayList<PDFASVerifyResult>());
try {
@@ -60,6 +73,10 @@ public class PDFASVerificationImpl implements PDFASVerification {
lvl = SignatureVerificationLevel.FULL_VERIFICATION;
}
+ statisticEvent.setFilesize(request.getInputData().length);
+ statisticEvent.setProfileId(null);
+ statisticEvent.setDevice(request.getVerificationLevel().toString());
+
List<VerifyResult> results = PdfAsHelper.synchornousVerify(
request.getInputData(), sigIdx, lvl, preProcessor);
@@ -111,7 +128,24 @@ public class PDFASVerificationImpl implements PDFASVerification {
response.getVerifyResults().add(webResult);
}
- } catch (Exception e) {
+
+ statisticEvent.setStatus(Status.OK);
+ statisticEvent.setEndNow();
+ statisticEvent.setTimestampNow();
+ StatisticFrontend.getInstance().storeEvent(statisticEvent);
+ statisticEvent.setLogged(true);
+ } catch (Throwable e) {
+
+ statisticEvent.setStatus(Status.ERROR);
+ statisticEvent.setException(e);
+ if(e instanceof PDFASError) {
+ statisticEvent.setErrorCode(((PDFASError)e).getCode());
+ }
+ statisticEvent.setEndNow();
+ statisticEvent.setTimestampNow();
+ StatisticFrontend.getInstance().storeEvent(statisticEvent);
+ statisticEvent.setLogged(true);
+
logger.warn("Failed to verify PDF", e);
if (WebConfiguration.isShowErrorDetails()) {
throw new WebServiceException("Generic Error", e);
diff --git a/pdf-as-web/src/main/resources/META-INF/services/at.gv.egiz.pdfas.web.stats.StatisticBackend b/pdf-as-web/src/main/resources/META-INF/services/at.gv.egiz.pdfas.web.stats.StatisticBackend
new file mode 100644
index 00000000..d77e0d54
--- /dev/null
+++ b/pdf-as-web/src/main/resources/META-INF/services/at.gv.egiz.pdfas.web.stats.StatisticBackend
@@ -0,0 +1 @@
+at.gv.egiz.pdfas.web.stats.impl.StatisticFileBackend \ No newline at end of file
diff --git a/pdf-as-web/src/main/webapp/WEB-INF/web.xml b/pdf-as-web/src/main/webapp/WEB-INF/web.xml
index f8b886ca..b6cfb46d 100644
--- a/pdf-as-web/src/main/webapp/WEB-INF/web.xml
+++ b/pdf-as-web/src/main/webapp/WEB-INF/web.xml
@@ -16,9 +16,16 @@
<filter-class>at.gv.egiz.pdfas.web.filter.ExceptionCatchFilter</filter-class>
</filter>
<filter>
+ <filter-name>UserAgentFilter</filter-name>
+ <display-name>UserAgentFilter</display-name>
+ <description></description>
+ <filter-class>at.gv.egiz.pdfas.web.filter.UserAgentFilter</filter-class>
+ </filter>
+ <filter>
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
</filter>
+
<!-- filter-mapping>
<filter-name>sitemesh</filter-name>
@@ -28,6 +35,10 @@
<filter-name>ExceptionCatchFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
+ <filter-mapping>
+ <filter-name>UserAgentFilter</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
<!-- listener>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
diff --git a/settings.gradle b/settings.gradle
index dffd05ec..e3b05013 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,2 +1,2 @@
-include "pdf-as-common", "signature-standards:sigs-pkcs7detached", "signature-standards:sigs-pades", "pdf-as-lib", "pdf-as-pdfbox", "pdf-as-moa", "pdf-as-tests", "pdf-as-cli", "pdf-as-legacy", "pdf-as-web-status", "pdf-as-web", "pdf-as-web-db", "pdf-as-web-client"
+include "pdf-as-common", "signature-standards:sigs-pkcs7detached", "signature-standards:sigs-pades", "pdf-as-lib", "pdf-as-pdfbox", "pdf-as-moa", "pdf-as-tests", "pdf-as-cli", "pdf-as-legacy", "pdf-as-web-status", "pdf-as-web-statistic-api", "pdf-as-web", "pdf-as-web-db", "pdf-as-web-client"