From 9ed02ff01d8dab4189674c317bebfed7b3147c64 Mon Sep 17 00:00:00 2001
From: Joze RIHTARSIC <joze.rihtarsic@ext.ec.europa.eu>
Date: Thu, 26 Jul 2018 14:47:13 +0200
Subject: [PATCH] Add audit to SMP

---
 smp-parent-pom/pom.xml                        |   5 +
 smp-server-library/pom.xml                    |  11 +
 .../ec/edelivery/smp/data/dao/BaseDao.java    |   4 +
 .../smp/data/dao/SMPRevisionListener.java     |  35 +++
 .../ec/edelivery/smp/data/model/DBDomain.java |   3 +
 .../edelivery/smp/data/model/DBOwnership.java |   3 +
 .../smp/data/model/DBRevisionLog.java         |  95 ++++++
 .../smp/data/model/DBServiceGroup.java        |   3 +
 .../smp/data/model/DBServiceMetadata.java     |   3 +
 .../ec/edelivery/smp/data/model/DBUser.java   |   3 +
 .../smp/config/SmpServicesTestConfig.java     |   7 +-
 ...actServiceGroupServiceIntegrationTest.java |  13 +-
 .../smp/services/AuditIntegrationTest.java    | 217 ++++++++++++++
 ...ServiceMultipleDomainsIntegrationTest.java |  24 +-
 ...oupServiceSingleDomainIntegrationTest.java |   7 +-
 .../ec/edelivery/smp/testutil/AuditUtils.java |  93 ++++++
 .../edelivery/smp/testutil/TestConstants.java |  21 ++
 smp-webapp/pom.xml                            |   2 +-
 .../edelivery/smp/config/DatabaseConfig.java  |   4 +
 .../mysql5innoDb-4.0.0-to-4.1.0.ddl           | 117 ++++++++
 ...reate-Mysql.sql => mysql5innoDb-4.0.0.ddl} |   0
 .../database-scripts/mysql5innoDb-4.1.0.ddl   | 275 ++++++++++++++++++
 .../oracle10g-4.0.0-to-4.1.0.ddl              |  78 +++++
 ...{create-Oracle.sql => oracle10g-4.0.0.ddl} |   0
 24 files changed, 997 insertions(+), 26 deletions(-)
 create mode 100644 smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/SMPRevisionListener.java
 create mode 100644 smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBRevisionLog.java
 create mode 100644 smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/AuditIntegrationTest.java
 create mode 100644 smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/AuditUtils.java
 create mode 100644 smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestConstants.java
 create mode 100755 smp-webapp/src/main/smp-setup/database-scripts/mysql5innoDb-4.0.0-to-4.1.0.ddl
 rename smp-webapp/src/main/smp-setup/database-scripts/{create-Mysql.sql => mysql5innoDb-4.0.0.ddl} (100%)
 create mode 100755 smp-webapp/src/main/smp-setup/database-scripts/mysql5innoDb-4.1.0.ddl
 create mode 100644 smp-webapp/src/main/smp-setup/database-scripts/oracle10g-4.0.0-to-4.1.0.ddl
 rename smp-webapp/src/main/smp-setup/database-scripts/{create-Oracle.sql => oracle10g-4.0.0.ddl} (100%)

diff --git a/smp-parent-pom/pom.xml b/smp-parent-pom/pom.xml
index 760e7df70..82e0e4217 100644
--- a/smp-parent-pom/pom.xml
+++ b/smp-parent-pom/pom.xml
@@ -263,6 +263,11 @@
 				<artifactId>hibernate-validator</artifactId>
 				<version>${hibernate.validator}</version>
 			</dependency>
+			<dependency>
+				<groupId>org.hibernate</groupId>
+				<artifactId>hibernate-envers</artifactId>
+				<version>${hibernate.version}</version>
+			</dependency>
 			<dependency>
 				<groupId>javax.xml.bind</groupId>
 				<artifactId>jaxb-api</artifactId>
diff --git a/smp-server-library/pom.xml b/smp-server-library/pom.xml
index f5d944cda..06254dbba 100644
--- a/smp-server-library/pom.xml
+++ b/smp-server-library/pom.xml
@@ -31,6 +31,13 @@
         <jdbc.password>smp</jdbc.password>
         <target-database>MySQL</target-database>
         <jdbc.read-connections.max>10</jdbc.read-connections.max>
+
+        <!-- jdbc.driver>oracle.jdbc.OracleDriver</jdbc.driver>
+        <jdbc.url>jdbc:oracle:thin:@192.168.56.102:1521/xe</jdbc.url>
+        <jdbc.user>smp</jdbc.user>
+        <jdbc.password>smp</jdbc.password>
+        <target-database>Oracle</target-database>
+        <jdbc.read-connections.max>10</jdbc.read-connections.max -->
     </properties>
 
     <dependencies>
@@ -87,6 +94,10 @@
             <groupId>org.hibernate</groupId>
             <artifactId>hibernate-core</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-envers</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/BaseDao.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/BaseDao.java
index 04c3d71e6..b27eb2582 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/BaseDao.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/BaseDao.java
@@ -43,6 +43,10 @@ public abstract class BaseDao<E extends BaseEntity> {
         em.detach(entity);
     }
 
+    public void merge(E entity) {
+        em.merge(entity);
+    }
+
     public void remove(E entity) {
         em.remove(entity);
     }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/SMPRevisionListener.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/SMPRevisionListener.java
new file mode 100644
index 000000000..05d72217e
--- /dev/null
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/SMPRevisionListener.java
@@ -0,0 +1,35 @@
+package eu.europa.ec.edelivery.smp.data.dao;
+
+import eu.europa.ec.edelivery.smp.data.model.DBRevisionLog;
+import eu.europa.ec.edelivery.smp.services.ServiceGroupService;
+import org.apache.commons.lang3.StringUtils;
+import org.hibernate.envers.RevisionListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import java.time.LocalDateTime;
+
+public class SMPRevisionListener implements RevisionListener {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ServiceGroupService.class);
+
+    @Override
+    public void newRevision(Object revisionEntity) {
+        DBRevisionLog rev = (DBRevisionLog) revisionEntity;
+        String username = getSessionUserName();
+        rev.setRevisionDate(LocalDateTime.now());
+        if (StringUtils.isEmpty(username)){
+            LOG.warn("Update database revision"+rev.getId()+" without session - authenticated user!");
+            rev.setUserName("anonymous");
+        } else {
+            rev.setUserName(getSessionUserName());
+        }
+    }
+
+    public String getSessionUserName() {
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        return authentication != null?authentication.getName():null;
+    }
+}
\ No newline at end of file
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java
index 65a1669ee..cfbdf0dc5 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBDomain.java
@@ -13,6 +13,8 @@
 
 package eu.europa.ec.edelivery.smp.data.model;
 
+import org.hibernate.envers.Audited;
+
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.Id;
@@ -28,6 +30,7 @@ import static eu.europa.ec.edelivery.smp.data.model.CommonColumnsLengths.MAX_IDE
  */
 @Entity
 @Table(name = "smp_domain")
+@Audited
 public class DBDomain implements BaseEntity{
 
     private String domainId;
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBOwnership.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBOwnership.java
index e526a40d4..e50d6638f 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBOwnership.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBOwnership.java
@@ -13,11 +13,14 @@
 
 package eu.europa.ec.edelivery.smp.data.model;
 
+import org.hibernate.envers.Audited;
+
 import javax.persistence.*;
 import java.io.Serializable;
 
 @Entity
 @Table (name = "smp_ownership")
+@Audited
 public class DBOwnership implements BaseEntity {
 
   private DBOwnershipId ownershipId;
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBRevisionLog.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBRevisionLog.java
new file mode 100644
index 000000000..5e91f387b
--- /dev/null
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBRevisionLog.java
@@ -0,0 +1,95 @@
+package eu.europa.ec.edelivery.smp.data.model;
+
+
+import eu.europa.ec.edelivery.smp.data.dao.SMPRevisionListener;
+import org.hibernate.envers.RevisionEntity;
+import org.hibernate.envers.RevisionNumber;
+import org.hibernate.envers.RevisionTimestamp;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+/**
+ * Own implementation of hibernate-envers Revision entity, in order to store the user and the modification type.
+ *
+ * @author Thomas Dussart
+ * @since 4.0
+ */
+@Entity
+@Table(name = "SMP_REV_INFO")
+@RevisionEntity(SMPRevisionListener.class)
+public class DBRevisionLog {
+
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    @RevisionNumber
+    private long id;
+
+    @RevisionTimestamp
+    private long timestamp;
+    /**
+     * User involve in this modification
+     */
+    @Column(name = "username")
+    private String userName;
+    /**
+     * Date of the modification.
+     */
+    @Column(name = "REVISION_DATE")
+    private LocalDateTime revisionDate;
+
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public LocalDateTime getRevisionDate() {
+        return revisionDate;
+    }
+
+    public void setRevisionDate(LocalDateTime revisionDate) {
+        this.revisionDate = revisionDate;
+    }
+
+    public long getId() {
+        return this.id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+
+    public long getTimestamp() {
+        return this.timestamp;
+    }
+
+    public void setTimestamp(long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public boolean equals(Object o) {
+        if(this == o) {
+            return true;
+        } else if(!(o instanceof DBRevisionLog)) {
+            return false;
+        } else {
+            DBRevisionLog that = (DBRevisionLog)o;
+            return this.id == that.id && this.timestamp == that.timestamp;
+        }
+    }
+
+    public int hashCode() {
+        int result = (int)this.id;
+        result = 31 * result + (int)(this.timestamp ^ this.timestamp >>> 32);
+        return result;
+    }
+
+
+}
\ No newline at end of file
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBServiceGroup.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBServiceGroup.java
index 6f9c848dc..c21364480 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBServiceGroup.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBServiceGroup.java
@@ -13,6 +13,8 @@
 
 package eu.europa.ec.edelivery.smp.data.model;
 
+import org.hibernate.envers.Audited;
+
 import javax.persistence.*;
 import java.io.Serializable;
 import java.util.HashSet;
@@ -23,6 +25,7 @@ import static javax.persistence.FetchType.LAZY;
 
 @Entity
 @Table(name = "smp_service_group")
+@Audited
 public class DBServiceGroup implements BaseEntity {
 
     private DBServiceGroupId serviceGroupId;
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBServiceMetadata.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBServiceMetadata.java
index 2dafbf133..8c474d6f3 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBServiceMetadata.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBServiceMetadata.java
@@ -13,6 +13,8 @@
 
 package eu.europa.ec.edelivery.smp.data.model;
 
+import org.hibernate.envers.Audited;
+
 import javax.persistence.*;
 import java.io.Serializable;
 
@@ -20,6 +22,7 @@ import static javax.persistence.FetchType.EAGER;
 
 @Entity
 @Table(name = "smp_service_metadata")
+@Audited
 public class DBServiceMetadata implements BaseEntity {
 
     private DBServiceMetadataId serviceMetadataId;
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBUser.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBUser.java
index d561605b6..c2563df62 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBUser.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/DBUser.java
@@ -12,6 +12,8 @@
  */
 package eu.europa.ec.edelivery.smp.data.model;
 
+import org.hibernate.envers.Audited;
+
 import javax.persistence.*;
 import java.io.Serializable;
 import java.util.HashSet;
@@ -21,6 +23,7 @@ import static eu.europa.ec.edelivery.smp.data.model.CommonColumnsLengths.MAX_USE
 
 @Entity
 @Table(name = "smp_user")
+@Audited
 public class DBUser implements BaseEntity {
 
     private String username;
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/SmpServicesTestConfig.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/SmpServicesTestConfig.java
index d41d1f7e0..c43b9f65a 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/SmpServicesTestConfig.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/config/SmpServicesTestConfig.java
@@ -13,6 +13,7 @@
 
 package eu.europa.ec.edelivery.smp.config;
 
+
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.*;
 import org.springframework.jdbc.datasource.DriverManagerDataSource;
@@ -23,6 +24,7 @@ import org.springframework.transaction.PlatformTransactionManager;
 
 import javax.persistence.EntityManagerFactory;
 import javax.sql.DataSource;
+import java.util.Properties;
 
 /**
  * Created by gutowpa on 21/09/2017.
@@ -61,11 +63,13 @@ public class SmpServicesTestConfig {
 
     @Bean
     public LocalContainerEntityManagerFactoryBean smpEntityManagerFactory() {
+        Properties prop = new Properties();
+        prop.setProperty("org.hibernate.envers.store_data_at_delete", "true");
         LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
         lef.setDataSource(dataSource());
         lef.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
+        lef.setJpaProperties(prop);
         lef.setPackagesToScan("eu.europa.ec.edelivery.smp.data.model");
-        //lef.setPersistenceXmlLocation("classpath:META-INF/smp-persistence.xml");
         return lef;
     }
 
@@ -76,4 +80,5 @@ public class SmpServicesTestConfig {
 
         return transactionManager;
     }
+
 }
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/AbstractServiceGroupServiceIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/AbstractServiceGroupServiceIntegrationTest.java
index c0f666543..05b9adb70 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/AbstractServiceGroupServiceIntegrationTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/AbstractServiceGroupServiceIntegrationTest.java
@@ -17,6 +17,7 @@ import eu.europa.ec.edelivery.smp.config.PropertiesSingleDomainTestConfig;
 import eu.europa.ec.edelivery.smp.config.SmpServicesTestConfig;
 import eu.europa.ec.edelivery.smp.data.dao.OwnershipDao;
 import eu.europa.ec.edelivery.smp.data.dao.ServiceGroupDao;
+import eu.europa.ec.edelivery.smp.testutil.TestConstants;
 import org.junit.runner.RunWith;
 import org.oasis_open.docs.bdxr.ns.smp._2016._05.ParticipantIdentifierType;
 import org.oasis_open.docs.bdxr.ns.smp._2016._05.ServiceGroup;
@@ -32,7 +33,7 @@ import java.io.IOException;
 
 import static eu.europa.ec.edelivery.smp.conversion.ServiceGroupConverter.unmarshal;
 import static eu.europa.ec.edelivery.smp.testutil.XmlTestUtils.loadDocumentAsString;
-import static eu.europa.ec.smp.api.Identifiers.asParticipantId;
+
 
 /**
  * Created by gutowpa on 27/03/2017.
@@ -43,11 +44,7 @@ import static eu.europa.ec.smp.api.Identifiers.asParticipantId;
 @Rollback(true)
 abstract class AbstractServiceGroupServiceIntegrationTest {
 
-    protected static final String SERVICE_GROUP_XML_PATH = "/eu/europa/ec/edelivery/smp/services/ServiceGroupPoland.xml";
-    protected static final ParticipantIdentifierType SERVICE_GROUP_ID = asParticipantId("participant-scheme-qns::urn:poland:ncpb");
-    public static final String ADMIN_USERNAME = "test_admin";
-    public static final String CERT_USER="CN=comon name,O=org,C=BE:0000000000000066";
-    public static final String CERT_USER_ENCODED="CN%3Dcomon%20name%2CO%3Dorg%2CC%3DBE%3A0000000000000066";
+;
 
     @PersistenceContext
     protected EntityManager em;
@@ -62,8 +59,8 @@ abstract class AbstractServiceGroupServiceIntegrationTest {
     protected ServiceGroupService serviceGroupService;
 
     protected ServiceGroup saveServiceGroup() throws IOException {
-        ServiceGroup inServiceGroup = unmarshal(loadDocumentAsString(SERVICE_GROUP_XML_PATH));
-        serviceGroupService.saveServiceGroup(inServiceGroup, null, ADMIN_USERNAME, ADMIN_USERNAME);
+        ServiceGroup inServiceGroup = unmarshal(loadDocumentAsString(TestConstants.SERVICE_GROUP_XML_PATH));
+        serviceGroupService.saveServiceGroup(inServiceGroup, null, TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_USERNAME);
         return inServiceGroup;
     }
 }
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/AuditIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/AuditIntegrationTest.java
new file mode 100644
index 000000000..da78c5a59
--- /dev/null
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/AuditIntegrationTest.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2017 European Commission | CEF eDelivery
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ *
+ * You may obtain a copy of the Licence attached in file: LICENCE-EUPL-v1.2.pdf
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and limitations under the Licence.
+ */
+
+package eu.europa.ec.edelivery.smp.services;
+
+import eu.europa.ec.edelivery.smp.config.PropertiesSingleDomainTestConfig;
+import eu.europa.ec.edelivery.smp.config.SmpServicesTestConfig;
+import eu.europa.ec.edelivery.smp.data.model.*;
+import org.hibernate.envers.AuditReader;
+import org.hibernate.envers.AuditReaderFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+
+import javax.persistence.*;
+import javax.xml.bind.JAXBException;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+;
+import java.util.Map;
+import java.util.UUID;
+
+import static org.junit.Assert.*;
+import static eu.europa.ec.edelivery.smp.testutil.AuditUtils.*;
+
+
+/**
+ * Created by rihtajo
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = {SmpServicesTestConfig.class, PropertiesSingleDomainTestConfig.class})
+public class AuditIntegrationTest {
+
+
+
+    // because envers creates audit on commit we user PersistenceUnit to control commit...
+    // (instead of  PersistenceContext and transaction annotations... )
+    @PersistenceUnit
+    EntityManagerFactory emf;
+
+
+    @Before
+    public void before() throws IOException {
+        clearDatabase();
+    }
+
+    @After
+    public void after() throws IOException {
+        clearDatabase();
+    }
+
+
+    private void clearDatabase(){
+
+        EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+
+        clearTable(em,"smp_service_metadata", "businessIdentifier='"+REVISION_BUSSINESS_ID+"'" +
+                " AND businessIdentifierScheme='"+REVISION_BUSSINESS_SCH+"'" +
+                " AND documentIdentifier='"+REVISION_DOCUMENT_ID+"'" +
+                " AND documentIdentifierScheme='"+REVISION_DOCUMENT_SCH+"'"
+        );
+
+        clearTable(em,"smp_ownership", "businessIdentifier='"+REVISION_BUSSINESS_ID+"'" +
+                " AND businessIdentifierScheme='"+REVISION_BUSSINESS_SCH+"'" +
+                " AND  username='"+REVISION_USER+"'"
+        );
+
+        clearTable(em,"smp_service_group", "businessIdentifier='"+REVISION_BUSSINESS_ID
+                +"' AND businessIdentifierScheme='"+REVISION_BUSSINESS_SCH+"'");
+
+        clearTable(em,"smp_user", "username='"+REVISION_USER+"'");
+        clearTable(em,"smp_domain", "domainId='"+REVISION_DOMAIN+"'");
+
+        em.getTransaction().commit();
+    }
+
+    public void clearTable(EntityManager em, String tableName, String condition){
+        System.out.printf(String.format("DELETE FROM %s WHERE %s", tableName, condition));
+        System.out.printf(String.format("DELETE FROM %s_AUD WHERE %s", tableName, condition));
+        Query qTable = em.createNativeQuery(String.format("DELETE FROM %s WHERE %s", tableName, condition));
+        Query qTableAud = em.createNativeQuery(String.format("DELETE FROM %s_AUD WHERE %s", tableName, condition));
+        qTable.executeUpdate();
+        qTableAud.executeUpdate();
+    }
+
+    @Test
+    public void testClassesForAudit() throws IOException, JAXBException {
+        AuditReader ar = AuditReaderFactory.get(emf.createEntityManager());
+        assertTrue(ar.isEntityClassAudited(DBServiceGroup.class));
+        assertTrue(ar.isEntityClassAudited(DBServiceMetadata.class));
+        assertTrue(ar.isEntityClassAudited(DBOwnership.class));
+        assertTrue(ar.isEntityClassAudited(DBDomain.class));
+        assertTrue(ar.isEntityClassAudited(DBUser.class));
+    }
+
+
+    @Test
+    public void testAuditDBServiceGroup() {
+
+        DBServiceGroup grp = createDBServiceGroup();
+
+        EntityManager em = emf.createEntityManager();
+        persist(em, grp.getDomain());
+        Map<String, Object> alterVal = new HashMap<>();
+        alterVal.put("Extension", UUID.randomUUID().toString());
+
+        testAuditEntity(DBServiceGroup.class, grp.getId(),grp,alterVal );
+    }
+
+    @Test
+    public void testAuditDBMetaData() {
+
+        DBServiceMetadata md = createDBServiceMetadata();
+        EntityManager em = emf.createEntityManager();
+        persist(em, md.getServiceGroup().getDomain());
+        persist(em, md.getServiceGroup());
+        Map<String, Object> alterVal = new HashMap<>();
+        alterVal.put("XmlContent", UUID.randomUUID().toString());
+
+        testAuditEntity(DBServiceMetadata.class, md.getId(),md,alterVal );
+    }
+
+    @Test
+    public void testAuditDBUser() {
+
+        DBUser dbuser = createDBUser();
+        Map<String, Object> alterVal = new HashMap<>();
+        alterVal.put("Password", UUID.randomUUID().toString());
+
+        testAuditEntity(DBUser.class, REVISION_USER,dbuser,alterVal );
+    }
+
+    @Test
+    public void testAuditDBOwnership() {
+
+        DBOwnership owsh = createDBOwnership();
+        EntityManager em = emf.createEntityManager();
+        persist(em, owsh.getServiceGroup().getDomain());
+        persist(em, owsh.getServiceGroup());
+        persist(em, owsh.getUser());
+
+        testAuditEntity(DBOwnership.class, owsh.getId(),owsh,null );
+    }
+
+    @Test
+    public void testAuditDBDomain() {
+
+        DBDomain domain = createDBDomain();
+        Map<String, Object> alterVal = new HashMap<>();
+        alterVal.put("BdmslSmpId", UUID.randomUUID().toString());
+        alterVal.put("BdmslClientCertAlias", UUID.randomUUID().toString());
+
+        testAuditEntity(DBDomain.class, REVISION_DOMAIN,domain,alterVal );
+    }
+
+
+
+
+    private void testAuditEntity(Class cls, Object id, Object entity, Map<String, Object> alterValues ) {
+        EntityManager em = emf.createEntityManager();
+
+        AuditReader ar = AuditReaderFactory.get(em);
+        // persist
+        persist(em, entity);
+        int iRevSize = ar.getRevisions(cls, id).size();
+        // update
+        if (alterValues != null && !alterValues.isEmpty()) {
+            alterValues.forEach((prop, val) -> {
+                reflectionSetFiled(cls, entity, prop, val);
+            });
+            update(em, entity);
+            assertEquals(++iRevSize, ar.getRevisions(cls, id).size());
+        }
+
+        // remove
+        remove(em, cls, id);
+        assertEquals(++iRevSize,ar.getRevisions(cls, id ).size());
+    }
+
+   private void persist(EntityManager em, Object dbEnetity){
+       em.getTransaction().begin();
+       em.persist(dbEnetity);
+       em.getTransaction().commit();
+   }
+
+    private void update(EntityManager em, Object dbEntity){
+        em.getTransaction().begin();
+        em.merge(dbEntity);
+        em.getTransaction().commit();
+    }
+
+    private void remove(EntityManager em, Class cls,  Object dbId){
+        em.getTransaction().begin();
+        // get attached reference to delete it
+        Object dbEntity = em.getReference(cls, dbId);
+
+        em.remove(dbEntity);
+        em.getTransaction().commit();
+    }
+}
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ServiceGroupServiceMultipleDomainsIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ServiceGroupServiceMultipleDomainsIntegrationTest.java
index 7f44fadcb..4a28efd35 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ServiceGroupServiceMultipleDomainsIntegrationTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ServiceGroupServiceMultipleDomainsIntegrationTest.java
@@ -16,6 +16,7 @@ package eu.europa.ec.edelivery.smp.services;
 import eu.europa.ec.edelivery.smp.data.model.DBDomain;
 import eu.europa.ec.edelivery.smp.data.model.DBServiceGroup;
 import eu.europa.ec.edelivery.smp.exceptions.WrongInputFieldException;
+import eu.europa.ec.edelivery.smp.testutil.TestConstants;
 import org.junit.Test;
 import org.oasis_open.docs.bdxr.ns.smp._2016._05.ServiceGroup;
 import org.springframework.test.context.jdbc.Sql;
@@ -36,10 +37,7 @@ import static org.springframework.util.StringUtils.isEmpty;
         "classpath:/service_integration_multiple_domains_test_data.sql"})
 public class ServiceGroupServiceMultipleDomainsIntegrationTest extends AbstractServiceGroupServiceIntegrationTest {
 
-    private static final String SECOND_DOMAIN_ID = "domain2";
-    private static final String SECOND_DOMAIN_CERT_HEADER = "client-cert-header-value";
-    private static final String SECOND_DOMAIN_SIGNING_ALIAS = "signature-alias";
-    private static final String SECOND_DOMAIN_SMP_ID = "SECOND-SMP-ID";
+    ;
 
     @Test(expected = WrongInputFieldException.class)
     public void explictlySpecifiedDomainIsRequiredWhenSavingInMultipleDomainConfiguration() throws IOException {
@@ -49,18 +47,18 @@ public class ServiceGroupServiceMultipleDomainsIntegrationTest extends AbstractS
     @Test
     public void saveAndReadPositiveScenarioForMultipleDomain() throws IOException {
         // given
-        ServiceGroup inServiceGroup = unmarshal(loadDocumentAsString(SERVICE_GROUP_XML_PATH));
-        serviceGroupService.saveServiceGroup(inServiceGroup, SECOND_DOMAIN_ID, ADMIN_USERNAME, ADMIN_USERNAME);
+        ServiceGroup inServiceGroup = unmarshal(loadDocumentAsString(TestConstants.SERVICE_GROUP_XML_PATH));
+        serviceGroupService.saveServiceGroup(inServiceGroup, TestConstants.SECOND_DOMAIN_ID, TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_USERNAME);
 
         // when
-        DBServiceGroup dbServiceGroup = serviceGroupDao.find(toDbModel(SERVICE_GROUP_ID));
+        DBServiceGroup dbServiceGroup = serviceGroupDao.find(toDbModel(TestConstants.SERVICE_GROUP_ID));
 
         // then
         DBDomain dbDomain = dbServiceGroup.getDomain();
-        assertEquals(SECOND_DOMAIN_ID, dbDomain.getId());
-        assertEquals(SECOND_DOMAIN_CERT_HEADER, dbDomain.getBdmslClientCertHeader());
-        assertEquals(SECOND_DOMAIN_SIGNING_ALIAS, dbDomain.getSignatureCertAlias());
-        assertEquals(SECOND_DOMAIN_SMP_ID, dbDomain.getBdmslSmpId());
+        assertEquals(TestConstants.SECOND_DOMAIN_ID, dbDomain.getId());
+        assertEquals(TestConstants.SECOND_DOMAIN_CERT_HEADER, dbDomain.getBdmslClientCertHeader());
+        assertEquals(TestConstants.SECOND_DOMAIN_SIGNING_ALIAS, dbDomain.getSignatureCertAlias());
+        assertEquals(TestConstants.SECOND_DOMAIN_SMP_ID, dbDomain.getBdmslSmpId());
         assertTrue(isEmpty(dbDomain.getBdmslClientCertAlias()));
     }
 
@@ -68,10 +66,10 @@ public class ServiceGroupServiceMultipleDomainsIntegrationTest extends AbstractS
     public void changingDomainOfExistingServiceGroupIsNotAllowed() throws Throwable {
         //given
         saveServiceGroup();
-        ServiceGroup newServiceGroup = unmarshal(loadDocumentAsString(SERVICE_GROUP_XML_PATH));
+        ServiceGroup newServiceGroup = unmarshal(loadDocumentAsString(TestConstants.SERVICE_GROUP_XML_PATH));
 
         //when-then
-        serviceGroupService.saveServiceGroup(newServiceGroup, SECOND_DOMAIN_ID, ADMIN_USERNAME, ADMIN_USERNAME);
+        serviceGroupService.saveServiceGroup(newServiceGroup, TestConstants.SECOND_DOMAIN_ID, TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_USERNAME);
     }
 
 
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ServiceGroupServiceSingleDomainIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ServiceGroupServiceSingleDomainIntegrationTest.java
index 57f2c29bf..8653a2d58 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ServiceGroupServiceSingleDomainIntegrationTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ServiceGroupServiceSingleDomainIntegrationTest.java
@@ -39,17 +39,17 @@ import static eu.europa.ec.edelivery.smp.conversion.ServiceGroupConverter.unmars
 import static eu.europa.ec.edelivery.smp.testutil.XmlTestUtils.loadDocumentAsString;
 import static eu.europa.ec.edelivery.smp.testutil.XmlTestUtils.marshall;
 import static eu.europa.ec.smp.api.Identifiers.asParticipantId;
+
 import static org.junit.Assert.*;
+import static eu.europa.ec.edelivery.smp.testutil.TestConstants.*;
 
 /**
  * Created by gutowpa on 17/01/2018.
  */
+
 @Sql("classpath:/service_integration_test_data.sql")
 public class ServiceGroupServiceSingleDomainIntegrationTest extends AbstractServiceGroupServiceIntegrationTest {
 
-    private static String UnknownUser="UnknownUser";
-
-
 
     @Rule
     public ExpectedException expectedExeption = ExpectedException.none();
@@ -126,6 +126,7 @@ public class ServiceGroupServiceSingleDomainIntegrationTest extends AbstractServ
         String invalidServiceUser = "WrongOwner";
         //given
         ServiceGroup oldServiceGroup = saveServiceGroup();
+
         expectedExeption.expect(UnknownUserException.class);
         expectedExeption.expectMessage("Unknown user '"+invalidServiceUser+"'");
 
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/AuditUtils.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/AuditUtils.java
new file mode 100644
index 000000000..85bef330a
--- /dev/null
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/AuditUtils.java
@@ -0,0 +1,93 @@
+package eu.europa.ec.edelivery.smp.testutil;
+
+import eu.europa.ec.edelivery.smp.data.model.*;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.UUID;
+
+public class AuditUtils {
+    public static final String REVISION_USER ="REVISION_USER";
+    public static final String REVISION_DOMAIN ="REVISION_DOMAIN";
+
+    public static final String REVISION_BUSSINESS_ID ="REVISION_BUSSINESS_ID";
+    public static final String REVISION_BUSSINESS_SCH ="REVISION_BUSSINESS_SCH";
+
+    public static final String REVISION_DOCUMENT_ID ="REVISION_DOCUMENT_ID";
+    public static final String REVISION_DOCUMENT_SCH ="REVISION_DOCUMENT_SCH";
+
+    public static void reflectionSetFiled(Class clazz, Object entity, String filedName, Object newValue ) {
+        try {
+            Method method = clazz.getMethod("set"+filedName, newValue.getClass());
+            method.invoke(entity, newValue);
+        } catch ( NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    public static DBUser createDBUser(){
+        DBUser dbuser = new DBUser();
+        dbuser.setUsername(REVISION_USER);
+        dbuser.setAdmin(true);
+        dbuser.setPassword(UUID.randomUUID().toString());
+        return dbuser;
+    }
+
+    public static DBDomain createDBDomain(){
+        DBDomain domain = new DBDomain();
+        domain.setId(REVISION_DOMAIN);
+        domain.setBdmslClientCertAlias(UUID.randomUUID().toString());
+        domain.setBdmslSmpId(UUID.randomUUID().toString());
+        return domain;
+    }
+
+    public static DBServiceGroup createDBServiceGroup(){
+        DBServiceGroupId grpID = new DBServiceGroupId();
+        grpID.setBusinessIdentifier(REVISION_BUSSINESS_ID);
+        grpID.setBusinessIdentifierScheme(REVISION_BUSSINESS_SCH);
+
+        DBDomain dbDomain = createDBDomain();
+
+        DBServiceGroup grp = new DBServiceGroup();
+        grp.setId(grpID);
+        grp.setDomain(dbDomain);
+        grp.setExtension(UUID.randomUUID().toString());
+        return grp;
+    }
+
+    public static DBOwnership createDBOwnership(){
+        DBServiceGroup grp = createDBServiceGroup();
+
+        DBUser dbuser = createDBUser();
+
+        DBOwnershipId ownID = new DBOwnershipId();
+        ownID.setBusinessIdentifier(grp.getId().getBusinessIdentifier());
+        ownID.setBusinessIdentifierScheme(grp.getId().getBusinessIdentifierScheme());
+        ownID.setUsername(dbuser.getUsername());
+
+        DBOwnership own = new DBOwnership();
+        own.setId(ownID);
+        own.setServiceGroup(grp);
+        own.setUser(dbuser);
+        return own;
+    }
+
+    public static DBServiceMetadata createDBServiceMetadata(){
+        DBServiceGroup grp = createDBServiceGroup();
+
+
+        DBServiceMetadataId smdId = new DBServiceMetadataId();
+        smdId.setBusinessIdentifier(grp.getId().getBusinessIdentifier());
+        smdId.setBusinessIdentifierScheme(grp.getId().getBusinessIdentifierScheme());
+        smdId.setDocumentIdentifier(REVISION_DOCUMENT_ID);
+        smdId.setDocumentIdentifierScheme(REVISION_DOCUMENT_SCH);
+
+        DBServiceMetadata smd = new DBServiceMetadata();
+        smd.setId(smdId);
+        smd.setServiceGroup(grp);
+        smd.setXmlContent(UUID.randomUUID().toString());
+
+
+        return smd;
+    }
+}
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestConstants.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestConstants.java
new file mode 100644
index 000000000..b8fd6bb66
--- /dev/null
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestConstants.java
@@ -0,0 +1,21 @@
+package eu.europa.ec.edelivery.smp.testutil;
+
+import org.oasis_open.docs.bdxr.ns.smp._2016._05.ParticipantIdentifierType;
+
+import static eu.europa.ec.smp.api.Identifiers.asParticipantId;
+
+public class TestConstants {
+
+    public static final String SERVICE_GROUP_XML_PATH = "/eu/europa/ec/edelivery/smp/services/ServiceGroupPoland.xml";
+    public static final ParticipantIdentifierType SERVICE_GROUP_ID = asParticipantId("participant-scheme-qns::urn:poland:ncpb");
+
+    public static final String ADMIN_USERNAME = "test_admin";
+    public static final String CERT_USER="CN=comon name,O=org,C=BE:0000000000000066";
+    public static final String CERT_USER_ENCODED="CN%3Dcomon%20name%2CO%3Dorg%2CC%3DBE%3A0000000000000066";
+
+
+    public static final String SECOND_DOMAIN_ID = "domain2";
+    public static final String SECOND_DOMAIN_CERT_HEADER = "client-cert-header-value";
+    public static final String SECOND_DOMAIN_SIGNING_ALIAS = "signature-alias";
+    public static final String SECOND_DOMAIN_SMP_ID = "SECOND-SMP-ID";
+}
diff --git a/smp-webapp/pom.xml b/smp-webapp/pom.xml
index 49af3b13d..1fe05f656 100644
--- a/smp-webapp/pom.xml
+++ b/smp-webapp/pom.xml
@@ -21,7 +21,7 @@
         <ftp.port>2059</ftp.port>
         <ftp.remotedir>/ec/test/server/weblogic/u010/home/digciedt/data/CIPA-EDEL_DEV/autodeploy</ftp.remotedir>
 
-        <!-- database -->
+        <!-- database-->
         <jdbc.driver>com.mysql.jdbc.Driver</jdbc.driver>
         <jdbc.url>jdbc:mysql://localhost:3306/smp</jdbc.url>
         <jdbc.user>smp</jdbc.user>
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/DatabaseConfig.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/DatabaseConfig.java
index fc4edd576..123c879bb 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/DatabaseConfig.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/DatabaseConfig.java
@@ -26,6 +26,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
 
 import javax.persistence.EntityManagerFactory;
 import javax.sql.DataSource;
+import java.util.Properties;
 
 /**
  * Created by Flavio Santos
@@ -61,10 +62,13 @@ public class DatabaseConfig {
 
     @Bean
     public LocalContainerEntityManagerFactoryBean smpEntityManagerFactory() {
+        Properties prop = new Properties();
+        prop.setProperty("org.hibernate.envers.store_data_at_delete", "true");
         LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
         lef.setDataSource(dataSource());
         lef.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
         lef.setPackagesToScan("eu.europa.ec.edelivery.smp.data.model");
+        lef.setJpaProperties(prop);
         //lef.setPersistenceXmlLocation("classpath:META-INF/smp-persistence.xml");
         return lef;
     }
diff --git a/smp-webapp/src/main/smp-setup/database-scripts/mysql5innoDb-4.0.0-to-4.1.0.ddl b/smp-webapp/src/main/smp-setup/database-scripts/mysql5innoDb-4.0.0-to-4.1.0.ddl
new file mode 100755
index 000000000..0f6e0cf55
--- /dev/null
+++ b/smp-webapp/src/main/smp-setup/database-scripts/mysql5innoDb-4.0.0-to-4.1.0.ddl
@@ -0,0 +1,117 @@
+-- Copyright 2018 European Commission | CEF eDelivery
+--
+-- Licensed under the EUPL, Version 1.2
+--
+-- You may obtain a copy of the Licence attached in file: LICENCE-EUPL-v1.2.pdf
+--
+-- Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the Licence for the specific language governing permissions and limitations under the Licence.
+
+CREATE TABLE smp_domain_AUD (
+  domainId              VARCHAR(50)
+                        CHARACTER SET utf8
+                        COLLATE utf8_bin NOT NULL,
+  bdmslClientCertHeader VARCHAR(4000)
+                        CHARACTER SET utf8
+                        COLLATE utf8_bin NULL,
+  bdmslClientCertAlias  VARCHAR(50)
+                        CHARACTER SET utf8
+                        COLLATE utf8_bin NULL,
+  bdmslSmpId            VARCHAR(50)
+                        CHARACTER SET utf8
+                        COLLATE utf8_bin NOT NULL,
+  signatureCertAlias    VARCHAR(50)
+                        CHARACTER SET utf8
+                        COLLATE utf8_bin NULL,
+  REV integer not null,
+  REVTYPE tinyint,
+  PRIMARY KEY(domainId, REV)
+)
+  ENGINE = InnoDB
+  DEFAULT CHARSET = utf8;
+
+CREATE TABLE smp_service_group_AUD (
+  businessIdentifier       VARCHAR(50)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  businessIdentifierScheme VARCHAR(100)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  domainId                 VARCHAR(50)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL
+                           DEFAULT 'domain1',
+  extension                TEXT             NULL DEFAULT NULL,
+  REV integer not null,
+  REVTYPE tinyint,
+  PRIMARY KEY (businessIdentifier, businessIdentifierScheme, REV)
+)
+  ENGINE = InnoDB
+  DEFAULT CHARSET = utf8;
+
+
+CREATE TABLE smp_service_metadata_AUD (
+  documentIdentifier       VARCHAR(500)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  documentIdentifierScheme VARCHAR(100)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  businessIdentifier       VARCHAR(50)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  businessIdentifierScheme VARCHAR(100)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  xmlcontent               TEXT,
+  REV integer not null,
+  REVTYPE tinyint,
+  PRIMARY KEY (documentIdentifier, documentIdentifierScheme, businessIdentifier, businessIdentifierScheme, REV)
+)
+  ENGINE = InnoDB
+  DEFAULT CHARSET = utf8;
+
+
+CREATE TABLE smp_user_AUD (
+  username VARCHAR(256)         NOT NULL,
+  password VARCHAR(256),
+  isadmin  TINYINT(1) DEFAULT 0 NOT NULL,
+  REV integer not null,
+  REVTYPE tinyint,
+  PRIMARY KEY (username, REV)
+)
+  ENGINE = InnoDB
+  DEFAULT CHARSET = utf8;
+
+
+CREATE TABLE smp_ownership_AUD (
+  username                 VARCHAR(256)     NOT NULL,
+  businessIdentifier       VARCHAR(50)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  businessIdentifierScheme VARCHAR(100)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  REV integer not null,
+  REVTYPE tinyint,
+  PRIMARY KEY (username, businessIdentifier, businessIdentifierScheme, REV)
+)
+  ENGINE = InnoDB
+  DEFAULT CHARSET = utf8;
+
+
+CREATE TABLE SMP_REV_INFO (
+  ID INT AUTO_INCREMENT NOT NULL,
+  TIMESTAMP BIGINT NULL,
+  REVISION_DATE timestamp NULL,
+  username VARCHAR(256)         NOT NULL,
+  CONSTRAINT PK_SMP_REV_INFO PRIMARY KEY (ID)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8;
+
+create table hibernate_sequence ( next_val bigint );
+create sequence hibernate_sequence;
+
+
+commit;
diff --git a/smp-webapp/src/main/smp-setup/database-scripts/create-Mysql.sql b/smp-webapp/src/main/smp-setup/database-scripts/mysql5innoDb-4.0.0.ddl
similarity index 100%
rename from smp-webapp/src/main/smp-setup/database-scripts/create-Mysql.sql
rename to smp-webapp/src/main/smp-setup/database-scripts/mysql5innoDb-4.0.0.ddl
diff --git a/smp-webapp/src/main/smp-setup/database-scripts/mysql5innoDb-4.1.0.ddl b/smp-webapp/src/main/smp-setup/database-scripts/mysql5innoDb-4.1.0.ddl
new file mode 100755
index 000000000..d43ddcead
--- /dev/null
+++ b/smp-webapp/src/main/smp-setup/database-scripts/mysql5innoDb-4.1.0.ddl
@@ -0,0 +1,275 @@
+-- Copyright 2018 European Commission | CEF eDelivery
+--
+-- Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence");
+-- You may not use this work except in compliance with the Licence.
+--
+-- You may obtain a copy of the Licence attached in file: LICENCE-EUPL-v1.2.pdf
+--
+-- Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the Licence for the specific language governing permissions and limitations under the Licence.
+
+CREATE TABLE smp_domain (
+  domainId              VARCHAR(50)
+                        CHARACTER SET utf8
+                        COLLATE utf8_bin NOT NULL,
+  bdmslClientCertHeader VARCHAR(4000)
+                        CHARACTER SET utf8
+                        COLLATE utf8_bin NULL,
+  bdmslClientCertAlias  VARCHAR(50)
+                        CHARACTER SET utf8
+                        COLLATE utf8_bin NULL,
+  bdmslSmpId            VARCHAR(50)
+                        CHARACTER SET utf8
+                        COLLATE utf8_bin NOT NULL,
+  signatureCertAlias    VARCHAR(50)
+                        CHARACTER SET utf8
+                        COLLATE utf8_bin NULL,
+  PRIMARY KEY(domainId)
+)
+  ENGINE = InnoDB
+  DEFAULT CHARSET = utf8;
+
+
+CREATE TABLE smp_domain_AUD (
+  domainId              VARCHAR(50)
+                        CHARACTER SET utf8
+                        COLLATE utf8_bin NOT NULL,
+  bdmslClientCertHeader VARCHAR(4000)
+                        CHARACTER SET utf8
+                        COLLATE utf8_bin NULL,
+  bdmslClientCertAlias  VARCHAR(50)
+                        CHARACTER SET utf8
+                        COLLATE utf8_bin NULL,
+  bdmslSmpId            VARCHAR(50)
+                        CHARACTER SET utf8
+                        COLLATE utf8_bin NOT NULL,
+  signatureCertAlias    VARCHAR(50)
+                        CHARACTER SET utf8
+                        COLLATE utf8_bin NULL,
+  REV integer not null,
+  REVTYPE tinyint,
+  PRIMARY KEY(domainId, REV)
+)
+  ENGINE = InnoDB
+  DEFAULT CHARSET = utf8;
+
+
+
+CREATE TABLE smp_service_group (
+  businessIdentifier       VARCHAR(50)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  businessIdentifierScheme VARCHAR(100)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  domainId                 VARCHAR(50)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL
+                           DEFAULT 'domain1',
+  extension                TEXT             NULL DEFAULT NULL,
+  PRIMARY KEY (businessIdentifier, businessIdentifierScheme),
+  CONSTRAINT FK_srv_group_domain FOREIGN KEY (domainId)
+    REFERENCES smp_domain (domainId)
+)
+  ENGINE = InnoDB
+  DEFAULT CHARSET = utf8;
+
+CREATE TABLE smp_service_group_AUD (
+  businessIdentifier       VARCHAR(50)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  businessIdentifierScheme VARCHAR(100)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  domainId                 VARCHAR(50)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL
+                           DEFAULT 'domain1',
+  extension                TEXT             NULL DEFAULT NULL,
+  REV integer not null,
+  REVTYPE tinyint,
+  PRIMARY KEY (businessIdentifier, businessIdentifierScheme, REV)
+)
+  ENGINE = InnoDB
+  DEFAULT CHARSET = utf8;
+
+CREATE TABLE smp_service_metadata (
+  documentIdentifier       VARCHAR(500)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  documentIdentifierScheme VARCHAR(100)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  businessIdentifier       VARCHAR(50)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  businessIdentifierScheme VARCHAR(100)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  xmlcontent               TEXT,
+  PRIMARY KEY (documentIdentifier, documentIdentifierScheme, businessIdentifier, businessIdentifierScheme),
+  KEY FK_service_metadata_service_group (businessIdentifier, businessIdentifierScheme),
+  CONSTRAINT FK_service_metadata_service_group FOREIGN KEY (businessIdentifier, businessIdentifierScheme) REFERENCES smp_service_group (businessIdentifier, businessIdentifierScheme)
+    ON DELETE CASCADE
+    ON UPDATE CASCADE
+)
+  ENGINE = InnoDB
+  DEFAULT CHARSET = utf8;
+
+CREATE TABLE smp_service_metadata_AUD (
+  documentIdentifier       VARCHAR(500)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  documentIdentifierScheme VARCHAR(100)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  businessIdentifier       VARCHAR(50)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  businessIdentifierScheme VARCHAR(100)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  xmlcontent               TEXT,
+  REV integer not null,
+  REVTYPE tinyint,
+  PRIMARY KEY (documentIdentifier, documentIdentifierScheme, businessIdentifier, businessIdentifierScheme, REV)
+)
+  ENGINE = InnoDB
+  DEFAULT CHARSET = utf8;
+
+
+CREATE TABLE smp_user (
+  username VARCHAR(256)         NOT NULL,
+  password VARCHAR(256),
+  isadmin  TINYINT(1) DEFAULT 0 NOT NULL,
+  PRIMARY KEY (username)
+)
+  ENGINE = InnoDB
+  DEFAULT CHARSET = utf8;
+
+CREATE TABLE smp_user_AUD (
+  username VARCHAR(256)         NOT NULL,
+  password VARCHAR(256),
+  isadmin  TINYINT(1) DEFAULT 0 NOT NULL,
+  REV integer not null,
+  REVTYPE tinyint,
+  PRIMARY KEY (username, REV)
+)
+  ENGINE = InnoDB
+  DEFAULT CHARSET = utf8;
+
+
+CREATE TABLE smp_ownership (
+  username                 VARCHAR(256)     NOT NULL,
+  businessIdentifier       VARCHAR(50)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  businessIdentifierScheme VARCHAR(100)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  KEY FK_ownership_service_group (businessIdentifier, businessIdentifierScheme),
+  KEY FK_ownership_user (username),
+  CONSTRAINT FK_ownership_service_group FOREIGN KEY (businessIdentifier, businessIdentifierScheme) REFERENCES smp_service_group (businessIdentifier, businessIdentifierScheme)
+    ON DELETE CASCADE
+    ON UPDATE CASCADE,
+  CONSTRAINT FK_ownership_user FOREIGN KEY (username) REFERENCES smp_user (username)
+    ON DELETE CASCADE
+    ON UPDATE CASCADE
+)
+  ENGINE = InnoDB
+  DEFAULT CHARSET = utf8;
+
+
+CREATE TABLE smp_ownership_AUD (
+  username                 VARCHAR(256)     NOT NULL,
+  businessIdentifier       VARCHAR(50)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  businessIdentifierScheme VARCHAR(100)
+                           CHARACTER SET utf8
+                           COLLATE utf8_bin NOT NULL,
+  REV integer not null,
+  REVTYPE tinyint,
+  PRIMARY KEY (username, businessIdentifier, businessIdentifierScheme, REV)
+)
+  ENGINE = InnoDB
+  DEFAULT CHARSET = utf8;
+
+
+CREATE TABLE SMP_REV_INFO (
+  ID INT AUTO_INCREMENT NOT NULL,
+  TIMESTAMP BIGINT NULL,
+  REVISION_DATE timestamp NULL,
+  USER_NAME VARCHAR(255) NULL,
+  CONSTRAINT PK_SMP_REV_INFO PRIMARY KEY (ID)
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8;
+
+
+
+DELIMITER //
+
+DROP PROCEDURE IF EXISTS validate_new_user //
+CREATE PROCEDURE validate_new_user (IN new_user_is_admin TINYINT(1))
+BEGIN
+    IF new_user_is_admin <> 0 AND new_user_is_admin <> 1
+    THEN
+      SIGNAL SQLSTATE '99999'
+      SET MESSAGE_TEXT = '0 or 1 are the only allowed values for ISADMIN column';
+    END IF;
+  END //
+
+DROP PROCEDURE IF EXISTS validate_new_domain //
+CREATE PROCEDURE validate_new_domain (IN new_bdmsl_client_cert_alias varchar(50), IN new_bdmsl_client_cert_header varchar(4000))
+BEGIN
+    IF ((new_bdmsl_client_cert_alias > '' OR new_bdmsl_client_cert_alias = null) AND (new_bdmsl_client_cert_header > '' OR new_bdmsl_client_cert_header = null))
+    THEN
+      SIGNAL SQLSTATE '99999'
+      SET MESSAGE_TEXT = 'Both BDMSL authentication ways cannot be switched ON at the same time: bdmslClientCertAlias and bdmslClientCertHeader';
+    END IF;
+  END //
+
+
+DROP TRIGGER IF EXISTS smp_domain_check_bdmsl_auth_before_insert //
+DROP TRIGGER IF EXISTS smp_domain_check_bdmsl_auth_before_update //
+CREATE TRIGGER smp_domain_check_bdmsl_auth_before_update
+BEFORE UPDATE ON smp_domain
+FOR EACH ROW
+  BEGIN
+    call validate_new_domain(NEW.bdmslClientCertAlias, NEW.bdmslClientCertHeader);
+  END //
+CREATE TRIGGER smp_domain_check_bdmsl_auth_before_insert
+BEFORE INSERT ON smp_domain
+FOR EACH ROW
+  BEGIN
+    call validate_new_domain(NEW.bdmslClientCertAlias, NEW.bdmslClientCertHeader);
+  END //
+
+
+DROP TRIGGER IF EXISTS smp_user_check_is_admin_value_before_insert //
+DROP TRIGGER IF EXISTS smp_user_check_is_admin_value_before_update //
+
+CREATE TRIGGER smp_user_check_is_admin_value_before_insert
+BEFORE INSERT ON smp_user
+FOR EACH ROW
+  BEGIN
+	call validate_new_user(NEW.ISADMIN);
+  END //
+CREATE TRIGGER smp_user_check_is_admin_value_before_update
+BEFORE UPDATE ON smp_user
+FOR EACH ROW
+  BEGIN
+	call validate_new_user(NEW.ISADMIN);
+  END //
+
+DELIMITER ;
+
+create table hibernate_sequence ( next_val bigint );
+create sequence hibernate_sequence;
+
+INSERT INTO smp_domain(domainId, bdmslSmpId) VALUES('domain1', 'DEFAULT-SMP-ID');
+-- default admin user with password "changeit"
+INSERT INTO smp_user(username, password, isadmin) VALUES ('smp_admin', '$2a$10$SZXMo7K/wA.ULWxH7uximOxeNk4mf3zU6nxJx/2VfKA19QlqwSpNO', '1');
+
+commit;
diff --git a/smp-webapp/src/main/smp-setup/database-scripts/oracle10g-4.0.0-to-4.1.0.ddl b/smp-webapp/src/main/smp-setup/database-scripts/oracle10g-4.0.0-to-4.1.0.ddl
new file mode 100644
index 000000000..e83c39ad7
--- /dev/null
+++ b/smp-webapp/src/main/smp-setup/database-scripts/oracle10g-4.0.0-to-4.1.0.ddl
@@ -0,0 +1,78 @@
+--
+-- Copyright 2018 European Commission | CEF eDelivery
+--
+-- Licensed under the EUPL, Version 1.2;
+-- You may not use this work except in compliance with the Licence.
+--
+-- You may obtain a copy of the Licence attached in file: LICENCE-EUPL-v1.2.pdf
+--
+-- Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the Licence for the specific language governing permissions and limitations under the Licence.
+
+CREATE TABLE smp_domain_AUD (
+  domainId              VARCHAR(50),
+  bdmslClientCertHeader VARCHAR(4000),
+  bdmslClientCertAlias  VARCHAR(50),
+  bdmslSmpId            VARCHAR(50),
+  signatureCertAlias    VARCHAR(50),
+  REV INTEGER NOT NULL, 
+  REVTYPE NUMBER(3),
+  CONSTRAINT PK_SMP_DOMAIN_AUD PRIMARY KEY(domainId)
+);
+
+CREATE TABLE smp_service_group_AUD (
+  extension                CLOB,
+  businessIdentifier       VARCHAR(50),
+  businessIdentifierScheme VARCHAR(100),
+  domainId                 VARCHAR(50),
+  REV INTEGER NOT NULL, 
+  REVTYPE NUMBER(3),
+  CONSTRAINT PK_SMP_GRP_AUD PRIMARY KEY (businessIdentifier, businessIdentifierScheme)
+);
+
+CREATE TABLE smp_service_metadata_AUD (
+  documentIdentifierScheme VARCHAR(100),
+  businessIdentifier       VARCHAR(50) ,
+  businessIdentifierScheme VARCHAR(100),
+  documentIdentifier       VARCHAR(500),
+  xmlcontent               CLOB,
+  REV INTEGER NOT NULL, 
+  REVTYPE NUMBER(3),
+  CONSTRAINT PK_SMP_SMD_AUD PRIMARY KEY (
+    documentIdentifierScheme,
+    businessIdentifier,
+    businessIdentifierScheme,
+    documentIdentifier)
+);
+
+CREATE TABLE smp_user_AUD (
+  username VARCHAR(256),
+  password VARCHAR(256),
+  isadmin  NUMBER(1) DEFAULT 0,
+  REV INTEGER NOT NULL, 
+  REVTYPE NUMBER(3),
+  CONSTRAINT PK_SMP_USER_AUD PRIMARY KEY (username)
+);
+
+CREATE TABLE smp_ownership_AUD (
+  username                 VARCHAR(256),
+  businessIdentifier       VARCHAR(50),
+  businessIdentifierScheme VARCHAR(100),
+  REV INTEGER NOT NULL, 
+  REVTYPE NUMBER(3),
+  CONSTRAINT PK_OWNERSHIP_AUD PRIMARY KEY (username, businessIdentifier, businessIdentifierScheme)
+);
+
+
+CREATE TABLE SMP_REV_INFO (
+  ID NUMBER(38, 0) NOT NULL, 
+  TIMESTAMP NUMBER(38, 0), 
+  REVISION_DATE TIMESTAMP,
+  username VARCHAR2(255), 
+  CONSTRAINT PK_SMP_REV_INFO PRIMARY KEY (ID)
+);
+CREATE SEQUENCE HIBERNATE_SEQUENCE START WITH 1 INCREMENT BY 1 MINVALUE 1 MAXVALUE 9999999999999999999999999999 CACHE 20 NOORDER;
+
+commit;
+
diff --git a/smp-webapp/src/main/smp-setup/database-scripts/create-Oracle.sql b/smp-webapp/src/main/smp-setup/database-scripts/oracle10g-4.0.0.ddl
similarity index 100%
rename from smp-webapp/src/main/smp-setup/database-scripts/create-Oracle.sql
rename to smp-webapp/src/main/smp-setup/database-scripts/oracle10g-4.0.0.ddl
-- 
GitLab