aboutsummaryrefslogtreecommitdiff
path: root/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web
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 /pdf-as-web/src/main/java/at/gv/egiz/pdfas/web
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
Diffstat (limited to 'pdf-as-web/src/main/java/at/gv/egiz/pdfas/web')
-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
15 files changed, 520 insertions, 16 deletions
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);