From f81b3716ac27094ab1845668cb38a1fe6a2d5f8c Mon Sep 17 00:00:00 2001
From: Alexander Marsalek <amarsalek@iaik.tugraz.at>
Date: Wed, 4 Jun 2014 18:50:50 +0200
Subject: added DocumentService

---
 .../eu/stork/documentservice/DocumentService.java  |  83 +++
 .../stork/documentservice/DocumentServiceImpl.java | 522 +++++++++++++++
 .../stork/documentservice/SPDocumentService.java   |  35 +
 .../documentservice/SPDocumentServiceImpl.java     | 126 ++++
 .../documentservice/data/DatabaseConnector.java    | 117 ++++
 .../data/DatabaseConnectorMySQLImpl.java           | 713 +++++++++++++++++++++
 .../stork/documentservice/data/DatabaseHelper.java |  37 ++
 .../documentservice/data/docservice.properties     |   9 +
 .../exceptions/DatabaseException.java              |   8 +
 .../exceptions/DocumentServiceException.java       |   9 +
 .../exceptions/EncryptionException.java            |   9 +
 .../documentservice/exceptions/ModelException.java |   8 +
 .../stork/documentservice/model/DocumentModel.java | 122 ++++
 .../stork/documentservice/model/RequestModel.java  | 106 +++
 .../documentservice/model/TempDocumentModel.java   | 118 ++++
 .../documentservice/tests/AttrQueryRequestSdoc.xml |  15 +
 .../stork/documentservice/tests/DatabaseTests.java | 265 ++++++++
 .../tests/DocumentServiceTests.java                | 123 ++++
 .../documentservice/tests/EncryptionTests.java     |  63 ++
 .../documentservice/utils/EncryptionHelper.java    | 182 ++++++
 .../documentservice/utils/ExternalDocservice.java  | 105 +++
 .../documentservice/utils/GetDSSFileAction.java    |  84 +++
 .../src/eu/stork/documentservice/utils/Utils.java  | 172 +++++
 .../eu/stork/documentservice/utils/XmlHelper.java  | 224 +++++++
 24 files changed, 3255 insertions(+)
 create mode 100644 DocumentService/src/eu/stork/documentservice/DocumentService.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/DocumentServiceImpl.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/SPDocumentService.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/SPDocumentServiceImpl.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/data/DatabaseConnector.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/data/DatabaseConnectorMySQLImpl.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/data/DatabaseHelper.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/data/docservice.properties
 create mode 100644 DocumentService/src/eu/stork/documentservice/exceptions/DatabaseException.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/exceptions/DocumentServiceException.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/exceptions/EncryptionException.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/exceptions/ModelException.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/model/DocumentModel.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/model/RequestModel.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/model/TempDocumentModel.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/tests/AttrQueryRequestSdoc.xml
 create mode 100644 DocumentService/src/eu/stork/documentservice/tests/DatabaseTests.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/tests/DocumentServiceTests.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/tests/EncryptionTests.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/utils/EncryptionHelper.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/utils/ExternalDocservice.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/utils/GetDSSFileAction.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/utils/Utils.java
 create mode 100644 DocumentService/src/eu/stork/documentservice/utils/XmlHelper.java

(limited to 'DocumentService/src')

diff --git a/DocumentService/src/eu/stork/documentservice/DocumentService.java b/DocumentService/src/eu/stork/documentservice/DocumentService.java
new file mode 100644
index 000000000..9c539312e
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/DocumentService.java
@@ -0,0 +1,83 @@
+package eu.stork.documentservice;
+
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+import javax.jws.soap.SOAPBinding.Style;
+import javax.jws.soap.SOAPBinding.Use;
+import javax.xml.ws.soap.MTOM;
+
+@MTOM
+@WebService(name = "DocumentService", targetNamespace = "http://stork.eu")
+@SOAPBinding(style = Style.DOCUMENT, use = Use.LITERAL)
+/**
+ * 
+ * @author Advania
+ *
+ */
+public interface DocumentService {
+		
+	/**
+	 * Add document to DTL layer
+	 * @param document the document to add
+	 * @param xmlRequest the original dss xml request
+	 * @param country the destination country 
+	 * @param SpId the sp id
+	 * @param mimeType the document mime type
+	 * @param receiverCert the receiver certificate (for encryption, not implemented now)
+	 * @return the document id (docId)
+	 */
+	@WebMethod(operationName = "addDocument")
+	public String addDocument(byte[] document, String xmlRequest, String country, String SpId, String mimeType, String receiverCert);
+		
+	/**
+	 * Get document from DTL
+	 * @param documentTransferRequest the document transfer request (attribute query saml)
+	 * @param dtlUrl the url of dtl
+	 * @return the document found
+	 */
+	@WebMethod(operationName = "getDocument")
+	public byte[] getDocument(String documentTransferRequest, String dtlUrl);
+	
+	/**
+	 * Get document mime type of document
+	 * @param docId the document id
+	 * @param dtlUrl the url of dtl
+	 * @return the document mime type
+	 */
+	@WebMethod(operationName = "getDocumentMime")
+	public String getDocumentMime(String docId, String dtlUrl);
+		
+	/**
+	 * Update document in dtl
+	 * @param docId the id of document (docId)
+	 * @param xmlResponse the dss xml response 
+	 * @param document the document data
+	 * @return true if successful
+	 */
+	@WebMethod(operationName = "updateDocument")
+	public boolean updateDocument(String docId, String xmlResponse, byte[] document);
+	
+	/**
+	 * Add document to DTL layer which SP has uploaded
+	 * @param docId the document ID of document
+	 * @param xmlRequest the original dss xml request
+	 * @param country the destination country 
+	 * @param SpId the sp id
+	 * @param mimeType the document mime type
+	 * @param receiverCert the receiver certificate (for encryption, not implemented now)
+	 * @return the full document ID
+	 */
+	@WebMethod(operationName = "addSPDocument")
+	public String addSPDocument(String docId, String xmlRequest, String country, String SpId, String receiverCert);
+	
+	/**
+	 * Update document in DTL and prepare for SP
+	 * @param documentTransferRequest the document transfer request (attribute query saml)
+	 * @param dtlUrl the url of the dtl
+	 * @param xmlResponse the xml response
+	 * @return true if successful
+	 */
+	@WebMethod(operationName = "updateSPDocument")
+	public boolean updateSPDocument(String documentTransferRequest, String dtlUrl, String xmlResponse);
+}
diff --git a/DocumentService/src/eu/stork/documentservice/DocumentServiceImpl.java b/DocumentService/src/eu/stork/documentservice/DocumentServiceImpl.java
new file mode 100644
index 000000000..74519dfee
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/DocumentServiceImpl.java
@@ -0,0 +1,522 @@
+package eu.stork.documentservice;
+
+import java.util.Date;
+import java.util.Properties;
+import java.util.UUID;
+
+import javax.jws.WebService;
+import javax.xml.ws.WebServiceException;
+import javax.xml.ws.soap.MTOM;
+
+import org.apache.log4j.Logger;
+
+import com.sun.tools.ws.processor.model.ModelException;
+
+import eu.stork.documentservice.data.DatabaseConnector;
+import eu.stork.documentservice.data.DatabaseConnectorMySQLImpl;
+import eu.stork.documentservice.model.DocumentModel;
+import eu.stork.documentservice.model.RequestModel;
+import eu.stork.documentservice.model.TempDocumentModel;
+import eu.stork.documentservice.utils.ExternalDocservice;
+import eu.stork.documentservice.utils.XmlHelper;
+
+@MTOM(threshold=500)
+@WebService(endpointInterface = "eu.stork.documentservice.DocumentService", targetNamespace = "http://stork.eu", portName = "DocumentServicePort", serviceName = "DocumentService")
+public class DocumentServiceImpl implements DocumentService
+{
+	//final static String PATH = "C:/Temp/upload/";
+	static String COUNTRY;
+	private DatabaseConnector conn;
+	private Properties props = new Properties();
+	private static final Logger LOG = Logger.getLogger(DocumentServiceImpl.class.getName());
+	
+	@Override	
+	public String addDocument(byte[] document, String xmlRequest, String destinationCountry, String SpId, String mimeType, String receiverCert) {
+		String returnMessage = "";
+		if (document != null)
+		{			
+			try 
+			{
+				LOG.trace("Adding document starting, document size: " + Integer.toString(document.length)
+						+ ", destination country: " + destinationCountry + ", SP Id: " + SpId
+						+ ", mime type: " + mimeType + ", receiver cert: " + receiverCert);
+				props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties"));
+				COUNTRY = props.getProperty("peps.country");
+				RequestModel request = new RequestModel();			
+				request.setDestcountry(destinationCountry);
+				request.setSpcountry(COUNTRY);
+				request.setSpid(SpId);
+				request.setRequestid(XmlHelper.getRequestId(xmlRequest));
+				request.setXmlrequest(xmlRequest);
+				
+				conn = new DatabaseConnectorMySQLImpl(props.getProperty("sql.user"), props.getProperty("sql.password"), 
+						props.getProperty("sql.server"), props.getProperty("sql.database"));
+				boolean ok = conn.addRequest(request);
+				if (ok)
+				{
+					LOG.trace("Request added.");
+					DocumentModel doc = new DocumentModel();
+					doc.setDocid(UUID.randomUUID().toString());
+					doc.setDocument(document);
+					doc.setMimetype(mimeType);
+					doc.setReicevercert(receiverCert);
+					ok = conn.addDocument(doc);
+					if (ok)
+					{
+						LOG.trace("Document added.");
+						RequestModel req = conn.getRequest(request.getRequestid());
+						if (req != null)
+						{
+							LOG.trace("Request found.");
+							req.setDocid(doc.getDocid());
+							if (conn.updateRequest(req))
+								returnMessage = req.getFullDocID();
+							else
+							{
+								LOG.warn("Could not update request.");
+								throw new WebServiceException("Could not update request.");
+							}
+						}
+					}
+					else
+					{
+						LOG.warn("Could not add document.");
+						throw new WebServiceException("Could not add document.");
+					}
+				}
+				else
+				{
+					LOG.warn("Could not add request.");
+					throw new WebServiceException("Could not add request.");
+				}
+			}
+			catch (ModelException e)
+			{
+				LOG.error("Invalid model in input", e);
+				e.printStackTrace();
+				throw new WebServiceException("Invalid input.", e);
+			}
+			catch (Exception e)
+			{
+				LOG.error("Exception in addDocument.", e);
+				e.printStackTrace();
+				throw new WebServiceException("Upload Failed");
+			}
+			LOG.trace("Add document ending, return message: " + returnMessage);
+			return returnMessage;
+		}
+		else
+			throw new WebServiceException("No document to upload.");
+	}
+
+	@Override
+	public byte[] getDocument(String documentTransferRequest, String dtlUrl) 
+	{		
+		try
+		{
+			String docId = XmlHelper.verifyRequest(documentTransferRequest);
+			if (docId != null && !docId.isEmpty())
+			{			
+				props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties"));
+				String ownDtlUrl = props.getProperty("docservice.url");
+				LOG.trace("Getting document starting for docId: " + docId);
+				if (dtlUrl != null && !dtlUrl.isEmpty() && !ownDtlUrl.equalsIgnoreCase(dtlUrl))
+				{
+					LOG.trace("Getting document from external DTL for docId: " + docId);
+					byte[] documentData = ExternalDocservice.getDocument(documentTransferRequest, dtlUrl);
+					if (documentData != null)
+					{
+						props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties"));
+						conn = new DatabaseConnectorMySQLImpl(props.getProperty("sql.user"), props.getProperty("sql.password"), 
+								props.getProperty("sql.server"), props.getProperty("sql.database"));
+						DocumentModel doc = conn.getDocument(docId);
+						if (doc != null)
+						{
+							doc.setDocument(documentData);
+							conn.updateDocument(doc);
+						}
+						else
+						{
+							doc = new DocumentModel();
+							doc.setDocid(docId);
+							doc.setDocument(documentData);							
+							doc.setMimetype(ExternalDocservice.getDocumentMime(docId, dtlUrl));
+							//TODO handle cert
+							doc.setReicevercert("");
+							conn.addDocument(doc);
+						}
+					}
+					
+					LOG.trace("Getting document from external DTL ending.");
+					return documentData;
+				}	
+				else
+				{
+					LOG.trace("Getting document from database for docId: " + docId);
+					props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties"));
+					conn = new DatabaseConnectorMySQLImpl(props.getProperty("sql.user"), props.getProperty("sql.password"), 
+							props.getProperty("sql.server"), props.getProperty("sql.database"));
+					DocumentModel doc = conn.getDocument(docId);
+					LOG.trace("Getting document from database ending.");
+					return doc.getDocument();
+				}
+			}
+			else
+			{
+				LOG.warn("Document id is null");
+				throw new WebServiceException("Document Id is null");
+			}			
+		}
+		catch (Exception e)
+		{
+			LOG.error("Exception in getDocument.", e);
+			e.printStackTrace();
+			throw new WebServiceException("Download Failed", e);
+		}
+	}
+	
+	@Override
+	/**
+	 * Get document mime type
+	 */
+	public String getDocumentMime(String docId, String dtlUrl)
+	{
+		try
+		{
+			if (docId != null && !docId.isEmpty())
+			{	
+				props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties"));
+				String ownDtlUrl = props.getProperty("docservice.url");
+				docId = XmlHelper.StripDocId(docId);
+				LOG.trace("Getting mime starting for docId: " + docId);
+				if (dtlUrl != null && !dtlUrl.isEmpty() && !ownDtlUrl.equalsIgnoreCase(dtlUrl))
+				{					
+					LOG.trace("Getting mime from external DTL for docId: " + docId);
+					String documentMime = ExternalDocservice.getDocumentMime(docId, dtlUrl);
+					if (documentMime != null && !documentMime.isEmpty())
+					{
+						conn = new DatabaseConnectorMySQLImpl(props.getProperty("sql.user"), props.getProperty("sql.password"), 
+								props.getProperty("sql.server"), props.getProperty("sql.database"));
+						DocumentModel doc = conn.getDocument(docId);
+						if (doc != null)
+						{
+							doc.setMimetype(documentMime);
+							conn.updateDocument(doc);
+						}
+					}
+					LOG.trace("Getting mime from external DTL ending, docId: " + docId + ", mime " + documentMime);
+					return documentMime;
+				}	
+				else
+				{
+					LOG.trace("Getting mime from dabase for docId: " + docId);
+					props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties"));
+					conn = new DatabaseConnectorMySQLImpl(props.getProperty("sql.user"), props.getProperty("sql.password"), 
+							props.getProperty("sql.server"), props.getProperty("sql.database"));
+					DocumentModel doc = conn.getDocument(docId);
+					LOG.trace("Getting mime from database ending, docId: " + docId + ", mime " + doc.getMimetype());
+					return doc.getMimetype();
+				}
+			}
+			else
+			{
+				LOG.warn("Document id is null");
+				throw new WebServiceException("Document Id is null");
+			}			
+		}
+		catch (Exception e)
+		{
+			LOG.error("Exception in getDocumentMime.", e);
+			e.printStackTrace();
+			throw new WebServiceException("Download Failed", e);
+		}
+	}
+	
+	@Override
+	/**
+	 * Update document in document service
+	 */
+	public boolean updateDocument(String docId, String xmlResponse, byte[] document)
+	{
+		boolean success = false;
+		if (docId != null && !docId.isEmpty())
+		{			
+			if (document != null)
+			{
+				try
+				{
+					docId = XmlHelper.StripDocId(docId);
+					LOG.trace("Starting document update for docId: " + docId);
+					props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties"));
+					conn = new DatabaseConnectorMySQLImpl(props.getProperty("sql.user"), props.getProperty("sql.password"), 
+							props.getProperty("sql.server"), props.getProperty("sql.database"));
+					DocumentModel doc = conn.getDocument(docId);
+					if(doc != null)
+					{
+						doc.setDocument(document);
+						success = conn.updateDocument(doc);
+						if (success && xmlResponse != null && !xmlResponse.isEmpty())
+						{
+							RequestModel request = conn.getRequestByDocId(docId);
+							if (request != null)
+							{
+								request.setXmlresponse(xmlResponse);
+								request.setRestimestamp(new Date());
+								success = conn.updateRequest(request);
+							}
+						}
+						LOG.trace("Document " + docId + " updated successfully: " + Boolean.toString(success));
+					}
+					else
+					{
+						LOG.warn("No document found for docId: " + docId);
+						throw new WebServiceException("Document is null");
+					}
+				}
+				catch (Exception e)
+				{
+					LOG.error("Exception in updateDocument.", e);
+					e.printStackTrace();
+					throw new WebServiceException("Update Failed", e);
+				}
+			}
+		}
+		else
+		{
+			LOG.warn("Document id is null");
+			throw new WebServiceException("Document Id is null");
+		}
+		
+		return success;
+	}
+	
+	@Override
+	public String addSPDocument(String docId, String xmlRequest, String destinationCountry, String SpId, String receiverCert) 
+	{
+		String returnMessage = "";
+		if (docId != null && !docId.isEmpty())
+		{
+			try 
+			{
+				LOG.trace("Adding document starting, document ID: " + docId
+						+ ", destination country: " + destinationCountry + ", SP Id: " + SpId
+						+ ", receiver cert: " + receiverCert);
+				props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties"));
+				COUNTRY = props.getProperty("peps.country");
+				RequestModel request = new RequestModel();			
+				request.setDestcountry(destinationCountry);
+				request.setSpcountry(COUNTRY);
+				request.setSpid(SpId);
+				request.setRequestid(XmlHelper.getRequestId(xmlRequest));
+				request.setXmlrequest(xmlRequest);
+				
+				conn = new DatabaseConnectorMySQLImpl(props.getProperty("sql.user"), props.getProperty("sql.password"), 
+						props.getProperty("sql.server"), props.getProperty("sql.database"));
+				boolean ok = conn.addRequest(request);
+				if (ok)
+				{
+					LOG.trace("Request added.");
+					LOG.trace("Getting temp document.");
+					TempDocumentModel tempDoc = conn.getTempDocument(docId);
+					if (tempDoc != null)
+					{
+						LOG.trace("Got temp document.");
+						conn.updateTempDocument(tempDoc);
+						LOG.trace("Temp document updated.");
+						DocumentModel doc = new DocumentModel();
+						doc.setDocid(tempDoc.getDocid());
+						doc.setDocument(tempDoc.getDocument());
+						doc.setMimetype(tempDoc.getMimetype());
+						doc.setReicevercert(receiverCert);
+						ok = conn.addDocument(doc);
+						if (ok)
+						{
+							LOG.trace("Document added.");							
+							RequestModel req = conn.getRequest(request.getRequestid());
+							if (req != null)
+							{
+								LOG.trace("Request found.");
+								req.setDocid(doc.getDocid());
+								if (conn.updateRequest(req))
+									returnMessage = req.getFullDocID();
+								else
+								{
+									LOG.warn("Could not update request.");
+									throw new WebServiceException("Could not update request.");
+								}
+							}
+						}
+						else
+						{
+							LOG.warn("Could not add document.");
+							throw new WebServiceException("Could not add document.");
+						}
+					}
+					else
+					{
+						LOG.warn("No document found with id " + docId);
+						throw new WebServiceException("No document found.");
+					}
+				}
+				else
+				{
+					LOG.warn("Could not add request.");
+					throw new WebServiceException("Could not add request.");
+				}
+			}
+			catch (ModelException e)
+			{
+				LOG.error("Invalid model in input", e);
+				e.printStackTrace();
+				throw new WebServiceException("Invalid input.", e);
+			}
+			catch (Exception e)
+			{
+				LOG.error("Exception in addSPDocument.", e);
+				e.printStackTrace();
+				throw new WebServiceException("Upload Failed");
+			}
+			LOG.trace("Add SP document ending, return message: " + returnMessage);
+		}
+		else
+		{
+			LOG.warn("Document id is null");
+			throw new WebServiceException("Document Id is null");
+		}
+		
+		return returnMessage;				
+	}
+	
+	@Override
+	public boolean updateSPDocument(String documentTransferRequest, String dtlUrl, String xmlResponse)
+	{
+		boolean success = false;
+		if (documentTransferRequest != null && !documentTransferRequest.isEmpty())
+		{			
+			if (xmlResponse != null && !xmlResponse.isEmpty())
+			{
+				try
+				{
+					String docId = XmlHelper.verifyRequest(documentTransferRequest);
+					LOG.trace("Document transfer requst ok. Doc ID: " + docId);
+					if (dtlUrl == null || dtlUrl.isEmpty())
+					{
+						LOG.trace("Starting SP document update from database for docId: " + docId);
+						props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties"));
+						conn = new DatabaseConnectorMySQLImpl(props.getProperty("sql.user"), props.getProperty("sql.password"), 
+							props.getProperty("sql.server"), props.getProperty("sql.database"));
+						DocumentModel doc = conn.getDocument(docId);
+						if(doc != null)
+						{
+							TempDocumentModel tempDoc = conn.getTempDocument(docId);
+							tempDoc.setDocument(doc.getDocument());
+							success = conn.updateTempDocument(tempDoc);
+							if (success && xmlResponse != null && !xmlResponse.isEmpty())
+							{
+								RequestModel request = conn.getRequestByDocId(docId);
+								if (request != null)
+								{
+									request.setXmlresponse(xmlResponse);
+									request.setRestimestamp(new Date());
+									if (conn.updateRequest(request))
+									{
+										LOG.trace("Request updated.");
+										success = true;
+									}
+									else
+									{
+										LOG.warn("Could not update request with id " + request.getRequestid());
+										throw new WebServiceException("Update SP document failed");
+									}
+								}
+							}
+							LOG.trace("Document " + docId + " updated successfully: " + Boolean.toString(success));
+						}
+						else
+						{
+							LOG.warn("No document found for docId: " + docId);
+							throw new WebServiceException("Document is null");
+						}
+					}
+					else
+					{
+						LOG.trace("Starting SP document update from external DTL for docId: " + docId);
+						byte[] documentData = ExternalDocservice.getDocument(documentTransferRequest, dtlUrl);
+						if (documentData != null)
+						{
+							props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties"));
+							conn = new DatabaseConnectorMySQLImpl(props.getProperty("sql.user"), props.getProperty("sql.password"), 
+									props.getProperty("sql.server"), props.getProperty("sql.database"));
+							DocumentModel doc = conn.getDocument(docId);
+							if (doc != null)
+							{
+								LOG.trace("Document found");
+								doc.setDocument(documentData);
+								if (conn.updateDocument(doc))
+								{
+									LOG.trace("Document updated");
+									TempDocumentModel tempDoc = conn.getTempDocument(docId);
+									if (tempDoc != null)
+									{
+										LOG.trace("Temp document found");
+										tempDoc.setDocument(documentData);
+										if (conn.updateTempDocument(tempDoc))
+										{
+											LOG.trace("Temp document updated");
+											RequestModel request = conn.getRequestByDocId(docId);
+											request.setXmlresponse(xmlResponse);
+											request.setRestimestamp(new Date());
+											if (conn.updateRequest(request))
+											{
+												LOG.trace("Request updated");
+												success = true;
+											}
+											else
+											{
+												LOG.warn("Could not update request with doc id " + docId);
+												throw new WebServiceException("SP update failed");
+											}
+										}
+										else
+										{
+											LOG.warn("Could not update temp document with id " + docId);
+											throw new WebServiceException("SP update failed");
+										}
+									}
+									else
+									{
+										LOG.warn("Could not find temp document with id " + docId);
+										throw new WebServiceException("SP update failed");
+									}
+								}
+								else
+								{
+									LOG.warn("Could not update document with id " + docId);
+									throw new WebServiceException("SP update failed");
+								}
+							}
+						}
+					}
+				}
+				catch (Exception e)
+				{
+					LOG.error("Exception in updateSPDocument.", e);
+					e.printStackTrace();
+					throw new WebServiceException("Update Failed", e);
+				}
+			}
+			else
+			{
+				LOG.warn("XML signing response is null or empty");
+				throw new WebServiceException("XML signing response is null");
+			}
+		}
+		else
+		{
+			LOG.warn("Document transfer request is null or empty");
+			throw new WebServiceException("Document transfer request is null");
+		}
+		
+		return success;
+	}
+}
diff --git a/DocumentService/src/eu/stork/documentservice/SPDocumentService.java b/DocumentService/src/eu/stork/documentservice/SPDocumentService.java
new file mode 100644
index 000000000..35235c644
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/SPDocumentService.java
@@ -0,0 +1,35 @@
+package eu.stork.documentservice;
+
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+import javax.jws.soap.SOAPBinding.Style;
+import javax.jws.soap.SOAPBinding.Use;
+import javax.xml.ws.soap.MTOM;
+
+@MTOM
+@WebService(name = "SPDocumentService", targetNamespace = "http://stork.eu")
+@SOAPBinding(style = Style.DOCUMENT, use = Use.LITERAL)
+/**
+ * 
+ * @author Advania
+ *
+ */
+public interface SPDocumentService {
+
+	/**
+	 * Add document to temp layer
+	 * @param document the document data to add
+	 * @return the document temp id
+	 */
+	@WebMethod(operationName = "addSPSignDocument")
+	public String addSPSignDocument(byte[] document, String spId, String mimeType, String receiverCert);
+		
+	/**
+	 * Get document from Temp layer
+	 * @param docId the document id
+	 * @return the document found
+	 */
+	@WebMethod(operationName = "getSPDocument")
+	public byte[] getSPDocument(String docId, String spId);
+}
diff --git a/DocumentService/src/eu/stork/documentservice/SPDocumentServiceImpl.java b/DocumentService/src/eu/stork/documentservice/SPDocumentServiceImpl.java
new file mode 100644
index 000000000..e89ed8c0c
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/SPDocumentServiceImpl.java
@@ -0,0 +1,126 @@
+package eu.stork.documentservice;
+
+import java.util.Properties;
+import java.util.UUID;
+
+import javax.jws.WebService;
+import javax.xml.ws.WebServiceException;
+import javax.xml.ws.soap.MTOM;
+
+import org.apache.log4j.Logger;
+
+import com.sun.tools.ws.processor.model.ModelException;
+
+import eu.stork.documentservice.data.DatabaseConnector;
+import eu.stork.documentservice.data.DatabaseConnectorMySQLImpl;
+import eu.stork.documentservice.model.TempDocumentModel;
+import eu.stork.documentservice.utils.XmlHelper;
+
+@MTOM(threshold=500)
+@WebService(endpointInterface = "eu.stork.documentservice.SPDocumentService", targetNamespace = "http://stork.eu", portName = "SPDocumentServicePort", serviceName = "SPDocumentService")
+public class SPDocumentServiceImpl implements SPDocumentService {
+
+	static String COUNTRY;
+	private DatabaseConnector conn;
+	private Properties props = new Properties();
+	private static final Logger LOG = Logger.getLogger(DocumentServiceImpl.class.getName());
+	
+	@Override
+	public String addSPSignDocument(byte[] document, String SpId, String mimeType, String receiverCert)
+	{
+		String returnMessage = "";
+		if (document != null)
+		{			
+			try 
+			{
+				LOG.trace("Adding temp document starting, document size: " + Integer.toString(document.length)
+						+ ", SP Id: " + SpId + ", mime type: " + mimeType + " receiver cert: " + receiverCert);
+				props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties"));
+				COUNTRY = props.getProperty("peps.country");				
+				
+				conn = new DatabaseConnectorMySQLImpl(props.getProperty("sql.user"), props.getProperty("sql.password"), 
+						props.getProperty("sql.server"), props.getProperty("sql.database"));
+
+				TempDocumentModel doc = new TempDocumentModel();
+				doc.setDocid(UUID.randomUUID().toString());
+				doc.setDocument(document);
+				doc.setSpid(SpId);
+				doc.setMimetype(mimeType);
+				doc.setReicevercert(receiverCert);
+				if (conn.addTempDocument(doc))
+				{
+					LOG.trace("Document added successfully. DocID: " + doc.getDocid());
+					returnMessage = doc.getDocid();
+				}
+				else
+				{
+					LOG.warn("Could not add document.");
+					throw new WebServiceException("Could not add document.");
+				}
+			}
+			catch (ModelException e)
+			{
+				LOG.error("Invalid model in input", e);
+				e.printStackTrace();
+				throw new WebServiceException("Invalid input.", e);
+			}
+			catch (Exception e)
+			{
+				LOG.error("Exception in SP addDocument.", e);
+				e.printStackTrace();
+				throw new WebServiceException("Upload Failed");
+			}
+			LOG.trace("Add document ending, return message: " + returnMessage);
+			return returnMessage;
+		}
+		else
+			throw new WebServiceException("No document to upload.");
+	}
+
+	@Override
+	public byte[] getSPDocument(String docId, String spId) 
+	{
+		try
+		{
+			if (docId != null && !docId.isEmpty())
+			{			
+				LOG.trace("Getting temp document from database for docId: " + docId);
+				docId = XmlHelper.StripDocId(docId);
+				props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties"));
+				conn = new DatabaseConnectorMySQLImpl(props.getProperty("sql.user"), props.getProperty("sql.password"), 
+						props.getProperty("sql.server"), props.getProperty("sql.database"));
+				TempDocumentModel doc = conn.getTempDocument(docId);
+				if (doc != null)
+				{
+					LOG.trace("Document found.");
+					if (doc.getSpid().equals(spId))
+					{
+						LOG.trace("Getting document from database ending. Document supplied.");
+						return doc.getDocument();
+					}
+					else
+					{
+						LOG.warn("Document SP ID of " + doc.getSpid() + " does not match sent SP ID of " + spId);
+						throw new WebServiceException("Incorrect SP ID."); 
+					}
+				}
+				else
+				{
+					LOG.warn("Document is null");
+					throw new WebServiceException("Document is null.");
+				}
+			}
+			else
+			{
+				LOG.warn("Document id is null or empty.");
+				throw new WebServiceException("Document Id is null");
+			}			
+		}
+		catch (Exception e)
+		{
+			LOG.error("Exception in SP getDocument.", e);
+			e.printStackTrace();
+			throw new WebServiceException("Download Failed", e);
+		}
+	}
+}
diff --git a/DocumentService/src/eu/stork/documentservice/data/DatabaseConnector.java b/DocumentService/src/eu/stork/documentservice/data/DatabaseConnector.java
new file mode 100644
index 000000000..26bd0c405
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/data/DatabaseConnector.java
@@ -0,0 +1,117 @@
+package eu.stork.documentservice.data;
+
+import eu.stork.documentservice.exceptions.DatabaseException;
+import eu.stork.documentservice.model.DocumentModel;
+import eu.stork.documentservice.model.RequestModel;
+import eu.stork.documentservice.model.TempDocumentModel;
+
+public interface DatabaseConnector {
+
+	/**
+	 * Add document to database
+	 * @param document The document model to add
+	 * @return True if successful
+	 * @throws DatabaseException
+	 */
+	public abstract boolean addDocument(DocumentModel document)
+			throws DatabaseException;
+
+	/**
+	 * Update document in database
+	 * @param document The document model to update
+	 * @return True if successful
+	 * @throws DatabaseException
+	 */
+	public abstract boolean updateDocument(DocumentModel document)
+			throws DatabaseException;
+
+	/**
+	 * Get Document from database
+	 * @param docId Document ID
+	 * @return The document found
+	 * @throws DatabaseException
+	 */
+	public abstract DocumentModel getDocument(String docId)
+			throws DatabaseException;
+
+	/**
+	 * Delete Document from database
+	 * @param docId Document ID
+	 * @return true if successful
+	 * @throws DatabaseException
+	 */
+	public abstract boolean deleteDocument(String docId)
+			throws DatabaseException;
+
+	/**
+	 * Add request to database
+	 * @param request The request to add
+	 * @return True if successful
+	 * @throws DatabaseException
+	 */
+	public abstract boolean addRequest(RequestModel request)
+			throws DatabaseException;
+
+	/**
+	 * Get request from database
+	 * @param requestId The request id
+	 * @return The request found
+	 * @throws DatabaseException
+	 */
+	public abstract RequestModel getRequest(String requestId)
+			throws DatabaseException;
+
+	/**
+	 * Get request from database
+	 * @param docId The document id
+	 * @return The request found
+	 * @throws DatabaseException
+	 */
+	public abstract RequestModel getRequestByDocId(String docId)
+			throws DatabaseException;
+
+	/**
+	 * Update request in database
+	 * @param request The request to update
+	 * @return True if successful
+	 * @throws DatabaseException
+	 */
+	public abstract boolean updateRequest(RequestModel request)
+			throws DatabaseException;
+	
+	/**
+	 * Add temp document to database
+	 * @param document The document model to add
+	 * @return True if successful
+	 * @throws DatabaseException
+	 */
+	public abstract boolean addTempDocument(TempDocumentModel document)
+			throws DatabaseException;
+	
+	/**
+	 * Get temp document from database
+	 * @param docId Document ID
+	 * @return The document found
+	 * @throws DatabaseException
+	 */
+	public abstract TempDocumentModel getTempDocument(String docId)
+			throws DatabaseException;
+	
+	/**
+	 * Update temp document in database
+	 * @param document The document model to update
+	 * @return True if successful
+	 * @throws DatabaseException
+	 */
+	public abstract boolean updateTempDocument(TempDocumentModel document)
+			throws DatabaseException;
+	
+	/**
+	 * Delete temp document from database
+	 * @param docId Document ID
+	 * @return true if successful
+	 * @throws DatabaseException
+	 */
+	public abstract boolean deleteTempDocument(String docId)
+			throws DatabaseException; 
+}
\ No newline at end of file
diff --git a/DocumentService/src/eu/stork/documentservice/data/DatabaseConnectorMySQLImpl.java b/DocumentService/src/eu/stork/documentservice/data/DatabaseConnectorMySQLImpl.java
new file mode 100644
index 000000000..bdabc55bf
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/data/DatabaseConnectorMySQLImpl.java
@@ -0,0 +1,713 @@
+package eu.stork.documentservice.data;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import eu.stork.documentservice.exceptions.DatabaseException;
+import eu.stork.documentservice.exceptions.ModelException;
+import eu.stork.documentservice.model.DocumentModel;
+import eu.stork.documentservice.model.RequestModel;
+import eu.stork.documentservice.model.TempDocumentModel;
+
+public class DatabaseConnectorMySQLImpl implements DatabaseConnector {
+	
+	private String user;
+	private String password;
+	private String server;
+	private String database;
+	
+	/**
+	 * The MYSQL connector constructor
+	 * @author sveinbjorno
+	 * @param _user the database user
+	 * @param _password the users password
+	 * @param _server the mysql server
+	 * @param _database the mysql database
+	 */
+	public DatabaseConnectorMySQLImpl(String _user, String _password, String _server, String _database)
+	{
+		user = _user;
+		password = _password;
+		server = _server;
+		database = _database;
+	}
+	
+	/* (non-Javadoc)
+	 * @see eu.stork.documentservice.data.DatabaseConnector#addDocument(eu.stork.documentservice.model.DocumentModel)
+	 */
+	@Override
+	public boolean addDocument(DocumentModel document) throws DatabaseException
+	{
+		boolean successful = false;
+		Connection con = null;
+		PreparedStatement pst = null;
+		
+		try
+		{	
+			document.insertValidate();
+			String url = "jdbc:mysql://" + server + "/" + database;
+			con = DriverManager.getConnection(url, user, password);			
+			
+			pst = con.prepareStatement("INSERT INTO document(DOCID, DOCUMENT, FILENAME, MIMETYPE, CREATED, RECEIVERCERT, "
+					+ "ENCKEY, ENCIV) VALUES(?, ?, ?, ?, ?, ?, ?, ?)");
+            pst.setString(1, document.getDocid());
+            pst.setBlob(2, document.getDataStream());
+            pst.setString(3, document.getFilename());
+            pst.setString(4, document.getMimetype());
+			pst.setTimestamp(5, DatabaseHelper.getSqlCurrentDate());
+			pst.setString(6, document.getReicevercert());
+			pst.setString(7, document.getEnckey());
+			pst.setString(8, document.getEnciv());
+            pst.executeUpdate();
+            successful = true;
+		}
+		catch (SQLException ex)
+		{
+			throw new DatabaseException(ex);
+		}
+		catch (ModelException mex)
+		{
+			throw new DatabaseException(mex);
+		}
+		finally
+		{
+			try
+			{
+				if (pst != null) {
+	                pst.close();
+	            }
+	            if (con != null) {
+	                con.close();
+	            }
+			}
+			catch (SQLException ex)
+			{
+				throw new DatabaseException(ex);
+			}
+		}
+		return successful;
+	}
+	
+	/* (non-Javadoc)
+	 * @see eu.stork.documentservice.data.DatabaseConnector#updateDocument(eu.stork.documentservice.model.DocumentModel)
+	 */
+	@Override
+	public boolean updateDocument(DocumentModel document) throws DatabaseException
+	{
+		boolean successful = false;
+		Connection con = null;
+		PreparedStatement pst = null;
+		
+		try
+		{	
+			document.updateValidate();
+			String url = "jdbc:mysql://" + server + "/" + database;
+			con = DriverManager.getConnection(url, user, password);			
+			
+			pst = con.prepareStatement("update document set DOCUMENT = ?, FILENAME = ?, MIMETYPE = ?, UPDATED = ?, "
+					+ "RECEIVERCERT = ?, ENCKEY = ?, ENCIV = ? where DOCID = ?");            
+            pst.setBlob(1, document.getDataStream());
+            pst.setString(2, document.getFilename());
+            pst.setString(3, document.getMimetype());
+			pst.setTimestamp(4, DatabaseHelper.getSqlCurrentDate());
+			pst.setString(5, document.getReicevercert());
+			pst.setString(6, document.getEnckey());
+			pst.setString(7, document.getEnciv());
+			pst.setString(8, document.getDocid());
+            pst.executeUpdate();
+            successful = true;
+		}
+		catch (SQLException ex)
+		{
+			throw new DatabaseException(ex);
+		}
+		catch (ModelException mex)
+		{
+			throw new DatabaseException(mex);
+		}
+		finally
+		{
+			try
+			{
+				if (pst != null) {
+	                pst.close();
+	            }
+	            if (con != null) {
+	                con.close();
+	            }
+			}
+			catch (SQLException ex)
+			{
+				throw new DatabaseException(ex);
+			}
+		}
+		return successful;
+	}
+	
+	/* (non-Javadoc)
+	 * @see eu.stork.documentservice.data.DatabaseConnector#getDocument(java.lang.String)
+	 */
+	@Override
+	public DocumentModel getDocument(String docId) throws DatabaseException
+	{
+		DocumentModel document = null;
+		Connection con = null;
+		PreparedStatement pst = null;
+		
+		try
+		{			
+			if (docId == null || docId.isEmpty())
+				throw new DatabaseException("Document ID is null or empty.");
+			String url = "jdbc:mysql://" + server + "/" + database;
+			con = DriverManager.getConnection(url, user, password);
+			String commandString = "select DOCUMENT, FILENAME, MIMETYPE, CREATED, UPDATED, DELETED, RECEIVERCERT, ENCKEY, ENCIV "
+				+ "from document where DOCID = ?";
+							
+			pst = con.prepareStatement(commandString);
+			pst.setString(1, docId);
+            
+			ResultSet set = pst.executeQuery();
+            if (set.next())
+            {
+            	document = new DocumentModel();
+            	document.setDocid(docId);
+            	document.setDataStream(set.getBinaryStream(1));
+            	document.setFilename(set.getString(2));
+            	document.setMimetype(set.getString(3));
+            	document.setCreated(DatabaseHelper.getUtilDate(set.getTimestamp(4)));
+            	document.setUpdated(DatabaseHelper.getUtilDate(set.getTimestamp(5)));
+            	document.setDeleted(DatabaseHelper.getUtilDate(set.getTimestamp(6)));
+            	document.setReicevercert(set.getString(7));
+            	document.setEnckey(set.getString(8));
+            	document.setEnciv(set.getString(9));
+            }
+		}
+		catch (ModelException mex)
+		{
+			throw new DatabaseException(mex);
+		}
+		catch (SQLException ex)
+		{
+			throw new DatabaseException(ex);
+		}
+		finally
+		{
+			try
+			{
+				if (pst != null) {
+	                pst.close();
+	            }
+	            if (con != null) {
+	                con.close();
+	            }
+			}
+			catch (SQLException ex)
+			{
+				throw new DatabaseException(ex);
+			}
+		}
+		
+		return document;		
+	}
+	
+	/* (non-Javadoc)
+	 * @see eu.stork.documentservice.data.DatabaseConnector#deleteDocument(java.lang.String)
+	 */
+	@Override
+	public boolean deleteDocument(String docId) throws DatabaseException
+	{
+		boolean successful = false;
+		Connection con = null;
+		PreparedStatement pst = null;
+		
+		try
+		{			
+			if (docId == null || docId.isEmpty())
+				throw new DatabaseException("Document ID is null or empty.");
+			String url = "jdbc:mysql://" + server + "/" + database;
+			con = DriverManager.getConnection(url, user, password);
+			String commandString = "update document set document = null, deleted = ? where DOCID = ?";
+							
+			pst = con.prepareStatement(commandString);
+			pst.setTimestamp(1, DatabaseHelper.getSqlCurrentDate());
+			pst.setString(2, docId);
+            
+			pst.executeUpdate();
+            successful = true;
+            
+		}
+		catch (SQLException ex)
+		{
+			throw new DatabaseException(ex);
+		}
+		finally
+		{
+			try
+			{
+				if (pst != null) {
+	                pst.close();
+	            }
+	            if (con != null) {
+	                con.close();
+	            }
+			}
+			catch (SQLException ex)
+			{
+				throw new DatabaseException(ex);
+			}
+		}
+		
+		return successful;		
+	}
+	
+	/* (non-Javadoc)
+	 * @see eu.stork.documentservice.data.DatabaseConnector#addRequest(eu.stork.documentservice.model.RequestModel)
+	 */
+	@Override
+	public boolean addRequest(RequestModel request) throws DatabaseException
+	{
+		boolean successful = false;
+		Connection con = null;
+		PreparedStatement pst = null;
+		
+		try
+		{			
+			request.insertValidate();
+			String url = "jdbc:mysql://" + server + "/" + database;
+			con = DriverManager.getConnection(url, user, password);			
+			
+			pst = con.prepareStatement("INSERT INTO request(REQUESTID, DOCID, DESTCOUNTRY, SPCOUNTRY, "
+					+ "SPID, XMLREQUEST, REQTIMESTAMP) VALUES(?, ?, ?, ?, ?, ?, ?)");
+            pst.setString(1, request.getRequestid());
+            pst.setString(2, request.getDocid());
+            pst.setString(3, request.getDestcountry());
+            pst.setString(4, request.getSpcountry());
+            pst.setString(5, request.getSpid());
+            pst.setString(6, request.getXmlrequest());
+			pst.setTimestamp(7, DatabaseHelper.getSqlCurrentDate());
+            pst.executeUpdate();
+            successful = true;
+		}
+		catch (ModelException mex)
+		{
+			throw new DatabaseException(mex);
+		}
+		catch (SQLException ex)
+		{
+			throw new DatabaseException(ex);
+		}
+		finally
+		{
+			try
+			{
+				if (pst != null) {
+	                pst.close();
+	            }
+	            if (con != null) {
+	                con.close();
+	            }
+			}
+			catch (SQLException ex)
+			{
+				throw new DatabaseException(ex);
+			}
+		}
+		return successful;
+	}
+	
+	/* (non-Javadoc)
+	 * @see eu.stork.documentservice.data.DatabaseConnector#getRequest(java.lang.String)
+	 */
+	@Override
+	public RequestModel getRequest(String requestId) throws DatabaseException
+	{
+		RequestModel request = null;
+		Connection con = null;
+		PreparedStatement pst = null;
+		
+		try
+		{			
+			if (requestId == null || requestId.isEmpty())
+				throw new DatabaseException("Request ID is null or empty.");
+			String url = "jdbc:mysql://" + server + "/" + database;
+			con = DriverManager.getConnection(url, user, password);
+			String commandString = "select DOCID, DESTCOUNTRY, SPCOUNTRY, SPID, XMLREQUEST, XMLRESPONSE, REQTIMESTAMP, "
+				+ "RESTIMESTAMP from request where REQUESTID = ?";
+							
+			pst = con.prepareStatement(commandString);
+			pst.setString(1, requestId);
+            
+			ResultSet set = pst.executeQuery();
+            if (set.next())
+            {
+            	request = new RequestModel();
+            	request.setRequestid(requestId);
+            	request.setDocid(set.getString(1));
+            	request.setDestcountry(set.getString(2));
+            	request.setSpcountry(set.getString(3));
+            	request.setSpid(set.getString(4));
+            	request.setXmlrequest(set.getString(5));
+            	request.setXmlresponse(set.getString(6));
+            	request.setReqtimestamp(DatabaseHelper.getUtilDate(set.getTimestamp(7)));
+            	request.setRestimestamp(DatabaseHelper.getSqlDate(set.getTimestamp(8)));
+            }
+		}
+		catch (SQLException ex)
+		{
+			throw new DatabaseException(ex);
+		}
+		finally
+		{
+			try
+			{
+				if (pst != null) {
+	                pst.close();
+	            }
+	            if (con != null) {
+	                con.close();
+	            }
+			}
+			catch (SQLException ex)
+			{
+				throw new DatabaseException(ex);
+			}
+		}
+		
+		return request;
+	}
+	
+	/* (non-Javadoc)
+	 * @see eu.stork.documentservice.data.DatabaseConnector#getRequestByDocId(java.lang.String)
+	 */
+	@Override
+	public RequestModel getRequestByDocId(String docId) throws DatabaseException
+	{
+		RequestModel request = null;
+		Connection con = null;
+		PreparedStatement pst = null;
+		
+		try
+		{			
+			if (docId == null || docId.isEmpty())
+				throw new DatabaseException("Document ID is null or empty.");
+			String url = "jdbc:mysql://" + server + "/" + database;
+			con = DriverManager.getConnection(url, user, password);
+			String commandString = "select REQUESTID, DESTCOUNTRY, SPCOUNTRY, SPID, XMLREQUEST, XMLRESPONSE, REQTIMESTAMP, "
+				+ "RESTIMESTAMP from request where DOCID = ?";
+							
+			pst = con.prepareStatement(commandString);
+			pst.setString(1, docId);
+            
+			ResultSet set = pst.executeQuery();
+            if (set.next())
+            {
+            	request = new RequestModel();
+            	request.setDocid(docId);
+            	request.setRequestid(set.getString(1));
+            	request.setDestcountry(set.getString(2));
+            	request.setSpcountry(set.getString(3));
+            	request.setSpid(set.getString(4));
+            	request.setXmlrequest(set.getString(5));
+            	request.setXmlresponse(set.getString(6));
+            	request.setReqtimestamp(DatabaseHelper.getUtilDate(set.getTimestamp(7)));
+            	request.setRestimestamp(DatabaseHelper.getSqlDate(set.getTimestamp(8)));
+            }
+		}
+		catch (SQLException ex)
+		{
+			throw new DatabaseException(ex);
+		}
+		finally
+		{
+			try
+			{
+				if (pst != null) {
+	                pst.close();
+	            }
+	            if (con != null) {
+	                con.close();
+	            }
+			}
+			catch (SQLException ex)
+			{
+				throw new DatabaseException(ex);
+			}
+		}
+		
+		return request;
+	}
+	
+	/* (non-Javadoc)
+	 * @see eu.stork.documentservice.data.DatabaseConnector#updateRequest(eu.stork.documentservice.model.RequestModel)
+	 */
+	@Override
+	public boolean updateRequest(RequestModel request) throws DatabaseException
+	{
+		boolean successful = false;
+		Connection con = null;
+		PreparedStatement pst = null;
+		
+		try
+		{			
+			request.updateValidate();
+			String url = "jdbc:mysql://" + server + "/" + database;
+			con = DriverManager.getConnection(url, user, password);			
+			
+			pst = con.prepareStatement("update request set DOCID = ?, DESTCOUNTRY = ?, SPCOUNTRY = ?, SPID = ?, "
+					+ "XMLREQUEST = ?, XMLRESPONSE = ?, RESTIMESTAMP = ? where REQUESTID = ?");            
+			pst.setString(1, request.getDocid());
+			pst.setString(2, request.getDestcountry());
+            pst.setString(3, request.getSpcountry());
+            pst.setString(4, request.getSpid());
+            pst.setString(5, request.getXmlrequest());
+            pst.setString(6, request.getXmlresponse());
+			pst.setTimestamp(7, DatabaseHelper.getSqlDate(request.getRestimestamp()));
+			pst.setString(8, request.getRequestid());
+            pst.executeUpdate();
+            successful = true;
+		}
+		catch (ModelException mex)
+		{
+			throw new DatabaseException(mex);
+		}
+		catch (SQLException ex)
+		{
+			throw new DatabaseException(ex);
+		}
+		finally
+		{
+			try
+			{
+				if (pst != null) {
+	                pst.close();
+	            }
+	            if (con != null) {
+	                con.close();
+	            }
+			}
+			catch (SQLException ex)
+			{
+				throw new DatabaseException(ex);
+			}
+		}
+		return successful;
+	}
+	
+	@Override
+	public boolean addTempDocument(TempDocumentModel document) throws DatabaseException
+	{
+		boolean successful = false;
+		Connection con = null;
+		PreparedStatement pst = null;
+		
+		try
+		{	
+			document.insertValidate();
+			String url = "jdbc:mysql://" + server + "/" + database;
+			con = DriverManager.getConnection(url, user, password);			
+			
+			pst = con.prepareStatement("INSERT INTO temp_document(DOCID, DOCUMENT, MIMETYPE, CREATED, RECEIVERCERT, "
+					+ "ENCKEY, ENCIV, SPID) VALUES(?, ?, ?, ?, ?, ?, ?, (SELECT ID FROM spid where spid = ?))");
+            pst.setString(1, document.getDocid());
+            pst.setBlob(2, document.getDataStream());
+            pst.setString(3, document.getMimetype());
+			pst.setTimestamp(4, DatabaseHelper.getSqlCurrentDate());
+			pst.setString(5, document.getReicevercert());
+			pst.setString(6, document.getEnckey());
+			pst.setString(7, document.getEnciv());
+			pst.setString(8, document.getSpid());
+            pst.executeUpdate();
+            successful = true;
+		}
+		catch (SQLException ex)
+		{
+			throw new DatabaseException(ex);
+		}
+		catch (ModelException mex)
+		{
+			throw new DatabaseException(mex);
+		}
+		finally
+		{
+			try
+			{
+				if (pst != null) {
+	                pst.close();
+	            }
+	            if (con != null) {
+	                con.close();
+	            }
+			}
+			catch (SQLException ex)
+			{
+				throw new DatabaseException(ex);
+			}
+		}
+		return successful;
+	}
+	
+	@Override
+	public TempDocumentModel getTempDocument(String docId) throws DatabaseException
+	{
+		TempDocumentModel document = null;
+		Connection con = null;
+		PreparedStatement pst = null;
+		
+		try
+		{			
+			if (docId == null || docId.isEmpty())
+				throw new DatabaseException("Document ID is null or empty.");
+			String url = "jdbc:mysql://" + server + "/" + database;
+			con = DriverManager.getConnection(url, user, password);
+			String commandString = "select temp.DOCUMENT, temp.MIMETYPE, temp.CREATED, temp.FETCHED, temp.DELETED, "
+				+ "temp.RECEIVERCERT, temp.ENCKEY, temp.ENCIV, sp.SPID "
+				+ "from temp_document temp inner join spid sp on sp.ID = temp.SPID where DOCID = ?";
+							
+			pst = con.prepareStatement(commandString);
+			pst.setString(1, docId);
+            
+			ResultSet set = pst.executeQuery();
+            if (set.next())
+            {
+            	document = new TempDocumentModel();
+            	document.setDocid(docId);
+            	document.setDataStream(set.getBinaryStream(1));
+            	document.setMimetype(set.getString(2));
+            	document.setCreated(DatabaseHelper.getUtilDate(set.getTimestamp(3)));
+            	document.setFetched(DatabaseHelper.getUtilDate(set.getTimestamp(4)));
+            	document.setDeleted(DatabaseHelper.getUtilDate(set.getTimestamp(5)));
+            	document.setReicevercert(set.getString(6));
+            	document.setEnckey(set.getString(7));
+            	document.setEnciv(set.getString(8));
+            	document.setSpid(set.getString(9));
+            }
+		}
+		catch (ModelException mex)
+		{
+			throw new DatabaseException(mex);
+		}
+		catch (SQLException ex)
+		{
+			throw new DatabaseException(ex);
+		}
+		finally
+		{
+			try
+			{
+				if (pst != null) {
+	                pst.close();
+	            }
+	            if (con != null) {
+	                con.close();
+	            }
+			}
+			catch (SQLException ex)
+			{
+				throw new DatabaseException(ex);
+			}
+		}
+		return document;
+	}
+	
+	@Override
+	public boolean updateTempDocument(TempDocumentModel document) throws DatabaseException
+	{
+		boolean successful = false;
+		Connection con = null;
+		PreparedStatement pst = null;
+		
+		try
+		{	
+			document.updateValidate();
+			String url = "jdbc:mysql://" + server + "/" + database;
+			con = DriverManager.getConnection(url, user, password);			
+			
+			pst = con.prepareStatement("update temp_document set DOCUMENT = ?, MIMETYPE = ?, FETCHED = ?, "
+					+ "RECEIVERCERT = ?, ENCKEY = ?, ENCIV = ? where DOCID = ?");            
+            pst.setBlob(1, document.getDataStream());
+            pst.setString(2, document.getMimetype());
+			pst.setTimestamp(3, DatabaseHelper.getSqlCurrentDate());
+			pst.setString(4, document.getReicevercert());
+			pst.setString(5, document.getEnckey());
+			pst.setString(6, document.getEnciv());
+			pst.setString(7, document.getDocid());
+            pst.executeUpdate();
+            successful = true;
+		}
+		catch (SQLException ex)
+		{
+			throw new DatabaseException(ex);
+		}
+		catch (ModelException mex)
+		{
+			throw new DatabaseException(mex);
+		}
+		finally
+		{
+			try
+			{
+				if (pst != null) {
+	                pst.close();
+	            }
+	            if (con != null) {
+	                con.close();
+	            }
+			}
+			catch (SQLException ex)
+			{
+				throw new DatabaseException(ex);
+			}
+		}
+		return successful;
+	}
+	
+	@Override
+	public boolean deleteTempDocument(String docId) throws DatabaseException
+	{
+		boolean successful = false;
+		Connection con = null;
+		PreparedStatement pst = null;
+		
+		try
+		{			
+			if (docId == null || docId.isEmpty())
+				throw new DatabaseException("Document ID is null or empty.");
+			String url = "jdbc:mysql://" + server + "/" + database;
+			con = DriverManager.getConnection(url, user, password);
+			String commandString = "update temp_document set document = null, deleted = ? where DOCID = ?";
+							
+			pst = con.prepareStatement(commandString);
+			pst.setTimestamp(1, DatabaseHelper.getSqlCurrentDate());
+			pst.setString(2, docId);
+            
+			pst.executeUpdate();
+            successful = true;
+            
+		}
+		catch (SQLException ex)
+		{
+			throw new DatabaseException(ex);
+		}
+		finally
+		{
+			try
+			{
+				if (pst != null) {
+	                pst.close();
+	            }
+	            if (con != null) {
+	                con.close();
+	            }
+			}
+			catch (SQLException ex)
+			{
+				throw new DatabaseException(ex);
+			}
+		}
+		
+		return successful;		
+	}
+}
diff --git a/DocumentService/src/eu/stork/documentservice/data/DatabaseHelper.java b/DocumentService/src/eu/stork/documentservice/data/DatabaseHelper.java
new file mode 100644
index 000000000..07c25aeba
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/data/DatabaseHelper.java
@@ -0,0 +1,37 @@
+package eu.stork.documentservice.data;
+
+public class DatabaseHelper {
+	/**
+	 * Get the current timestamp in SQL timestamp
+	 * @return the current time in sql timestamp
+	 */
+	public static java.sql.Timestamp getSqlCurrentDate() {
+	    java.util.Date today = new java.util.Date();
+	    return new java.sql.Timestamp(today.getTime());
+	}
+	
+	/**
+	 * Convert Java Date to SQL timestamp
+	 * @param date the date to convert
+	 * @return the date in sql timestamp
+	 */
+	public static java.sql.Timestamp getSqlDate(java.util.Date date) {
+		if (date != null)
+			return new java.sql.Timestamp(date.getTime());
+		else
+			return null;
+	}
+
+	/**
+	 * Convert SQL timestamp to Java Date
+	 * @param time the timestamp to concert
+	 * @return the time in util date
+	 */
+	public static java.util.Date getUtilDate(java.sql.Timestamp time) {
+		if (time != null)
+			return new java.util.Date(time.getTime());
+		else
+			return null;
+	}
+
+}
diff --git a/DocumentService/src/eu/stork/documentservice/data/docservice.properties b/DocumentService/src/eu/stork/documentservice/data/docservice.properties
new file mode 100644
index 000000000..051738da2
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/data/docservice.properties
@@ -0,0 +1,9 @@
+sql.server=localhost:3306
+sql.database=storktransfer
+sql.user=stork
+sql.password=stork
+
+peps.country=LOCAL
+peps.url=http://mopsos.iaik.tugraz.at:8080/PEPS/GetDSSFileAction
+
+docservice.url=http://mopsos.iaik.tugraz.at:8080/DocumentService/DocumentService
diff --git a/DocumentService/src/eu/stork/documentservice/exceptions/DatabaseException.java b/DocumentService/src/eu/stork/documentservice/exceptions/DatabaseException.java
new file mode 100644
index 000000000..bacca1ded
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/exceptions/DatabaseException.java
@@ -0,0 +1,8 @@
+package eu.stork.documentservice.exceptions;
+
+public class DatabaseException extends Exception {
+	public DatabaseException() { super(); }
+	  public DatabaseException(String message) { super(message); }
+	  public DatabaseException(String message, Throwable cause) { super(message, cause); }
+	  public DatabaseException(Throwable cause) { super(cause); }
+}
diff --git a/DocumentService/src/eu/stork/documentservice/exceptions/DocumentServiceException.java b/DocumentService/src/eu/stork/documentservice/exceptions/DocumentServiceException.java
new file mode 100644
index 000000000..e77da437c
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/exceptions/DocumentServiceException.java
@@ -0,0 +1,9 @@
+package eu.stork.documentservice.exceptions;
+
+public class DocumentServiceException extends Exception {
+	public DocumentServiceException() { super(); }
+	  public DocumentServiceException(String message) { super(message); }
+	  public DocumentServiceException(String message, Throwable cause) { super(message, cause); }
+	  public DocumentServiceException(Throwable cause) { super(cause); }
+
+}
diff --git a/DocumentService/src/eu/stork/documentservice/exceptions/EncryptionException.java b/DocumentService/src/eu/stork/documentservice/exceptions/EncryptionException.java
new file mode 100644
index 000000000..b7557ea96
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/exceptions/EncryptionException.java
@@ -0,0 +1,9 @@
+package eu.stork.documentservice.exceptions;
+
+public class EncryptionException extends Exception {
+	public EncryptionException() { super(); }
+	  public EncryptionException(String message) { super(message); }
+	  public EncryptionException(String message, Throwable cause) { super(message, cause); }
+	  public EncryptionException(Throwable cause) { super(cause); }
+
+}
diff --git a/DocumentService/src/eu/stork/documentservice/exceptions/ModelException.java b/DocumentService/src/eu/stork/documentservice/exceptions/ModelException.java
new file mode 100644
index 000000000..b85f1579b
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/exceptions/ModelException.java
@@ -0,0 +1,8 @@
+package eu.stork.documentservice.exceptions;
+
+public class ModelException extends Exception {
+	public ModelException() { super(); }
+	  public ModelException(String message) { super(message); }
+	  public ModelException(String message, Throwable cause) { super(message, cause); }
+	  public ModelException(Throwable cause) { super(cause); }
+}
diff --git a/DocumentService/src/eu/stork/documentservice/model/DocumentModel.java b/DocumentService/src/eu/stork/documentservice/model/DocumentModel.java
new file mode 100644
index 000000000..10ae8a189
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/model/DocumentModel.java
@@ -0,0 +1,122 @@
+package eu.stork.documentservice.model;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+
+import eu.stork.documentservice.exceptions.ModelException;
+
+/**
+ * The document model class
+ * @author sveinbjorno
+ *
+ */
+public class DocumentModel {
+	private String docid;
+	private byte[] document;
+	private String filename;
+	private String mimetype;
+	private String reicevercert;	
+	private String enckey;
+	private String enciv;
+	private Date created;
+	private Date updated;
+	private Date deleted;
+	
+	public String getDocid() {
+		return docid;
+	}
+	public void setDocid(String docid) {
+		this.docid = docid;
+	}
+	public byte[] getDocument() {
+		return document;
+	}
+	public void setDocument(byte[] document) {
+		this.document = document;
+	}
+	public String getFilename() {
+		return filename;
+	}
+	public void setFilename(String filename) {
+		this.filename = filename;
+	}
+	public String getMimetype() {
+		return mimetype;
+	}
+	public void setMimetype(String mimetype) {
+		this.mimetype = mimetype;
+	}
+	public String getReicevercert() {
+		return reicevercert;
+	}
+	public void setReicevercert(String reicevercert) {
+		this.reicevercert = reicevercert;		
+	}
+	public String getEnckey() {
+		return enckey;
+	}
+	public void setEnckey(String enckey) {
+		this.enckey = enckey;
+	}
+	public String getEnciv() {
+		return enciv;
+	}
+	public void setEnciv(String enciv) {
+		this.enciv = enciv;
+	}
+	public Date getCreated() {
+		return created;
+	}
+	public void setCreated(Date created) {
+		this.created = created;
+	}
+	public Date getUpdated() {
+		return updated;
+	}
+	public void setUpdated(Date updated) {
+		this.updated = updated;
+	}
+	public Date getDeleted() {
+		return deleted;
+	}
+	public void setDeleted(Date deleted) {
+		this.deleted = deleted;
+	}
+	
+	public InputStream getDataStream()
+	{
+		if (this.document != null)			
+			return new ByteArrayInputStream(this.document);
+		else
+			return null;
+	}
+	
+	public void setDataStream(InputStream stream) throws ModelException
+	{				
+		try {
+			this.document = new byte[stream.available()];
+			stream.read(this.document);
+		} catch (IOException e) {
+			throw new ModelException("Unable to parse stream.", e);
+		}
+	}
+	
+	public void insertValidate() throws ModelException
+	{		
+		if (this.docid == null || this.docid.isEmpty())
+			throw new ModelException("Document ID is null or empty");
+		if (this.document == null)
+			throw new ModelException("Document is null");
+		if (this.mimetype == null || this.mimetype.isEmpty())
+			throw new ModelException("MIME type is null or empty.");
+	}
+	
+	public void updateValidate() throws ModelException
+	{
+		this.insertValidate();
+		if (this.created == null)
+			throw new ModelException("Created is null");
+	}	
+}
diff --git a/DocumentService/src/eu/stork/documentservice/model/RequestModel.java b/DocumentService/src/eu/stork/documentservice/model/RequestModel.java
new file mode 100644
index 000000000..638af419e
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/model/RequestModel.java
@@ -0,0 +1,106 @@
+package eu.stork.documentservice.model;
+
+import java.util.Date;
+
+import eu.stork.documentservice.exceptions.ModelException;
+
+/**
+ * The request model class
+ * @author sveinbjorno
+ *
+ */
+public class RequestModel {
+
+	private String requestid;
+	private String docid;
+	private String destcountry;
+	private String spcountry;
+	private String spid;
+	private String xmlrequest;
+	private String xmlresponse;
+	private Date reqtimestamp;
+	private Date restimestamp;
+	
+	public String getRequestid() {
+		return requestid;
+	}
+	public void setRequestid(String requestid) {
+		this.requestid = requestid;
+	}
+	public String getDocid() {
+		return docid;
+	}
+	public void setDocid(String docid) {
+		this.docid = docid;
+	}
+	public String getDestcountry() {
+		return destcountry;
+	}
+	public void setDestcountry(String destcountry) {
+		this.destcountry = destcountry;
+	}
+	public String getSpcountry() {
+		return spcountry;
+	}
+	public void setSpcountry(String spcountry) {
+		this.spcountry = spcountry;
+	}
+	public String getSpid() {
+		return spid;
+	}
+	public void setSpid(String spid) {
+		this.spid = spid;
+	}
+	public String getXmlrequest() {
+		return xmlrequest;
+	}
+	public void setXmlrequest(String xmlrequest) {
+		this.xmlrequest = xmlrequest;
+	}
+	public String getXmlresponse() {
+		return xmlresponse;
+	}
+	public void setXmlresponse(String xmlresponse) {
+		this.xmlresponse = xmlresponse;
+	}
+	public Date getReqtimestamp() {
+		return reqtimestamp;
+	}
+	public void setReqtimestamp(Date reqtimestamp) {
+		this.reqtimestamp = reqtimestamp;
+	}
+	public Date getRestimestamp() {
+		return restimestamp;
+	}
+	public void setRestimestamp(Date restimestamp) {
+		this.restimestamp = restimestamp;
+	}
+	
+	public String getFullDocID()
+	{
+		return this.spcountry + "/" + this.destcountry + "/" + this.docid;
+	}
+	
+	public void insertValidate() throws ModelException
+	{		
+		if (this.requestid == null || this.requestid.isEmpty())
+			throw new ModelException("Request ID is null or empty");		
+		if (this.destcountry == null || this.destcountry.isEmpty())
+			throw new ModelException("Destination country is null or empty.");
+		if (this.spcountry == null || this.spcountry.isEmpty())
+			throw new ModelException("SP country is null or empty.");
+		if (this.destcountry == null || this.destcountry.isEmpty())
+			throw new ModelException("Destination country is null or empty.");
+		if (this.xmlrequest== null || this.xmlrequest.isEmpty())
+			throw new ModelException("XML request is null or empty.");
+	}
+	
+	public void updateValidate() throws ModelException
+	{
+		this.insertValidate();
+		if (this.docid == null || this.docid.isEmpty())
+			throw new ModelException("Document ID is null or empty");
+		if (this.reqtimestamp == null)
+			throw new ModelException("Request timestamp is null or empty");
+	}
+}
diff --git a/DocumentService/src/eu/stork/documentservice/model/TempDocumentModel.java b/DocumentService/src/eu/stork/documentservice/model/TempDocumentModel.java
new file mode 100644
index 000000000..7c28cc0f7
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/model/TempDocumentModel.java
@@ -0,0 +1,118 @@
+package eu.stork.documentservice.model;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+
+import eu.stork.documentservice.exceptions.ModelException;
+
+public class TempDocumentModel {
+	private String docid;
+	private byte[] document;
+	private String spid;
+	private String mimetype;
+	private String reicevercert;	
+	private String enckey;
+	private String enciv;
+	private Date created;
+	private Date fetched;
+	private Date deleted;
+	
+	public String getDocid() {
+		return docid;
+	}
+	public void setDocid(String docid) {
+		this.docid = docid;
+	}
+	public byte[] getDocument() {
+		return document;
+	}
+	public void setDocument(byte[] document) {
+		this.document = document;
+	}
+	public String getSpid() {
+		return spid;
+	}
+	public void setSpid(String spid) {
+		this.spid = spid;
+	}	
+	public String getMimetype() {
+		return mimetype;
+	}
+	public void setMimetype(String mimetype) {
+		this.mimetype = mimetype;
+	}
+
+	public String getReicevercert() {
+		return reicevercert;
+	}
+	public void setReicevercert(String reicevercert) {
+		this.reicevercert = reicevercert;		
+	}
+	public String getEnckey() {
+		return enckey;
+	}
+	public void setEnckey(String enckey) {
+		this.enckey = enckey;
+	}
+	public String getEnciv() {
+		return enciv;
+	}
+	public void setEnciv(String enciv) {
+		this.enciv = enciv;
+	}
+	public Date getCreated() {
+		return created;
+	}
+	public void setCreated(Date created) {
+		this.created = created;
+	}
+	public Date getFetched() {
+		return fetched;
+	}
+	public void setFetched(Date fetched) {
+		this.fetched = fetched;
+	}
+	public Date getDeleted() {
+		return deleted;
+	}
+	public void setDeleted(Date deleted) {
+		this.deleted = deleted;
+	}
+	
+	public InputStream getDataStream()
+	{
+		if (this.document != null)			
+			return new ByteArrayInputStream(this.document);
+		else
+			return null;
+	}
+	
+	public void setDataStream(InputStream stream) throws ModelException
+	{				
+		try {
+			this.document = new byte[stream.available()];
+			stream.read(this.document);
+		} catch (IOException e) {
+			throw new ModelException("Unable to parse stream.", e);
+		}
+	}
+	
+	public void insertValidate() throws ModelException
+	{		
+		if (this.docid == null || this.docid.isEmpty())
+			throw new ModelException("Document ID is null or empty");
+		if (this.document == null)
+			throw new ModelException("Document is null");		
+		if (this.spid == null || this.spid.isEmpty())
+			throw new ModelException("SPId is null or empty.");
+	}
+	
+	public void updateValidate() throws ModelException
+	{
+		this.insertValidate();
+		if (this.created == null)
+			throw new ModelException("Created is null");
+	}	
+}
diff --git a/DocumentService/src/eu/stork/documentservice/tests/AttrQueryRequestSdoc.xml b/DocumentService/src/eu/stork/documentservice/tests/AttrQueryRequestSdoc.xml
new file mode 100644
index 000000000..01dbf7317
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/tests/AttrQueryRequestSdoc.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?><saml2p:AttributeQuery xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:stork="urn:eu:stork:names:tc:STORK:1.0:assertion" xmlns:storkp="urn:eu:stork:names:tc:STORK:1.0:protocol" xmlns:xs="http://www.w3.org/2001/XMLSchema" AssertionConsumerServiceURL="http://S-PEPS.gov.xx/PEPS/ColleagueResponse" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" Destination="http://A-PEPS.gov.xx/PEPS/AttributeColleagueRequest" ID="_502bc4db31bb07e54a8b59c6b738dcfc" IssueInstant="2014-01-29T14:04:32.188Z" Version="2.0"><saml2:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://S-PEPS.gov.xx</saml2:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><ds:Reference URI="#_502bc4db31bb07e54a8b59c6b738dcfc"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs"/></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>3F4d8+UWhFgV+WjA3SnBH1xp3k8=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>elOYmXMcuith/nZoqF7NNpBNt8KbUHBVleRcxgMEQwqn4fsebriUFhlbesnIWmJcSKSJetlsVNm+1ZydGjxasTAsz1Nm3K9IVm2gyhXWOqisTfSRcGavJzJuS2MpLvz+O3aa/RbNvDJvDqTD3eGhvfBB/8M/eWNhgQFI5xFFH2DcsW96YtMNafaocHt4lh35+8C4htV3bd8AAD6jzVwN1itBOKivlB048OA3BI9PXdnzLKOfBOXH3TrXpqI06BJpBITFB/teOWLys4p7YH+FejQZgo0mS8+srrRbx+eILqXy+GCujJ8eCJXo2d3JQMcMLqoHaT0Jgj18+QagVkWmiA==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIIDIjCCAgqgAwIBAgIES6idsjANBgkqhkiG9w0BAQUFADBTMQswCQYDVQQGEwJFUzEOMAwGA1UE
+CAwFU3BhaW4xDzANBgNVBAcMBk1hZHJpZDEOMAwGA1UECgwFSW5kcmExEzARBgNVBAMMCmxvY2Fs
+LWRlbW8wHhcNMTMwODI4MTY0NzM1WhcNMTUwODI4MTY0NzM1WjBTMQswCQYDVQQGEwJFUzEOMAwG
+A1UECAwFU3BhaW4xDzANBgNVBAcMBk1hZHJpZDEOMAwGA1UECgwFSW5kcmExEzARBgNVBAMMCmxv
+Y2FsLWRlbW8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx+7zEQUbt8Ot9dByR5TuY
+NPmTwaKhECtnkxYAx9tl+Ga3kFiv+dOSeDoQOhxkICG1ZMaG0Gtk0EQWjscC1cLwDXpAOdhOm5xh
+ndFHxa3V3Y3zomFZA7A3nwP8wt17wDrc1xi2Ye8VrwO7Vjb/F8Rgutlcrvq+LF4g9nQLoRiKUq8w
+NFvDlvhBbLr8hMVBMY/jY7tSQ85qLqKUkWRcoDttJjgWZoO1vpBS4m+FywtYdOoHnN6fv4Dvf1r2
+rNLgebgBvSfwznxiulwW6FBLasYX0rYKP7RfwG8TJ+FumOgAjADj2LdwK25RZNg44XU2V1z1Fp37
+fNXhfo08LpdD1ueFAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBADMRGTWOmadZyCoJNluV+M7LopjC
+9WpFUj76X0cAoNXmt12zYqYe8hjRmBr6l2V/FXT3/TyWET1nILG46zwwAxslw3b2LvkhU+9QcuB8
+yC8TCJJ0kgsTZ/EUZPSbwUG7Nn2jkMiyjlyKcjSCQOzEKQyR1xYwyZG40+BPeGbYjmRgm6kcmCxY
+USWoPwNyfke9gNT80f0pUj7wJ9YwWbTIz1rhf/h7rxoMYypXo+JXwaXW/Ra8v1uDcwfKpE5ZgwAU
+nubLXF4A+H7/N7ZvB5XDwJ4W+99nuPsKfwacD8m1sflTXcEPzzhOq6iQ9anJT94/pMctnp827zXA
+y66jvDrin5I=</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml2p:Extensions><stork:QualityAuthenticationAssuranceLevel>3</stork:QualityAuthenticationAssuranceLevel><stork:spCountry>IS</stork:spCountry><storkp:eIDSectorShare>false</storkp:eIDSectorShare><storkp:eIDCrossSectorShare>false</storkp:eIDCrossSectorShare><storkp:eIDCrossBorderShare>false</storkp:eIDCrossBorderShare><storkp:RequestedAttributes><stork:RequestedAttribute Name="http://www.stork.gov.eu/1.0/docRequest" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"><stork:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:anyType">IS/IS/fbea6e68-0393-401b-b616-f767fff9418c</stork:AttributeValue></stork:RequestedAttribute></storkp:RequestedAttributes></saml2p:Extensions><saml2:Subject><saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"/></saml2:Subject></saml2p:AttributeQuery>
\ No newline at end of file
diff --git a/DocumentService/src/eu/stork/documentservice/tests/DatabaseTests.java b/DocumentService/src/eu/stork/documentservice/tests/DatabaseTests.java
new file mode 100644
index 000000000..a888f0737
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/tests/DatabaseTests.java
@@ -0,0 +1,265 @@
+package eu.stork.documentservice.tests;
+
+import static org.junit.Assert.*;
+
+import java.util.Date;
+import java.util.UUID;
+
+import org.junit.Test;
+
+import eu.stork.documentservice.data.DatabaseConnector;
+import eu.stork.documentservice.data.DatabaseConnectorMySQLImpl;
+import eu.stork.documentservice.exceptions.DatabaseException;
+import eu.stork.documentservice.model.DocumentModel;
+import eu.stork.documentservice.model.RequestModel;
+import eu.stork.documentservice.model.TempDocumentModel;
+import eu.stork.documentservice.utils.Utils;
+
+public class DatabaseTests {
+	
+	private String user = "stork";
+	private String password = "stork";
+	private String database = "stork";
+	private String server = "localhost:3306";
+	private String pdfLoc = "C:/Temp/temp.pdf";
+	private String destCountry = "AT";
+	private String spCountry = "IS";
+	private String spId = "Demo-SP";
+	private String xmlrequest = "<xml><data>foo</data>";
+	private String xmlresponse = "<xml><data>foo_signed</data>";
+	private static String docId = "";
+	private static String docId2 = "";
+	private static String reqId = "";
+	
+	public DatabaseTests()
+	{
+		if (docId.isEmpty())
+			docId = UUID.randomUUID().toString();
+		if (docId2.isEmpty())
+			docId2 = UUID.randomUUID().toString();
+		if (reqId.isEmpty())
+			reqId = UUID.randomUUID().toString();
+	}
+
+	@Test
+	//Test adding document
+	public void test1() {
+		DatabaseConnector conn = new DatabaseConnectorMySQLImpl(user, password, server, database);		
+		DocumentModel document = new DocumentModel();
+		document.setDocid(docId);
+		document.setDocument(Utils.readData(pdfLoc));
+		document.setFilename("pdfdoc.pdf");
+		document.setMimetype("application/pdf");
+		
+		try
+		{
+			boolean ok = conn.addDocument(document);
+			assertTrue(ok);
+		}
+		catch (DatabaseException ex)
+		{
+			ex.printStackTrace();
+		}
+	}
+	
+	@Test
+	//Test getting document
+	public void test2()
+	{
+		DatabaseConnector conn = new DatabaseConnectorMySQLImpl(user, password, server, database);
+		try
+		{
+			DocumentModel document = conn.getDocument(docId);
+			assertNotNull(document);
+		}
+		catch (DatabaseException ex)
+		{
+			ex.printStackTrace();
+		}		
+	}
+	
+	@Test
+	//Test updating document
+	public void test3()
+	{
+		DatabaseConnector conn = new DatabaseConnectorMySQLImpl(user, password, server, database);
+		try
+		{
+			DocumentModel document = conn.getDocument(docId);
+			boolean ok = conn.updateDocument(document);
+			assertTrue(ok);
+		}
+		catch (DatabaseException ex)
+		{
+			ex.printStackTrace();
+		}		
+	}
+	
+	@Test
+	//Test deleting document
+	public void test4()
+	{
+		DatabaseConnector conn = new DatabaseConnectorMySQLImpl(user, password, server, database);
+		try
+		{
+			boolean ok = conn.deleteDocument(docId);
+			assertTrue(ok);
+		}
+		catch (DatabaseException ex)
+		{
+			ex.printStackTrace();
+		}		
+	}
+	
+	@Test
+	//Test adding new request
+	public void test5()
+	{
+		DatabaseConnector conn = new DatabaseConnectorMySQLImpl(user, password, server, database);
+		RequestModel request = new RequestModel();		
+		request.setRequestid(reqId);
+		request.setDestcountry(destCountry);
+		request.setSpcountry(spCountry);
+		request.setSpid(spId);
+		request.setXmlrequest(xmlrequest);
+		
+		try
+		{
+			boolean ok = conn.addRequest(request);
+			assertTrue(ok);
+		}
+		catch (DatabaseException ex)
+		{
+			ex.printStackTrace();
+		}
+	}
+	
+	@Test
+	//Test getting request
+	public void test6()
+	{
+		DatabaseConnector conn = new DatabaseConnectorMySQLImpl(user, password, server, database);
+		
+		try
+		{
+			RequestModel request = conn.getRequest(reqId);
+			assertNotNull(request);
+		}
+		catch (DatabaseException ex)
+		{
+			ex.printStackTrace();
+		}
+	}
+	
+	@Test
+	//Test updating request
+	public void test7()
+	{
+		DatabaseConnector conn = new DatabaseConnectorMySQLImpl(user, password, server, database);
+
+		try
+		{
+			RequestModel request = conn.getRequest(reqId);
+			request.setDocid(docId);
+			boolean ok = conn.updateRequest(request);
+			assertTrue(ok);
+		}
+		catch (DatabaseException ex)
+		{
+			ex.printStackTrace();
+		}
+	}
+	
+	@Test
+	//Test getting new request
+	public void test8()
+	{
+		DatabaseConnector conn = new DatabaseConnectorMySQLImpl(user, password, server, database);
+
+		try
+		{
+			RequestModel request = conn.getRequest(reqId);
+			request.setXmlresponse(xmlresponse);
+			request.setRestimestamp(new Date());
+			boolean ok = conn.updateRequest(request);
+			assertTrue(ok);
+		}
+		catch (DatabaseException ex)
+		{
+			ex.printStackTrace();
+		}
+	}
+	
+	
+	@Test
+	//Test add temp document
+	public void test10()
+	{
+		DatabaseConnector conn = new DatabaseConnectorMySQLImpl(user, password, server, database);		
+		TempDocumentModel document = new TempDocumentModel();
+		document.setDocid(docId2);
+		document.setDocument(Utils.readData(pdfLoc));
+		document.setSpid(spId);
+		//document.setFilename("pdfdoc.pdf");
+		document.setMimetype("application/pdf");
+		
+		try
+		{
+			boolean ok = conn.addTempDocument(document);
+			assertTrue(ok);
+		}
+		catch (DatabaseException ex)
+		{
+			ex.printStackTrace();
+		}
+	}
+	
+	@Test
+	//Test getting temp document
+	public void test11()
+	{
+		DatabaseConnector conn = new DatabaseConnectorMySQLImpl(user, password, server, database);
+		try
+		{			
+			TempDocumentModel document = conn.getTempDocument(docId2);
+			assertNotNull(document);
+		}
+		catch (DatabaseException ex)
+		{
+			ex.printStackTrace();
+		}		
+	}
+	
+	@Test
+	//Test updating temp document
+	public void test12()
+	{
+		DatabaseConnector conn = new DatabaseConnectorMySQLImpl(user, password, server, database);
+		try
+		{
+			TempDocumentModel document = conn.getTempDocument(docId2);
+			boolean ok = conn.updateTempDocument(document);
+			assertTrue(ok);
+		}
+		catch (DatabaseException ex)
+		{
+			ex.printStackTrace();
+		}		
+	}
+	
+	@Test
+	//Test delete temp document
+	public void test13()
+	{
+		DatabaseConnector conn = new DatabaseConnectorMySQLImpl(user, password, server, database);
+		try
+		{
+			boolean ok = conn.deleteTempDocument(docId2);			
+			assertTrue(ok);
+		}
+		catch (DatabaseException ex)
+		{
+			ex.printStackTrace();
+		}		
+	}
+}
diff --git a/DocumentService/src/eu/stork/documentservice/tests/DocumentServiceTests.java b/DocumentService/src/eu/stork/documentservice/tests/DocumentServiceTests.java
new file mode 100644
index 000000000..0d27cf044
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/tests/DocumentServiceTests.java
@@ -0,0 +1,123 @@
+package eu.stork.documentservice.tests;
+
+import static org.junit.Assert.*;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.BindingProvider;
+import javax.xml.ws.Service;
+import javax.xml.ws.soap.SOAPBinding;
+
+import org.junit.Test;
+
+import eu.stork.documentservice.DocumentService;
+import eu.stork.documentservice.exceptions.DocumentServiceException;
+import eu.stork.documentservice.utils.Utils;
+import eu.stork.documentservice.utils.XmlHelper;
+
+public class DocumentServiceTests {
+
+	private static String xmlrequest = "<dss:SignRequest xmlns:dss=\"urn:oasis:names:tc:dss:1.0:core:schema\" RequestID=\"_d96b62a87d18f1095180b1f44c90b5fd\"><dss:InputDocuments><dss:Document><dss:Base64Data MimeType=\"text/plain\">VGVzdCB0ZXh0</dss:Base64Data></dss:Document></dss:InputDocuments></dss:SignRequest>";
+	private static String docRequstLoc = "C:/Temp/AttrQueryRequestSdoc.xml"; 
+	private static String docRequstLocMod = "C:/Temp/AttrQueryRequestSdocMod.xml";
+	private static String destCountry = "AT";	
+	private static String spID ="DEMO-SP";
+	
+	@Test
+	public void testXmlParsing() {
+		String reqId = null;
+		try {
+			reqId = XmlHelper.getRequestId(xmlrequest);
+		} catch (DocumentServiceException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		assertNotNull(reqId);
+	}
+	
+	@Test
+	public void testXmlParsingDocument() {
+		String doc = null;
+		try {
+			doc = XmlHelper.getRequestDocumentData(xmlrequest);
+		} catch (DocumentServiceException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		assertNotNull(doc);
+	}
+	
+	@Test
+	public void testXmlParsingDocumentMime() {
+		String mime = null;
+		try {
+			mime = XmlHelper.getRequestDocumentMime(xmlrequest);
+		} catch (DocumentServiceException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		assertNotNull(mime);
+	}
+	
+	@Test
+	public void testCheckTransferrequest()
+	{		
+		byte[] docBytes = Utils.readData(docRequstLoc);		
+		try {
+			String docId = XmlHelper.verifyRequestByte(docBytes);
+			assertTrue(!docId.isEmpty());
+		} catch (DocumentServiceException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}		
+	}
+	
+	@Test
+	public void testCheckTransferrequestMod()
+	{		
+		byte[] docBytes = Utils.readData(docRequstLocMod);		
+		try {
+			XmlHelper.verifyRequestByte(docBytes);			
+			fail("testCheckTransferrequestMod(...) should've thrown an DocumentServiceException!");
+		} catch (DocumentServiceException e) {
+			e.printStackTrace();
+			//success("Exception thrown.");
+		}		
+	}
+	
+	@Test
+	public void testAddDocument()
+	{
+		URL url = null;
+		  try {
+		   url = new URL("http://localhost:8080/DocumentService/DocumentService?wsdl");
+		  } catch (MalformedURLException e) {
+		   e.printStackTrace();
+		  }
+		  QName qname = new QName("http://stork.eu",
+		    "DocumentService");
+
+		  Service service = Service.create(url, qname);
+		  DocumentService docservice = service.getPort(DocumentService.class);
+		  
+		  BindingProvider bp = (BindingProvider) docservice;
+	      SOAPBinding binding = (SOAPBinding) bp.getBinding();
+	      binding.setMTOMEnabled(true);
+	      
+	      try
+	      {
+		      String doc = XmlHelper.getRequestDocumentData(xmlrequest);
+		      byte[] docData = Utils.decodeBase64String(doc, false);
+		      String mime = XmlHelper.getRequestDocumentMime(xmlrequest);
+			  String docid = docservice.addDocument(docData, xmlrequest, destCountry, spID, mime, "");	  
+			  assertNotNull(docid);
+	      }
+	      catch (Exception ex)
+	      {
+	    	  ex.printStackTrace();
+	      }
+	}
+
+}
diff --git a/DocumentService/src/eu/stork/documentservice/tests/EncryptionTests.java b/DocumentService/src/eu/stork/documentservice/tests/EncryptionTests.java
new file mode 100644
index 000000000..9ac0862cf
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/tests/EncryptionTests.java
@@ -0,0 +1,63 @@
+package eu.stork.documentservice.tests;
+
+import static org.junit.Assert.*;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+
+import eu.stork.documentservice.exceptions.EncryptionException;
+import eu.stork.documentservice.utils.EncryptionHelper;
+import eu.stork.documentservice.utils.Utils;
+
+public class EncryptionTests {
+
+	private String pdfLoc = "C:/Temp/temp.pdf";
+	private String certLocation = "C:/Temp/testcert.pem";
+	private static String encKey;
+	private static String encIv;
+	
+	@Test
+	//Test encrypting some data
+	public void test1() {
+		try {
+			EncryptionHelper enc = new EncryptionHelper();
+			byte[] data = (Utils.readData(pdfLoc));
+			byte[] encdata = enc.encrypt(data);			
+			assertNotNull(encdata);
+		} catch (EncryptionException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	@Test
+	//Test encrypting and decrypting some data
+	public void test2() {
+		try {
+			EncryptionHelper enc = new EncryptionHelper();
+			byte[] data = (Utils.readData(pdfLoc));
+			byte[] encdata = enc.encrypt(data);
+			encKey = enc.getKey();
+			encIv = enc.getIv();
+			
+			EncryptionHelper enc1 = new EncryptionHelper(encKey, encIv);
+			byte[] decdata = enc1.decrypt(encdata);
+			assertTrue(Arrays.equals(data, decdata));
+		} catch (EncryptionException e) {
+			e.printStackTrace();
+		}
+	}
+
+	@Test
+	//Test encrypting with a certificate
+	public void test3() {
+		try {
+			EncryptionHelper enc = new EncryptionHelper(encKey, encIv);
+			String certString = Utils.readString(certLocation);
+			String secret = enc.encryptWithCert(certString, encKey);
+			assertTrue((secret != null && !secret.isEmpty()));
+		} catch (EncryptionException e) {
+			e.printStackTrace();
+		}
+	}
+}
diff --git a/DocumentService/src/eu/stork/documentservice/utils/EncryptionHelper.java b/DocumentService/src/eu/stork/documentservice/utils/EncryptionHelper.java
new file mode 100644
index 000000000..1c55e59e3
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/utils/EncryptionHelper.java
@@ -0,0 +1,182 @@
+package eu.stork.documentservice.utils;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.security.AlgorithmParameters;
+import java.security.PublicKey;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+import javax.crypto.*;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+import com.sun.org.apache.xml.internal.security.utils.Base64;
+
+import eu.stork.documentservice.exceptions.EncryptionException;
+
+public class EncryptionHelper {
+	
+	private static String key;
+	private static String iv;
+	private static Cipher cipher;
+	
+	public EncryptionHelper() throws EncryptionException
+	{
+		this.generateKeys();
+	}
+	
+	public EncryptionHelper(String inKey, String inIv) throws EncryptionException
+	{
+		this.initKeys(inKey, inIv);
+	}
+	
+	/**
+	 * Generate new symmetric keys
+	 * @throws EncryptionException
+	 */
+	public void generateKeys() throws EncryptionException
+	{
+		try 
+		{
+			KeyGenerator keyGen = KeyGenerator.getInstance("AES");
+			keyGen.init(256);
+			SecretKey secretKey = keyGen.generateKey();
+			cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+			cipher.init(Cipher.ENCRYPT_MODE, secretKey);
+			AlgorithmParameters params = cipher.getParameters();
+			key = Base64.encode(secretKey.getEncoded());
+			iv = Base64.encode(params.getParameterSpec(IvParameterSpec.class).getIV());
+		} 
+		catch (Exception e) 
+		{				
+			e.printStackTrace();
+			throw new EncryptionException("Unable to generate encryption key.", e);
+		}		
+	}
+	
+	/**
+	 * Initialize keys with specified keys
+	 * @param inKey the key to use
+	 * @param inIv the IV to use
+	 * @throws EncryptionException the exception thrown
+	 */
+	public void initKeys(String inKey, String inIv) throws EncryptionException
+	{
+		try 
+		{
+			key = inKey;
+			iv = inIv;
+			SecretKeySpec skeySpec = new SecretKeySpec(Base64.decode(inKey), "AES");
+			cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+			cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(Base64.decode(inIv)));
+		} 
+		catch (Exception e) 
+		{				
+			e.printStackTrace();
+			throw new EncryptionException("Unable to initialize encryption key.", e);
+		}		
+	}
+	
+	/**
+	 * Encrypt data with key
+	 * @param clearData the clear data
+	 * @return the encrypted data
+	 * @throws EncryptionException the exception thrown
+	 */
+	public byte[] encrypt(byte[] clearData) throws EncryptionException
+	{		
+		if (clearData != null)
+		{
+			try
+			{
+				return cipher.doFinal(clearData);
+			}
+			catch (Exception ex)
+			{
+				throw new EncryptionException("Could not decrypt data.", ex);
+			}
+		}
+		else
+			throw new EncryptionException("Clear data is null.");
+	}
+	
+	/**
+	 * Decrypt data with keys
+	 * @param encData the encrypted data
+	 * @return decrypted data
+	 * @throws EncryptionException the exception thrown
+	 */
+	public byte[] decrypt(byte[] encData) throws EncryptionException
+	{
+		if (encData != null)
+		{
+			try
+			{
+				return cipher.doFinal(encData);
+			}
+			catch (Exception ex)
+			{
+				throw new EncryptionException("Could not encrypt data.", ex);
+			}
+		}
+		else
+			throw new EncryptionException("Encrypted data is null.");
+	}
+	
+	/**
+	 * Get the key string
+	 * @return the key
+	 */
+	public String getKey()
+	{
+		return key;
+	}
+	
+	/**
+	 * Get the IV string
+	 * @return the iv
+	 */
+	public String getIv()
+	{
+		return iv; 
+	}
+	
+	/**
+	 * Encrypt string with certificate
+	 * @param certString the PEM formated certificate
+	 * @param input the string to encrypt
+	 * @return encrypted string
+	 * @throws EncryptionException the exception thrown
+	 */
+	public String encryptWithCert(String certString, String input) throws EncryptionException
+	{
+		if (certString != null && !certString.isEmpty())
+		{
+			if (input != null && !input.isEmpty())
+			{
+				try {					
+					certString = certString.replace("-----BEGIN CERTIFICATE-----", "");
+					certString = certString.replace("-----END CERTIFICATE-----", "");
+					InputStream inStream = new ByteArrayInputStream(Base64.decode(certString));
+					CertificateFactory cf = CertificateFactory.getInstance("X.509");
+					X509Certificate cert = (X509Certificate)cf.generateCertificate(inStream);
+					PublicKey pk = cert.getPublicKey();
+					Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
+					rsaCipher.init(Cipher.ENCRYPT_MODE, pk);
+					byte[] encrypted = rsaCipher.doFinal(input.getBytes("UTF-8"));
+					return Base64.encode(encrypted);
+				} 
+				catch (Exception e) {
+					e.printStackTrace();
+					throw new EncryptionException("Unabled to encrypt string.", e);
+				}
+			}
+			else
+				throw new EncryptionException("Input is null or empty.");
+		}
+		else
+			throw new EncryptionException("Certificate is null or empty.");
+	}
+	
+}
diff --git a/DocumentService/src/eu/stork/documentservice/utils/ExternalDocservice.java b/DocumentService/src/eu/stork/documentservice/utils/ExternalDocservice.java
new file mode 100644
index 000000000..821d636a2
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/utils/ExternalDocservice.java
@@ -0,0 +1,105 @@
+package eu.stork.documentservice.utils;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.BindingProvider;
+import javax.xml.ws.Service;
+import javax.xml.ws.soap.SOAPBinding;
+
+import eu.stork.documentservice.DocumentService;
+import eu.stork.documentservice.exceptions.DocumentServiceException;
+
+public class ExternalDocservice {
+	
+	/**
+	 * Get document from external DTL
+	 * @param documentTransferRequest the document transfer request (attribute query)
+	 * @param dtlUrl the URL of external DTL
+	 * @return the document found
+	 * @throws DocumentServiceException
+	 */
+	public static byte[] getDocument(String documentTransferRequest, String dtlUrl) throws DocumentServiceException
+	{
+		if (documentTransferRequest != null && !documentTransferRequest.isEmpty())
+		{								
+			if (dtlUrl != null && !dtlUrl.isEmpty())
+			{
+				try 
+				{
+					URL url = new URL(dtlUrl);					
+				  
+					QName qname = new QName("http://stork.eu",
+					    "DocumentService");
+	
+					Service service = Service.create(url, qname);
+					DocumentService docservice = service.getPort(DocumentService.class);
+					  
+					BindingProvider bp = (BindingProvider) docservice;
+				    SOAPBinding binding = (SOAPBinding) bp.getBinding();
+				    binding.setMTOMEnabled(true);
+				      
+				    return docservice.getDocument(documentTransferRequest, dtlUrl);
+				}
+				 catch (MalformedURLException e) {
+					   e.printStackTrace();
+					   throw new DocumentServiceException("DTL url is invalid.", e);
+				 }
+				catch (Exception e) {
+					e.printStackTrace();
+					   throw new DocumentServiceException(e);
+				}
+			}
+			else
+				throw new DocumentServiceException("DTL url is empty.");
+		}
+		else
+			throw new DocumentServiceException("Document transfer request is empty.");
+	}
+
+	/**
+	 * Get document mime from external DTL
+	 * @param docId the document id
+	 * @param dtlUrl the URL of external DTL
+	 * @return the document mime found
+	 * @throws DocumentServiceException
+	 */
+	public static String getDocumentMime(String docId, String dtlUrl) throws DocumentServiceException
+	{
+		if (docId != null && !docId.isEmpty())
+		{								
+			if (dtlUrl != null && !dtlUrl.isEmpty())
+			{
+				try 
+				{
+					URL url = new URL(dtlUrl);					
+				  
+					QName qname = new QName("http://stork.eu",
+					    "DocumentService");
+	
+					Service service = Service.create(url, qname);
+					DocumentService docservice = service.getPort(DocumentService.class);
+					  
+					BindingProvider bp = (BindingProvider) docservice;
+				    SOAPBinding binding = (SOAPBinding) bp.getBinding();
+				    binding.setMTOMEnabled(true);
+				      
+				    return docservice.getDocumentMime(docId, dtlUrl);
+				}
+				 catch (MalformedURLException e) {
+					   e.printStackTrace();
+					   throw new DocumentServiceException("DTL url is invalid.", e);
+				 }
+				catch (Exception e) {
+					e.printStackTrace();
+					   throw new DocumentServiceException(e);
+				}
+			}
+			else
+				throw new DocumentServiceException("DTL url is empty.");
+		}
+		else
+			throw new DocumentServiceException("Document Id is empty.");
+	}
+}
diff --git a/DocumentService/src/eu/stork/documentservice/utils/GetDSSFileAction.java b/DocumentService/src/eu/stork/documentservice/utils/GetDSSFileAction.java
new file mode 100644
index 000000000..b80c63dc2
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/utils/GetDSSFileAction.java
@@ -0,0 +1,84 @@
+package eu.stork.documentservice.utils;
+/*
+ * This work is Open Source and licensed by the European Commission under the
+ * conditions of the European Public License v1.1 
+ *  
+ * (http://www.osor.eu/eupl/european-union-public-licence-eupl-v.1.1); 
+ * 
+ * any use of this file implies acceptance of the conditions of this license. 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS,  WITHOUT 
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
+ * License for the specific language governing permissions and limitations 
+ * under the License.
+ */
+
+
+import org.apache.log4j.Logger;
+import org.bouncycastle.util.encoders.UrlBase64;
+
+import eu.stork.peps.auth.commons.IPersonalAttributeList;
+import eu.stork.peps.auth.commons.PEPSUtil;
+
+import eu.stork.peps.auth.commons.PersonalAttribute;
+import eu.stork.peps.auth.commons.STORKAttrQueryRequest;
+
+//import eu.stork.peps.auth.cpeps.AUCPEPS;
+import eu.stork.peps.auth.engine.STORKSAMLEngine;
+import eu.stork.peps.exceptions.STORKSAMLEngineException;
+
+/**
+ * This Action will be invoked by file transfer in order to validate saml
+ * 
+ * @author Advania
+ * 
+ * @version $Revision: $, $Date: $
+ * 
+ */
+public final class GetDSSFileAction {
+	/**
+	 * Unique identifier. 
+	 */
+	private static final long serialVersionUID = 6233180247896844849L;
+	/**
+	 * Logger object.
+	 */
+	private static final Logger LOG = Logger.getLogger(GetDSSFileAction.class.getName());
+//	public String SAMLRequest;
+//	public String docId;
+	private static final String SAML_INSTANCE = "VIDP";
+
+	public static String processDocRequest(String samlRequest)
+	{		
+		String result = "";
+	    //final Map<String, String> parameters = getHttpRequestParameters();	
+		STORKAttrQueryRequest request;
+		try {
+			request = processDocRequest_(samlRequest);
+			final IPersonalAttributeList pal = request.getPersonalAttributeList();
+		    final PersonalAttribute sdoc = pal.get("docRequest");
+		    if (sdoc != null)
+		    {
+		    	String docId = sdoc.getValue().get(0);
+		    	return docId;
+		    }
+		} catch (final STORKSAMLEngineException e) {
+			e.printStackTrace();
+		}	   		
+		return null;
+	}
+		
+	private static STORKAttrQueryRequest processDocRequest_(String samlRequest) 
+		throws STORKSAMLEngineException{
+
+			// fetch the samlToken from the request
+			final byte[] samlToken =  UrlBase64.decode(samlRequest);			
+	
+			final STORKSAMLEngine engine = STORKSAMLEngine.getInstance(SAML_INSTANCE);
+		      
+			final STORKAttrQueryRequest attrData= engine.validateSTORKAttrQueryRequest(samlToken);
+			//SAMLRequest = new String(samlToken);
+			LOG.trace("Processing doc request done. SAML: " + new String(samlToken));
+			return attrData;											
+	  }	
+}
diff --git a/DocumentService/src/eu/stork/documentservice/utils/Utils.java b/DocumentService/src/eu/stork/documentservice/utils/Utils.java
new file mode 100644
index 000000000..45072a0be
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/utils/Utils.java
@@ -0,0 +1,172 @@
+package eu.stork.documentservice.utils;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import org.bouncycastle.util.encoders.Base64;
+import org.bouncycastle.util.encoders.UrlBase64;
+
+public class Utils {
+	
+	public static boolean saveData(byte[] data, String PATH, String fileName)
+	{
+		boolean ok = false;
+		if (data != null)
+		{
+			try
+			{
+				FileOutputStream fos;
+	            File outputDir = new File(PATH);
+	            File saveFile = new File(outputDir, fileName);
+	            fos = new FileOutputStream(saveFile);
+	            fos.write(data);
+	            fos.flush();
+	            fos.close();
+	            ok = true;
+			}
+			catch (Exception e)
+			{
+				e.printStackTrace();
+			}
+		}
+		return ok;
+	}
+	
+	public static byte[] readData(String fileName)
+	{
+		byte[] data = null;
+		
+		if (fileName != "")
+		{
+			try
+			{
+				FileInputStream fis;
+				File inputDir = new File(fileName);
+				fis = new FileInputStream(inputDir);
+				data = new byte[(int)inputDir.length()];
+				fis.read(data);
+				fis.close();
+			}
+			catch (Exception e)
+			{
+				e.printStackTrace();
+			}
+		}
+		
+		return data;
+	}
+	
+	public static String readString(String fileName)
+	{
+		File file = new File(fileName);
+		StringBuilder text = new StringBuilder();
+
+		try {
+		    BufferedReader br = new BufferedReader(new FileReader(file));
+		    String line;
+
+		    while ((line = br.readLine()) != null) {
+		        text.append(line);
+		    }
+		    br.close();
+		}
+		catch (Exception e) {
+		   e.printStackTrace();
+		}
+	    return text.toString();
+	}
+	
+	public static InputStream getStream(String string, String codePage) throws UnsupportedEncodingException
+	{
+		return new ByteArrayInputStream(string.getBytes(codePage));
+	}
+	
+	public static String encodeBase64bytes(final byte[] bytes, boolean urlSafe) {
+	      try {
+	    	  if (urlSafe)
+	    		  return new String(UrlBase64.encode(bytes), "UTF8");
+	    	  else
+	    		  return new String(Base64.encode(bytes), "UTF8");
+	      } catch (UnsupportedEncodingException e) {	          
+	          return null;
+	      }
+	  }
+	
+	public static byte[] decodeBase64String(final String base64string, boolean urlSave) {
+		if (urlSave)
+			return UrlBase64.decode(base64string);
+		else
+			return Base64.decode(base64string);
+	}
+	
+	// HTTP GET request
+	public static String sendGet(String url) throws Exception 
+	{ 
+		URL obj = new URL(url);
+		HttpURLConnection con = (HttpURLConnection) obj.openConnection();
+	 
+		// optional default is GET
+		con.setRequestMethod("GET");
+	 
+			//add request header
+		con.setRequestProperty("User-Agent", "unknown");
+	 
+		//int responseCode = con.getResponseCode();
+		
+		BufferedReader in = new BufferedReader(
+				new InputStreamReader(con.getInputStream()));
+		String inputLine;
+		StringBuffer response = new StringBuffer();
+	 
+		while ((inputLine = in.readLine()) != null) {
+			response.append(inputLine);
+		}
+		in.close();
+	 
+		return response.toString();
+	 
+		}
+	 
+		// HTTP POST request
+		public static String sendPost(String url, String urlParameters) throws Exception
+		{
+	 		URL obj = new URL(url);
+			HttpURLConnection con = (HttpURLConnection) obj.openConnection();
+	 
+			//add request header
+			con.setRequestMethod("POST");
+			con.setRequestProperty("User-Agent", "unknown");
+			con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
+	 
+			// Send post request
+			con.setDoOutput(true);
+			DataOutputStream wr = new DataOutputStream(con.getOutputStream());
+			wr.writeBytes(urlParameters);
+			wr.flush();
+			wr.close();
+	 
+			//int responseCode = con.getResponseCode();
+				 
+			BufferedReader in = new BufferedReader(
+			        new InputStreamReader(con.getInputStream()));
+			String inputLine;
+			StringBuffer response = new StringBuffer();
+	 
+			while ((inputLine = in.readLine()) != null) {
+				response.append(inputLine);
+			}
+			in.close();
+	 
+			return response.toString();
+		}
+}
diff --git a/DocumentService/src/eu/stork/documentservice/utils/XmlHelper.java b/DocumentService/src/eu/stork/documentservice/utils/XmlHelper.java
new file mode 100644
index 000000000..cd325db2e
--- /dev/null
+++ b/DocumentService/src/eu/stork/documentservice/utils/XmlHelper.java
@@ -0,0 +1,224 @@
+package eu.stork.documentservice.utils;
+
+import java.io.InputStream;
+import java.util.Properties;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Node;
+import org.w3c.dom.Element;
+
+//import at.gv.egovernment.moa.id.protocols.stork2.attributeproviders.GetDSSFileAction;
+
+import eu.stork.documentservice.data.DatabaseConnectorMySQLImpl;
+import eu.stork.documentservice.exceptions.DocumentServiceException;
+
+public class XmlHelper {
+	
+	private static Properties props = new Properties();
+	
+	public static String getRequestId(String xmlRequest) throws DocumentServiceException
+	{
+		if (xmlRequest == null || xmlRequest.isEmpty())
+			throw new DocumentServiceException("XML request is empty");
+		else
+		{
+			try
+			{
+				InputStream is = Utils.getStream(xmlRequest, "UTF-8");
+				DocumentBuilder dBuilder = DocumentBuilderFactory.newInstance()
+	                    .newDocumentBuilder();
+				Document doc = dBuilder.parse(is);
+				Element reqElement = doc.getDocumentElement();
+				String reqId = reqElement.getAttribute("RequestID"); 
+				return reqId.replace("_", "");
+			}
+			catch (Exception ex)
+			{
+				throw new DocumentServiceException("Unabled to parse xml.", ex);
+			}
+		}
+	}
+	
+	public static String getRequestDocument(String xmlRequest) throws DocumentServiceException
+	{
+		if (xmlRequest == null || xmlRequest.isEmpty())
+			throw new DocumentServiceException("XML request is empty");
+		else
+		{
+			try
+			{
+				InputStream is = Utils.getStream(xmlRequest, "UTF-8");
+				DocumentBuilder dBuilder = DocumentBuilderFactory.newInstance()
+	                    .newDocumentBuilder();
+				Document doc = dBuilder.parse(is);
+				String document = "";
+				Element req = doc.getDocumentElement();
+				NodeList nList0 = req.getChildNodes();
+				for (int i = 0; i < nList0.getLength(); i++)
+				{
+					Node node = nList0.item(i);
+					NodeList nList1 = node.getChildNodes();
+					for (int j = 0; j < nList1.getLength(); j++)
+					{
+						NodeList nList2 = nList1.item(j).getChildNodes();
+						for (int k = 0; k < nList2.getLength(); k++)
+						{
+							Node docNode =nList2.item(k);
+							document = docNode.getTextContent();
+						}
+					}
+				}
+				return document;
+			}
+			catch (Exception ex)
+			{
+				throw new DocumentServiceException("Unabled to parse xml.", ex);
+			}
+		}
+	}
+	
+	public static String getRequestDocumentData(String xmlRequest) throws DocumentServiceException
+	{
+		if (xmlRequest == null || xmlRequest.isEmpty())
+			throw new DocumentServiceException("XML request is empty");
+		else
+		{
+			try
+			{
+				InputStream is = Utils.getStream(xmlRequest, "UTF-8");
+				DocumentBuilderFactory xmlFactory = DocumentBuilderFactory.newInstance();
+				DocumentBuilder docBuilder = xmlFactory.newDocumentBuilder();
+				Document xmlDoc = docBuilder.parse(is);
+				XPathFactory xpathFact = XPathFactory.newInstance();
+				XPath xpath = xpathFact.newXPath();
+				return xpath.evaluate("/SignRequest/InputDocuments/Document/Base64Data/text()", xmlDoc);				
+				
+			}
+			catch (Exception ex)
+			{
+				throw new DocumentServiceException("Unabled to parse xml.", ex);
+			}
+		}
+	}
+	
+	public static String getRequestDocumentMime(String xmlRequest) throws DocumentServiceException
+	{
+		if (xmlRequest == null || xmlRequest.isEmpty())
+			throw new DocumentServiceException("XML request is empty");
+		else
+		{
+			try
+			{
+				InputStream is = Utils.getStream(xmlRequest, "UTF-8");
+				DocumentBuilderFactory xmlFactory = DocumentBuilderFactory.newInstance();
+				DocumentBuilder docBuilder = xmlFactory.newDocumentBuilder();
+				Document xmlDoc = docBuilder.parse(is);
+				XPathFactory xpathFact = XPathFactory.newInstance();
+				XPath xpath = xpathFact.newXPath();
+				return xpath.evaluate("/SignRequest/InputDocuments/Document/Base64Data/@MimeType", xmlDoc);				
+				
+			}
+			catch (Exception ex)
+			{
+				throw new DocumentServiceException("Unabled to parse xml.", ex);
+			}
+		}
+	}
+	
+	private static String getDocId(String response) throws DocumentServiceException
+	{
+		if (response == null || response.isEmpty())
+			throw new DocumentServiceException("Response is empty");
+		else
+		{
+			if (response.contains("docId"))
+			{
+				int index = response.indexOf("docId");
+				String docText = response.substring(response.indexOf(">" ,index), response.indexOf("<", index));
+				String docId = docText.replaceAll("[<>]", "");	//s:label name="docId" value="%{docId}"/			
+				docId = docId.substring(docId.indexOf("/")+1);
+				docId = docId.substring(docId.indexOf('/')+1);
+				return docId.replace("/", "");
+			}
+			else
+				throw new DocumentServiceException("No document ID in response.");
+		}
+	}
+	
+	/**
+	 * String the document id
+	 * @param docId the document id to strip
+	 * @return the stripped ID
+	 * @throws DocumentServiceException
+	 */
+	public static String StripDocId(String docId) throws DocumentServiceException
+	{
+		if (docId == null || docId.isEmpty())
+			throw new DocumentServiceException("Doc ID is empty");
+		else
+		{
+			docId = docId.substring(docId.indexOf("/")+1);
+			docId = docId.substring(docId.indexOf('/')+1);
+			return docId.replace("/", "");
+		}
+	}
+	
+	public static String verifyRequest(String transferRequest) throws DocumentServiceException
+	{
+		if (transferRequest == null || transferRequest.isEmpty())
+			throw new DocumentServiceException("Transfer request is empty");
+		else
+		{			
+			try {		
+				String docId="";
+				try{
+				
+//				props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties"));	
+//				System.out.println("url:"+props.getProperty("peps.url"));
+				
+//				final byte[] samlToken =  PEPSUtil.decodeSAMLTokenUrlSafe(parameters
+//						.get(PEPSParameters.SAML_REQUEST.toString()));			
+//			
+//					final STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP");
+//				      
+//					final STORKAttrQueryRequest attrData= engine.validateSTORKAttrQueryRequest(samlToken);
+					
+//				String response = Utils.sendPost(props.getProperty("peps.url"), "SAMLRequest=" + transferRequest);
+//				docId=getDocId(response);;
+				docId = GetDSSFileAction.processDocRequest(transferRequest);
+				}catch(Exception e){e.printStackTrace();}
+				return docId;
+				//FIXME
+//				String response = Utils.sendPost(props.getProperty("peps.url"), "SAMLRequest=" + transferRequest);
+//				return getDocId(response);
+			} catch (Exception e) {
+				e.printStackTrace();
+				throw new DocumentServiceException("Could verify request.", e);
+			} 
+		}
+	}
+	
+	public static String verifyRequestByte(byte[] transferRequest) throws DocumentServiceException
+	{
+		if (transferRequest == null)
+			throw new DocumentServiceException("Transfer request is empty");
+		else
+		{			
+			try {				
+				props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties"));
+				String response = Utils.sendPost(props.getProperty("peps.url"),"SAMLRequest=" + Utils.encodeBase64bytes(transferRequest, true));
+				return getDocId(response);
+			} catch (Exception e) {
+				e.printStackTrace();
+				throw new DocumentServiceException("Could not read properties.", e);
+			}
+	
+		}
+	}
+}
-- 
cgit v1.2.3