diff --git a/pom.xml b/pom.xml
index 4b88ec5b930f2578fb31299a0991b6006d75f2f4..2136c38582b9da5a7181e742481bcfbadfefddeb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -53,18 +53,18 @@
         <commons-net.version>3.8.0</commons-net.version>
         <commons-validator.version>1.7</commons-validator.version>
         <cxf-xjc-runtime.version>3.3.2</cxf-xjc-runtime.version>
-        <cxf.version>3.5.5</cxf.version>
+        <cxf.version>3.5.6</cxf.version>
         <ehcache.version>2.10.9.2</ehcache.version>
-        <freemarker.version>2.3.31</freemarker.version>
+        <freemarker.version>2.3.32</freemarker.version>
         <h2.version>2.1.214</h2.version>
         <hamcrest-junit.version>2.0.0.0</hamcrest-junit.version>
         <hamcrest.version>2.2</hamcrest.version>
         <hibernate-jpa.version>1.0.2.Final</hibernate-jpa.version>
-        <hibernate.validator.version>7.0.1.Final</hibernate.validator.version>
-        <hibernate.version>5.6.9.Final</hibernate.version>
-        <httpclient.version>4.5.13</httpclient.version>
+        <hibernate.validator.version>7.0.5.Final</hibernate.validator.version>
+        <hibernate.version>5.6.15.Final</hibernate.version>
+        <httpclient.version>4.5.14</httpclient.version>
         <jackson-databind.version>2.14.1</jackson-databind.version>
-        <jackson.version>2.14.1</jackson.version>
+        <jackson.version>2.15.2</jackson.version>
         <javaee-api.version>7.0</javaee-api.version>
         <javax.annotation.version>1.3.2</javax.annotation.version>
         <javax.mail.version>1.6.2</javax.mail.version>
@@ -77,16 +77,15 @@
         <junit-platform-surefire-provider.version>1.3.2</junit-platform-surefire-provider.version>
         <junitparams.version>1.1.1</junitparams.version>
         <logback.version>1.2.11</logback.version>
-        <mysql.jdbc.version>8.0.32</mysql.jdbc.version>
+        <mysql.jdbc.version>8.0.33</mysql.jdbc.version>
         <metro.version>2.2.1-1</metro.version>
-        <!-- mockito.version>2.23.4</mockito.version -->
         <mockito.version>4.10.0</mockito.version>
         <orika.version>1.5.4</orika.version>
         <servlet-api.version>3.0.1</servlet-api.version>
         <slf4j.version>1.7.36</slf4j.version>
         <spring-modules-jakarta-commons.version>0.8</spring-modules-jakarta-commons.version>
         <spring-boot.version>2.7.12</spring-boot.version>
-        <spring-boot.tomcat.version>9.0.74</spring-boot.tomcat.version>
+        <spring-boot.tomcat.version>9.0.75</spring-boot.tomcat.version>
         <spring.security.version>5.8.3</spring.security.version>
         <spring.version>5.3.27</spring.version>
         <xmlunit.version>2.9.0</xmlunit.version>
diff --git a/smp-angular/src/app/common/dialogs/access-token-generation-dialog/access-token-generation-dialog.component.html b/smp-angular/src/app/common/dialogs/access-token-generation-dialog/access-token-generation-dialog.component.html
index e0c8125c53015663b529c0c7ca4224dc1d564f12..5a8c968898ff874c77656cf377028e3fccf4bb81 100644
--- a/smp-angular/src/app/common/dialogs/access-token-generation-dialog/access-token-generation-dialog.component.html
+++ b/smp-angular/src/app/common/dialogs/access-token-generation-dialog/access-token-generation-dialog.component.html
@@ -29,7 +29,7 @@
         </mat-form-field>
 
         <mat-card-actions>
-          <button mat-raised-button color="primary" (click)="regenerateAccessToken()"
+          <button id="regenerateAccessTokenButton" mat-raised-button color="primary" (click)="regenerateAccessToken()"
                   [disabled]="!dialogForm.valid">
             <mat-icon>check_circle</mat-icon>
             <span>Regenerate access token</span>
@@ -56,7 +56,7 @@
 <div class="required-fields">* required fields</div>
 
 <mat-dialog-actions>
-  <button mat-raised-button color="primary" (click)="closeDialog()">
+  <button id="closeDialogButton" mat-raised-button color="primary" (click)="closeDialog()">
     <mat-icon>cancel</mat-icon>
     <span>Close</span>
   </button>
diff --git a/smp-angular/src/app/common/dialogs/certificate-dialog/certificate-dialog.component.html b/smp-angular/src/app/common/dialogs/certificate-dialog/certificate-dialog.component.html
index 92fd40e5ed9ce75e81da8209a090dafd89d9cd45..be9f578d79c4f63d8979ebf7d6b3cabec18445b1 100644
--- a/smp-angular/src/app/common/dialogs/certificate-dialog/certificate-dialog.component.html
+++ b/smp-angular/src/app/common/dialogs/certificate-dialog/certificate-dialog.component.html
@@ -4,7 +4,7 @@
 </mat-dialog-content>
 
 <mat-dialog-actions>
-  <button mat-raised-button color="primary" mat-dialog-close>
+  <button id="closeDialogButton" mat-raised-button color="primary" mat-dialog-close>
     <mat-icon>close</mat-icon>
     <span>Close</span>
   </button>
diff --git a/smp-angular/src/app/common/dialogs/credential-dialog/credential-dialog.component.html b/smp-angular/src/app/common/dialogs/credential-dialog/credential-dialog.component.html
index 0bc75a15dfd240548b99eb787c987d73b0ea24f3..82f5386e1c2536248bb4d93a6106b6482a371f64 100644
--- a/smp-angular/src/app/common/dialogs/credential-dialog/credential-dialog.component.html
+++ b/smp-angular/src/app/common/dialogs/credential-dialog/credential-dialog.component.html
@@ -42,7 +42,7 @@
       <label class="custom-file-upload" style="flex-grow: 1">
         <input #fileInput type="file" id="custom-file-upload" accept=".cer,.crt,.pem,.der"
                (change)="uploadCertificate($event)">
-        <button mat-flat-button color="primary" (click)="fileInput.click()">Import</button>
+        <button id="importButton" mat-flat-button color="primary" (click)="fileInput.click()">Import</button>
       </label>
 
       <mat-form-field class="certificate-subject" style="width:100%">
@@ -81,21 +81,21 @@
     </div>
 </mat-dialog-content>
 <mat-dialog-actions>
-  <button *ngIf="isAccessTokenType && !isReadOnly" [disabled]="!credentialForm.valid " mat-raised-button color="primary"
+  <button id="generatedAccessTokenButton" *ngIf="isAccessTokenType && !isReadOnly" [disabled]="!credentialForm.valid " mat-raised-button color="primary"
           (click)="generatedAccessToken()">
     <mat-icon>key</mat-icon>
     <span>Generate new access token</span>
   </button>
 
 
-  <button *ngIf="isCertificateType && !isReadOnly" [disabled]="!credentialForm.valid " mat-raised-button color="primary"
+  <button id="storeCertificateCredentialsButton" *ngIf="isCertificateType && !isReadOnly" [disabled]="!credentialForm.valid " mat-raised-button color="primary"
           (click)="storeCertificateCredentials()">
     <mat-icon>key</mat-icon>
     <span>Save Certificate</span>
   </button>
 
 
-  <button mat-raised-button color="primary" (click)="closeDialog()">
+  <button id="closeDialogButton" mat-raised-button color="primary" (click)="closeDialog()">
     <mat-icon>cancel</mat-icon>
     <span>Close</span>
   </button>
diff --git a/smp-angular/src/app/common/dialogs/manage-members-dialog/manage-members-dialog.component.html b/smp-angular/src/app/common/dialogs/manage-members-dialog/manage-members-dialog.component.html
index 4e61a04a2f6acbe4bc52057a11bc1701aa456863..7be76f3860b50c4eb95a7376b634bdd0faa79414 100644
--- a/smp-angular/src/app/common/dialogs/manage-members-dialog/manage-members-dialog.component.html
+++ b/smp-angular/src/app/common/dialogs/manage-members-dialog/manage-members-dialog.component.html
@@ -9,7 +9,7 @@
  </domain-member-panel>
 </mat-dialog-content>
 <mat-dialog-actions>
-  <button mat-raised-button color="primary" (click)="closeDialog()">
+  <button id="closeDialogButton" mat-raised-button color="primary" (click)="closeDialog()">
     <mat-icon>cancel</mat-icon>
     <span>Close</span>
   </button>
diff --git a/smp-angular/src/app/common/dialogs/member-dialog/member-dialog.component.html b/smp-angular/src/app/common/dialogs/member-dialog/member-dialog.component.html
index b11f368cc9ffda0ce222a175362be3878b9bea99..89389b8dad06e910edfd95aae8b7b16cdd11cdce 100644
--- a/smp-angular/src/app/common/dialogs/member-dialog/member-dialog.component.html
+++ b/smp-angular/src/app/common/dialogs/member-dialog/member-dialog.component.html
@@ -33,7 +33,7 @@
   </form>
 </mat-dialog-content>
 <mat-dialog-actions>
-  <button mat-raised-button color="primary" (click)="closeDialog()">
+  <button id="closeDialogButton" mat-raised-button color="primary" (click)="closeDialog()">
     <mat-icon>cancel</mat-icon>
     <span>Close</span>
   </button>
diff --git a/smp-angular/src/app/common/dialogs/password-change-dialog/password-change-dialog.component.html b/smp-angular/src/app/common/dialogs/password-change-dialog/password-change-dialog.component.html
index 2b684909a44f0f52fe78057b28b7e0ddfb8f4e3d..a91d88f85fb2ab69ff00a78559b206a039ff1318 100644
--- a/smp-angular/src/app/common/dialogs/password-change-dialog/password-change-dialog.component.html
+++ b/smp-angular/src/app/common/dialogs/password-change-dialog/password-change-dialog.component.html
@@ -54,12 +54,13 @@
 
 <div class="required-fields">* required fields</div>
 <mat-dialog-actions>
-  <button mat-raised-button color="primary" (click)="changeCurrentUserPassword()"
+  <button id="changeCurrentUserPasswordButton" mat-raised-button color="primary"
+          (click)="changeCurrentUserPassword()"
           [disabled]="!dialogForm.valid ">
     <mat-icon>check_circle</mat-icon>
     <span>Set/change password</span>
   </button>
-  <button *ngIf="!this.forceChange" mat-raised-button color="primary" mat-dialog-close>
+  <button id="closeDialogButton" *ngIf="!this.forceChange" mat-raised-button color="primary" mat-dialog-close>
     <mat-icon>cancel</mat-icon>
     <span>Close</span>
   </button>
diff --git a/smp-angular/src/app/common/panels/membership-panel/membership-panel.component.html b/smp-angular/src/app/common/panels/membership-panel/membership-panel.component.html
index 90b26267996fd6200cbeb15779e5c6def78d8235..2a3c9f39b746234abe389a94a3208d8d8dd96793 100644
--- a/smp-angular/src/app/common/panels/membership-panel/membership-panel.component.html
+++ b/smp-angular/src/app/common/panels/membership-panel/membership-panel.component.html
@@ -1,7 +1,8 @@
 <div id="domain-member-panel" class="mat-elevation-z2">
   <mat-toolbar class="mat-elevation-z2">
     <mat-toolbar-row class="smp-toolbar-row">
-      <button id="addMemberButton" mat-raised-button (click)="onAddMemberButtonClicked()" color="primary"
+      <button id="addMemberButton" mat-raised-button
+              (click)="onAddMemberButtonClicked()" color="primary"
               [disabled]="inviteMemberDisabled"
               matTooltip="Invite new member"
       >
diff --git a/smp-angular/src/app/common/panels/user-settings-panel/user-profile-panel.component.html b/smp-angular/src/app/common/panels/user-settings-panel/user-profile-panel.component.html
index f9fae6db7244ea63a955a51dc0235d38db8e1abc..4a524c2edc1675f0c6f2f7f9bc891cfc063887b9 100644
--- a/smp-angular/src/app/common/panels/user-settings-panel/user-profile-panel.component.html
+++ b/smp-angular/src/app/common/panels/user-settings-panel/user-profile-panel.component.html
@@ -108,12 +108,12 @@
       <!-- buttons  -->
       <mat-toolbar class ="mat-elevation-z2">
         <mat-toolbar-row  class="smp-toolbar-row">
-          <button id="cancelButton_id" mat-raised-button (click)="onResetButtonClicked()" color="primary"
+          <button id="resetButton" mat-raised-button (click)="onResetButtonClicked()" color="primary"
                   [disabled]="!resetButtonEnabled">
             <mat-icon>refresh</mat-icon>
             <span>Reset</span>
           </button>
-          <button id="saveButton_id" mat-raised-button (click)="onSaveButtonClicked()" color="primary"
+          <button id="saveButton" mat-raised-button (click)="onSaveButtonClicked()" color="primary"
                   [disabled]="!submitButtonEnabled">
             <mat-icon>save</mat-icon>
             <span>Save</span>
diff --git a/smp-angular/src/app/common/search-table/search-table.component.html b/smp-angular/src/app/common/search-table/search-table.component.html
index 0bb3c6baa10d281b49cf74050afc05b27b8c1d21..7ea56530ab7f8367da8b194bdabd40cee84ee121 100644
--- a/smp-angular/src/app/common/search-table/search-table.component.html
+++ b/smp-angular/src/app/common/search-table/search-table.component.html
@@ -89,11 +89,13 @@
         <ng-container [ngTemplateOutlet]="additionalRowActionButtons"
                       [ngTemplateOutletContext]="{row:row}"></ng-container>
 
-        <button *ngIf="allowEditItems" mat-icon-button color="primary" [disabled]="row.deleted || loading"
+        <button id="editSearchRowButton" *ngIf="allowEditItems" mat-icon-button color="primary"
+                [disabled]="row.deleted || loading"
                 (click)="editSearchTableEntityRow(row)" matTooltip="Edit">
           <mat-icon>edit</mat-icon>
         </button>
-        <button *ngIf="allowDeleteItems" mat-icon-button color="primary" [disabled]="row.deleted || loading"
+        <button id="deleteRowButton" *ngIf="allowDeleteItems" mat-icon-button color="primary"
+                [disabled]="row.deleted || loading"
                 (click)="onDeleteRowActionClicked(row)" matTooltip="Delete">
           <mat-icon>delete</mat-icon>
         </button>
diff --git a/smp-angular/src/app/edit/edit-domain/domain-group-panel/group-dialog/group-dialog.component.html b/smp-angular/src/app/edit/edit-domain/domain-group-panel/group-dialog/group-dialog.component.html
index a7e701006d7dc293466d2e69d862ea336dce5f40..30bbba10d5650eaa7123cc7e09b56534c8570656 100644
--- a/smp-angular/src/app/edit/edit-domain/domain-group-panel/group-dialog/group-dialog.component.html
+++ b/smp-angular/src/app/edit/edit-domain/domain-group-panel/group-dialog/group-dialog.component.html
@@ -33,7 +33,7 @@
   </form>
 </mat-dialog-content>
 <mat-dialog-actions>
-  <button mat-raised-button color="primary" (click)="closeDialog()">
+  <button id="closeDialogButton" mat-raised-button color="primary" (click)="closeDialog()">
     <mat-icon>cancel</mat-icon>
     <span>Close</span>
   </button>
diff --git a/smp-angular/src/app/edit/edit-group/group-resource-panel/resource-dialog/resource-dialog.component.html b/smp-angular/src/app/edit/edit-group/group-resource-panel/resource-dialog/resource-dialog.component.html
index 16fcafc431c4c7c484dc8c693261706344acb1dc..87bd91024392e634411c2fec6bc948fe5ca943f9 100644
--- a/smp-angular/src/app/edit/edit-group/group-resource-panel/resource-dialog/resource-dialog.component.html
+++ b/smp-angular/src/app/edit/edit-group/group-resource-panel/resource-dialog/resource-dialog.component.html
@@ -70,7 +70,7 @@
   </form>
 </mat-dialog-content>
 <mat-dialog-actions>
-  <button mat-raised-button color="primary" (click)="closeDialog()">
+  <button id="closeDialogButton" mat-raised-button color="primary" (click)="closeDialog()">
     <mat-icon>cancel</mat-icon>
     <span>Close</span>
   </button>
diff --git a/smp-angular/src/app/edit/edit-resources/document-wizard-dialog/document-wizard-dialog.component.html b/smp-angular/src/app/edit/edit-resources/document-wizard-dialog/document-wizard-dialog.component.html
index 4b6e3041900c8bd9a65822e13f48000d6a7a850a..39dabff5f35295c5984ff72861b7c0640fe3846f 100644
--- a/smp-angular/src/app/edit/edit-resources/document-wizard-dialog/document-wizard-dialog.component.html
+++ b/smp-angular/src/app/edit/edit-resources/document-wizard-dialog/document-wizard-dialog.component.html
@@ -20,13 +20,13 @@
 </mat-dialog-content>
 
 <mat-dialog-actions>
-    <button mat-raised-button color="primary" [mat-dialog-close]="true"
+    <button id="generateDocumentButton" mat-raised-button color="primary" [mat-dialog-close]="true"
             [disabled]="!dialogForm.valid">
       <mat-icon>check_circle</mat-icon>
       <span>OK</span>
     </button>
 
-    <button mat-raised-button color="primary" mat-dialog-close>
+    <button id="closeDialogButton" mat-raised-button color="primary" mat-dialog-close>
       <mat-icon>cancel</mat-icon>
       <span>Cancel</span>
     </button>
diff --git a/smp-angular/src/app/edit/edit-resources/subresource-document-wizard-dialog/subresource-document-wizard.component.html b/smp-angular/src/app/edit/edit-resources/subresource-document-wizard-dialog/subresource-document-wizard.component.html
index 4e5e778c3b1ed4951190cbc577e8b4f1066129ec..72b879d43356e0ec5e75906f55da65e9b56f17d2 100644
--- a/smp-angular/src/app/edit/edit-resources/subresource-document-wizard-dialog/subresource-document-wizard.component.html
+++ b/smp-angular/src/app/edit/edit-resources/subresource-document-wizard-dialog/subresource-document-wizard.component.html
@@ -71,7 +71,7 @@
               <input #fileInput type="file" style="display: inline-block;cursor: pointer; display: none;"
                      id="certificate-file-upload" accept=".cer,.crt,.pem,.der"
                      (change)="uploadCertificate($event)">
-              <button mat-flat-button color="primary"
+              <button id="uploadCertificateButton" mat-flat-button color="primary"
                       (click)="fileInput.click()" >Upload certificate</button>
             </label>
             <div *ngIf="certificateValidationMessage"
@@ -112,13 +112,13 @@
 
 <div class="required-fields">* required fields</div>
 <mat-dialog-actions>
-    <button mat-raised-button color="primary" [mat-dialog-close]="true"
+    <button id="generateSubresourceButton" mat-raised-button color="primary" [mat-dialog-close]="true"
             [disabled]="!dialogForm.valid">
       <mat-icon>check_circle</mat-icon>
       <span>OK</span>
     </button>
 
-    <button mat-raised-button color="primary" mat-dialog-close>
+    <button id="closeDialogButton" mat-raised-button color="primary" mat-dialog-close>
       <mat-icon>cancel</mat-icon>
       <span>Cancel</span>
     </button>
diff --git a/smp-angular/src/app/system-settings/domain/domain.component.html b/smp-angular/src/app/system-settings/domain/domain.component.html
index c44cc96e8b60b98b701562ad6651d48d22425ec3..4a16a422da202086f2a88a9f533035a6d43e1ada 100644
--- a/smp-angular/src/app/system-settings/domain/domain.component.html
+++ b/smp-angular/src/app/system-settings/domain/domain.component.html
@@ -23,19 +23,19 @@
   <ng-template #additionalToolButtons >
     <tool-button-spacer></tool-button-spacer>
 
-    <button  id="registerButton" mat-raised-button (click)="smlRegisterSelectedDomain()"
+    <button id="registerButton" mat-raised-button (click)="smlRegisterSelectedDomain()"
             [disabled]="!enableSMLRegister()" color="primary">
       <mat-icon>link</mat-icon>
       <span>Register</span>
     </button>
-    <button  id="unregisterButton" mat-raised-button (click)="smlUnregisterSelectedDomain()"
+    <button id="unregisterButton" mat-raised-button (click)="smlUnregisterSelectedDomain()"
             [disabled]="!enableSMLUnregister()" color="primary">
       <mat-icon>link_off</mat-icon>
       <span>Unregister</span>
     </button>
     <tool-button-spacer></tool-button-spacer>
 
-    <button mat-raised-button color="primary" (click)="openEditKeystoreDialog()">
+    <button id="openEditKeystoreDialogButton" mat-raised-button color="primary" (click)="openEditKeystoreDialog()">
       <mat-icon>vpn_key</mat-icon>
       <span> Edit keystore</span>
     </button>
diff --git a/smp-angular/src/app/system-settings/domain/keystore-edit-dialog/keystore-edit-dialog.component.html b/smp-angular/src/app/system-settings/domain/keystore-edit-dialog/keystore-edit-dialog.component.html
index a966500492c285803101e18e40c80dbb2911e7ac..f6532f03e1230a6ddd41fe9435c5bf90363118bf 100644
--- a/smp-angular/src/app/system-settings/domain/keystore-edit-dialog/keystore-edit-dialog.component.html
+++ b/smp-angular/src/app/system-settings/domain/keystore-edit-dialog/keystore-edit-dialog.component.html
@@ -24,12 +24,12 @@
 
         <ng-template #certificateRowActions let-row="row" ngx-datatable-cell-template>
           <div>
-            <button mat-icon-button color="primary"
+            <button id="showCertificateDataButton" mat-icon-button color="primary"
                     matTooltip="Certificate details"
                     (click)="onShowCertificateDataRow(row)" >
               <mat-icon>details</mat-icon>
             </button>
-            <button mat-icon-button color="primary"
+            <button id="deleteCertificateButton" mat-icon-button color="primary"
                     matTooltip="Delete certificate"
                     (click)="onDeleteCertificateRowActionClicked(row)">
               <mat-icon>delete</mat-icon>
@@ -38,7 +38,7 @@
         </ng-template>
       </ngx-datatable>
       </div>
-      <button mat-raised-button color="primary" (click)="openImportKeystoreDialog()">
+      <button id="importKeystoreButton" mat-raised-button color="primary" (click)="openImportKeystoreDialog()">
         <mat-icon>vpn_key</mat-icon>
         <span>Import keystore</span>
       </button>
@@ -47,7 +47,7 @@
 </mat-dialog-content>
 
 <mat-dialog-actions>
-  <button mat-raised-button color="primary" mat-dialog-close>
+  <button id="closeDialogButton" mat-raised-button color="primary" mat-dialog-close>
         <mat-icon>close</mat-icon>
         <span>Close</span>
       </button>
diff --git a/smp-angular/src/app/system-settings/property/property-details-dialog/property-details-dialog.component.html b/smp-angular/src/app/system-settings/property/property-details-dialog/property-details-dialog.component.html
index 61ed7e754d6523bd1441524989018c2f74b9ba1f..da649f4648f2d8202ba938cb4b504b6089e3b45c 100644
--- a/smp-angular/src/app/system-settings/property/property-details-dialog/property-details-dialog.component.html
+++ b/smp-angular/src/app/system-settings/property/property-details-dialog/property-details-dialog.component.html
@@ -28,7 +28,7 @@
 </mat-dialog-content>
 
 <mat-dialog-actions>
-  <button mat-raised-button color="primary" (click)="submitForm()" [disabled]="!propertyForm.valid">
+  <button id="updatePropertyButton" mat-raised-button color="primary" (click)="submitForm()" [disabled]="!propertyForm.valid">
     <mat-icon>check_circle</mat-icon>
     <span>OK</span>
   </button>
diff --git a/smp-angular/src/app/system-settings/user/user-details-dialog/user-details-dialog.component.html b/smp-angular/src/app/system-settings/user/user-details-dialog/user-details-dialog.component.html
index 367f033368efae0306f24ae6e6b0755a6a437a25..7d410bbd20b4565abd52e9001425e95eec6ba20f 100644
--- a/smp-angular/src/app/system-settings/user/user-details-dialog/user-details-dialog.component.html
+++ b/smp-angular/src/app/system-settings/user/user-details-dialog/user-details-dialog.component.html
@@ -161,7 +161,7 @@
                      maxlength="255" disabled>
             </mat-form-field>
           </div>
-          <button mat-flat-button color="primary" style="width: 100%" [disabled]="!editMode"
+          <button id="regenerateAccessTokenButton" mat-flat-button color="primary" style="width: 100%" [disabled]="!editMode"
                   (click)="regenerateAccessToken()">
             <span>Regenerate access token</span>
           </button>
@@ -189,7 +189,7 @@
             <label class="custom-file-upload" style="flex-grow: 1">
               <input  #fileInput type="file" id="custom-file-upload" accept=".cer,.crt,.pem,.der"
                      (change)="uploadCertificate($event)">
-              <button mat-flat-button color="primary" (click)="fileInput.click()"
+              <button id="importCertificateButton" mat-flat-button color="primary" (click)="fileInput.click()"
               >Import
               </button>
             </label>
diff --git a/smp-angular/src/app/user-settings/user-access-tokens/user-access-tokens.component.html b/smp-angular/src/app/user-settings/user-access-tokens/user-access-tokens.component.html
index f01632547adee4e9e2957039c945f3f3a1741f0b..86b5f8e811a76f1d6ce988c402394266e00e6b49 100644
--- a/smp-angular/src/app/user-settings/user-access-tokens/user-access-tokens.component.html
+++ b/smp-angular/src/app/user-settings/user-access-tokens/user-access-tokens.component.html
@@ -11,7 +11,7 @@
 
 <ng-template #commonToolbar>
 
-  <button mat-raised-button color="primary" matTooltip="Create new Access token " style="margin: 2em "
+  <button id="createAccessTokenButton" mat-raised-button color="primary" matTooltip="Create new Access token " style="margin: 2em "
   (click)="createNewAccessToken()">
     <mat-icon>key</mat-icon>
     <span>Create access Token</span>
diff --git a/smp-angular/src/app/user-settings/user-certificates/user-certificates.component.html b/smp-angular/src/app/user-settings/user-certificates/user-certificates.component.html
index 88b9870a7ada28ef4fcfdd54859b884bbb8b0754..1a2b41aae4cd7f06216fdeea2a9ac70f864a56e8 100644
--- a/smp-angular/src/app/user-settings/user-certificates/user-certificates.component.html
+++ b/smp-angular/src/app/user-settings/user-certificates/user-certificates.component.html
@@ -11,7 +11,8 @@
 </div>
 
 <ng-template #commonToolbar>
-  <button mat-raised-button color="primary" matTooltip="Import new certificate" style="margin: 2em "
+  <button id="importNewCertificateButton" mat-raised-button color="primary"
+          matTooltip="Import new certificate" style="margin: 2em "
   (click)="createNew()">
     <mat-icon>article</mat-icon>
     <span>Import new certificate</span>
diff --git a/smp-angular/src/app/window/sidenav/nav-tree-menu/nav-tree-menu.component.html b/smp-angular/src/app/window/sidenav/nav-tree-menu/nav-tree-menu.component.html
index 591d49763903bf8176a869ff9dd102c578cf4269..15e2731136357c9b4223ec9049c2ec45a2c28527 100644
--- a/smp-angular/src/app/window/sidenav/nav-tree-menu/nav-tree-menu.component.html
+++ b/smp-angular/src/app/window/sidenav/nav-tree-menu/nav-tree-menu.component.html
@@ -1,5 +1,7 @@
 <ng-container *ngIf="!isLeaf; else menuItem">
-  <button mat-menu-item [matMenuTriggerFor]="itemMenu" (click)="triggerClickEvent()">
+  <button mat-menu-item [matMenuTriggerFor]="itemMenu"
+          [id]="data.code+'Button'"
+          (click)="triggerClickEvent()">
     <mat-icon *ngIf="data.icon">{{data.icon}}</mat-icon>
     <span>{{ data.name }}</span>
   </button>
@@ -10,7 +12,9 @@
   </mat-menu>
 </ng-container>
 <ng-template #menuItem>
-  <button mat-menu-item (click)="triggerClickEvent()">
+  <button mat-menu-item
+          [id]="data.code+'Button'"
+          (click)="triggerClickEvent()">
     <mat-icon *ngIf="data.icon">{{data.icon}}</mat-icon>
     <span>{{ data.name }}</span></button>
 </ng-template>
diff --git a/smp-angular/src/app/window/sidenav/nav-tree/nav-tree.component.html b/smp-angular/src/app/window/sidenav/nav-tree/nav-tree.component.html
index c3ff46de4d97be398be4bdc334cbd46bb01a48d8..1bec6450b2222daaddda4fcb8c5b08c13c2d9fc3 100644
--- a/smp-angular/src/app/window/sidenav/nav-tree/nav-tree.component.html
+++ b/smp-angular/src/app/window/sidenav/nav-tree/nav-tree.component.html
@@ -4,7 +4,7 @@
   <!-- Leaf nodes -->
   <mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle>
     <li class="mat-tree-node nav-tree-leaf" [ngClass]="{ 'navigation-selected': navigationModel.selected === node}">
-      <button mat-menu-item (click)="menuClickHandler(node)" >
+      <button [id]="node.code+'Button'" mat-menu-item (click)="menuClickHandler(node)" >
         <mat-icon *ngIf="node.icon">{{node.icon}}</mat-icon>
         <span *ngIf="fullMenu">{{node.name}}</span>
       </button>
@@ -21,13 +21,13 @@
               {{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
             </mat-icon>
           </a>
-          <button mat-menu-item (click)="menuClickHandler(node)" >
+          <button  [id]="node.code+'Button'" mat-menu-item (click)="menuClickHandler(node)" >
             <mat-icon *ngIf="node.icon">{{node.icon}}</mat-icon>
             <span *ngIf="fullMenu">{{node.name}}</span>
           </button>
         </ng-container>
         <ng-template #iconButton>
-          <button #iconItem mat-menu-item [matMenuTriggerFor]="itemMenu" >
+          <button  [id]="node.code+'Button'" #iconItem mat-menu-item [matMenuTriggerFor]="itemMenu" >
             <mat-icon *ngIf="node.icon">{{node.icon}}</mat-icon>
           </button>
           <mat-menu #itemMenu="matMenu" xPosition="before" yPosition="below">
diff --git a/smp-angular/src/app/window/toolbar/toolbar.component.html b/smp-angular/src/app/window/toolbar/toolbar.component.html
index 7c46c453d287fcc7a86673182ca19406dea2d3f9..a7f4b3f0e153613de314fa6d6e1f093377199fd6 100644
--- a/smp-angular/src/app/window/toolbar/toolbar.component.html
+++ b/smp-angular/src/app/window/toolbar/toolbar.component.html
@@ -35,7 +35,7 @@
 
       </div>
       <div *ngIf="!currentUser" style="text-align: center; vertical-align: middle;margin: 2px;">
-        <button mat-menu-item disabled="true">
+        <button  id="notLoggedInButton" mat-menu-item disabled="true">
           <mat-icon>person_outline</mat-icon>
           <span>Not logged in</span>
         </button>
diff --git a/smp-docker/images/tomcat-mysql-smp-sml/Dockerfile b/smp-docker/images/tomcat-mysql-smp-sml/Dockerfile
index d119e25f57ec9d3f13ef4f7f42b7bc310869807a..973a8bf896371a5812a5c051a501737b2f02a640 100755
--- a/smp-docker/images/tomcat-mysql-smp-sml/Dockerfile
+++ b/smp-docker/images/tomcat-mysql-smp-sml/Dockerfile
@@ -19,10 +19,10 @@ ENV SMP_HOME=/opt/smp  \
     SMP_DB_USER_PASSWORD=smp  \
     MYSQL_ROOT_PASSWORD=root \
 # sml environment variables
-    SML_VERSION=4.2.RC1 \
+    SML_VERSION=4.2 \
     SML_DISTRIBUTION_URL=https://ec.europa.eu/digital-building-blocks/artifact/repository/public/eu/europa/ec/bdmsl/bdmsl-webapp/ \
-    SML_SHA512=2330e6caf557fd6a6e8725eb339c26cb2d06f0ca768fd1766989f5dec7557e41375ef61b65cad5d87fa478f3c468272880ebe8521bb66e8e7dee9bb16d0a3d51  \
-    SML_SETUP_SHA512=f9b7a9607f34f2d547acac13e7044df04fdf616b163f4cae8788f7b1eccd837c3db947458b4f55273d263f6af2e794c18d5216484cc8132e3cfd2dc176d9e1bf  \
+    SML_SHA512=b505958c87ce046c0b25f78fbb8555a22a3a636b3906fec77fd24341f649e9e01037083b2617827269ff3554ddbe5168cb4278f1e2d81172e444f6150e92f73e  \
+    SML_SETUP_SHA512=e99ee7b8e193566964321ca126f2b20dfcc2ed904e5c2d0dc8253e49b727067e48420813bec3ed617d64724a66525c2aa17e502a130a2156d6cb81406c5d2bf9  \
     SML_DB_SCHEMA=sml  \
     SML_DB_USER=sml \
     SML_DB_USER_PASSWORD=sml  \
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/ServicesBeansConfiguration.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/ServicesBeansConfiguration.java
index 5ad8753a286b1586c106788b3ab503acd431f6f0..ff2a75fa6e16cae0a56fab05f29fa22f1f821569 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/ServicesBeansConfiguration.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/ServicesBeansConfiguration.java
@@ -9,6 +9,7 @@ import org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean;
 
 @Configuration
 @ComponentScan(basePackages = {
+        "eu.europa.ec.edelivery.smp.data.dao",
         "eu.europa.ec.edelivery.smp.conversion",
         "eu.europa.ec.edelivery.smp.security",
         "eu.europa.ec.edelivery.smp.services",
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DocumentDao.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DocumentDao.java
index 0d65b4966b111d0465fff7a14282d8507e2d7662..40b1430768f38f50130f189bbc5d39a37688840d 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DocumentDao.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DocumentDao.java
@@ -26,7 +26,6 @@ import static eu.europa.ec.edelivery.smp.data.dao.QueryNames.*;
 @Repository
 public class DocumentDao extends BaseDao<DBDocument> {
 
-
     /**
      * Method returns the document for the resource
      *
@@ -85,7 +84,6 @@ public class DocumentDao extends BaseDao<DBDocument> {
         TypedQuery<DBDocumentVersion> query = memEManager.createNamedQuery(QUERY_DOCUMENT_VERSION_LIST_FOR_RESOURCE, DBDocumentVersion.class);
         query.setParameter(PARAM_RESOURCE_ID, dbResource.getId());
         return query.getResultList();
-
     }
 
     /**
@@ -98,6 +96,5 @@ public class DocumentDao extends BaseDao<DBDocument> {
         TypedQuery<DBDocumentVersion> query = memEManager.createNamedQuery(QUERY_DOCUMENT_VERSION_LIST_FOR_SUBRESOURCE, DBDocumentVersion.class);
         query.setParameter(PARAM_SUBRESOURCE_ID, subresource.getId());
         return query.getResultList();
-
     }
 }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDao.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDao.java
index 2152bff8f0724550f49964eb9fd7d87d582001aa..613877f6fe087ede0b0e0d58186ca282c50174ce 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDao.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDao.java
@@ -109,7 +109,7 @@ public class ResourceDao extends BaseDao<DBResource> {
     }
 
     public List<DBResource> getPublicResourcesSearch(int iPage, int iPageSize, DBUser user, String schema, String identifier) {
-        LOG.debug("Get resources for user [{}]", user);
+        LOG.debug("Get resources list for user [{}], search scheme [{}] and search value [{}]", user, schema, identifier);
 
         TypedQuery<DBResource> query = memEManager.createNamedQuery(QUERY_RESOURCE_ALL_FOR_USER, DBResource.class);
         if (iPageSize > -1 && iPage > -1) {
@@ -126,7 +126,7 @@ public class ResourceDao extends BaseDao<DBResource> {
     }
 
     public Long getPublicResourcesSearchCount(DBUser user, String schema, String identifier) {
-        LOG.debug("Get resources count for user [{}]", user);
+        LOG.debug("Get resources count for user [{}], search scheme [{}] and search value [{}]", user, schema, identifier);
         TypedQuery<Long> query = memEManager.createNamedQuery(QUERY_RESOURCE_ALL_FOR_USER_COUNT, Long.class);
 
         query.setParameter(PARAM_USER_ID, user != null ? user.getId() : null);
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBResource.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBResource.java
index 4bdb5be07a9481badde6ec3586af3aff7a4d0340..bc2520e4e878786e55a0961178998eb9d51749b1 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBResource.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBResource.java
@@ -96,7 +96,7 @@ import static eu.europa.ec.edelivery.smp.data.dao.QueryNames.*;
 @NamedQuery(name = QUERY_RESOURCE_ALL_FOR_USER, query = "SELECT DISTINCT r FROM  DBResource r LEFT JOIN DBResourceMember rm ON r.id = rm.resource.id WHERE " +
         " (:resource_identifier IS NULL OR r.identifierValue like :resource_identifier) " +
         " AND (:resource_scheme IS NULL OR r.identifierScheme like :resource_scheme) " +
-        " AND :user_id IS NOT NULL AND rm.user.id = :user_id "  +
+        " AND ( :user_id IS NOT NULL AND rm.user.id = :user_id "  +
         " OR  r.visibility ='PUBLIC' " + // user must be member of the group or the group is public
         "   AND (:user_id IS NOT NULL " +
         "         AND  ((select count(gm.id) FROM  DBGroupMember gm where gm.user.id = :user_id and gm.group.id = r.group.id) > 0 " +
@@ -106,13 +106,13 @@ import static eu.europa.ec.edelivery.smp.data.dao.QueryNames.*;
         "            OR  (select count(dm.id) from DBDomainMember dm where dm.user.id = :user_id and dm.domain.id = r.group.domain.id) > 0 " +
         "            OR (select count(gm.id) from DBGroupMember gm where gm.user.id = :user_id and gm.group.domain.id = r.group.domain.id) > 0 " +
         "            OR (select count(rm.id) from DBResourceMember rm where rm.user.id = :user_id and rm.resource.group.domain.id = r.group.domain.id) > 0 " +
-        "))"+
+        ")))"+
         "order by r.identifierScheme, r.identifierValue"
 )
 @NamedQuery(name = QUERY_RESOURCE_ALL_FOR_USER_COUNT, query = "SELECT count(distinct r.id) FROM  DBResource r LEFT JOIN DBResourceMember rm ON r.id = rm.resource.id WHERE " +
         " (:resource_identifier IS NULL OR r.identifierValue like :resource_identifier) " +
         " AND (:resource_scheme IS NULL OR r.identifierScheme like :resource_scheme) " +
-        " AND :user_id IS NOT NULL AND rm.user.id = :user_id "  +
+        " AND (:user_id IS NOT NULL AND rm.user.id = :user_id "  +
         " OR  r.visibility ='PUBLIC' " + // user must be member of the group or the group is public
         "   AND (:user_id IS NOT NULL " +
         "         AND  ((select count(gm.id) FROM  DBGroupMember gm where gm.user.id = :user_id and gm.group.id = r.group.id) > 0 " +
@@ -122,7 +122,7 @@ import static eu.europa.ec.edelivery.smp.data.dao.QueryNames.*;
         "            OR  (select count(dm.id) from DBDomainMember dm where dm.user.id = :user_id and dm.domain.id = r.group.domain.id) > 0 " +
         "            OR (select count(gm.id) from DBGroupMember gm where gm.user.id = :user_id and gm.group.domain.id = r.group.domain.id) > 0 " +
         "            OR (select count(rm.id) from DBResourceMember rm where rm.user.id = :user_id and rm.resource.group.domain.id = r.group.domain.id) > 0 " +
-        "))"
+        ")))"
 )
 public class DBResource extends BaseEntity {
 
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/CredentialService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/CredentialService.java
index 9edf83db69b32d458bb2d36e53709011ad3f7d8a..1b3280b7091bc922b73a73bdcd98fcca356f6566 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/CredentialService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/CredentialService.java
@@ -15,6 +15,7 @@ import eu.europa.ec.edelivery.smp.data.model.user.DBUser;
 import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority;
 import eu.europa.ec.edelivery.smp.data.ui.enums.AlertSuspensionMomentEnum;
 import eu.europa.ec.edelivery.smp.exceptions.ErrorCode;
+import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
 import eu.europa.ec.edelivery.smp.logging.SMPMessageCode;
@@ -28,8 +29,8 @@ import org.springframework.security.core.Authentication;
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.crypto.bcrypt.BCrypt;
 import org.springframework.stereotype.Service;
-
 import org.springframework.transaction.annotation.Transactional;
+
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateRevokedException;
 import java.security.cert.X509Certificate;
@@ -70,12 +71,12 @@ public class CredentialService {
         this.alertService = alertService;
     }
 
-    @Transactional(noRollbackForClassName = {"java.lang.RuntimeException"})
+    @Transactional(noRollbackFor = {AuthenticationException.class, SMPRuntimeException.class, RuntimeException.class})
     public Authentication authenticateByUsernamePassword(String username, String userCredentialToken)
             throws AuthenticationException {
 
         long startTime = Calendar.getInstance().getTimeInMillis();
-
+        LOG.debug("authenticateByUsernamePassword: start [{}]", username);
         DBCredential credential;
         try {
             Optional<DBCredential> dbCredential = mCredentialDao.findUsernamePasswordCredentialForUsernameAndUI(username);
@@ -92,38 +93,38 @@ public class CredentialService {
             throw BAD_CREDENTIALS_EXCEPTION;
 
         }
-
         validateIfCredentialIsSuspended(credential, startTime);
         DBUser user = credential.getUser();
 
-
         SMPAuthority authority = SMPAuthority.getAuthorityByApplicationRole(user.getApplicationRole());
         // the webservice authentication does not support session set the session secret is null!
+        LOG.debug("authenticateByUsernamePassword: create details [{}]", username);
         SMPUserDetails userDetails = new SMPUserDetails(user,
-                SecurityUtils.generatePrivateSymmetricKey(SMPEnvironmentProperties.getInstance().isSMPStartupInDevMode()),
+                SecurityUtils.generatePrivateSymmetricKey(true),
                 Collections.singletonList(authority));
-
         UILoginAuthenticationToken smpAuthenticationToken = new UILoginAuthenticationToken(username, userCredentialToken,
                 userDetails);
         try {
+            LOG.debug("authenticateByUsernamePassword:validate security token [{}]", username);
             if (!BCrypt.checkpw(userCredentialToken, credential.getValue())) {
                 LOG.securityWarn(SMPMessageCode.SEC_INVALID_USER_CREDENTIALS, username, credential.getName(), credential.getCredentialType(), credential.getCredentialTarget());
                 loginAttemptFailedAndThrowError(credential, true, startTime);
             }
+            LOG.debug("authenticateByUsernamePassword: reset failed attempts for user token [{}]", username);
             credential.setSequentialLoginFailureCount(0);
             credential.setLastFailedLoginAttempt(null);
-            mCredentialDao.update(credential);
         } catch (IllegalArgumentException ex) {
             // password is not hashed
             LOG.securityWarn(SMPMessageCode.SEC_INVALID_USER_CREDENTIALS, ex, username);
             loginAttemptFailedAndThrowError(credential, true, startTime);
         }
+        LOG.info("authenticateByUsernamePassword: done updating [{}]", username);
         LOG.securityInfo(SMPMessageCode.SEC_USER_AUTHENTICATED, username, user.getApplicationRole());
         return smpAuthenticationToken;
     }
 
 
-    @Transactional(noRollbackForClassName = {"org.springframework.security.core.AuthenticationException","org.springframework.security.authentication.BadCredentialsException"})
+    @Transactional(noRollbackFor = {AuthenticationException.class, BadCredentialsException.class, SMPRuntimeException.class})
     public Authentication authenticateByAuthenticationToken(String authenticationTokenId, String authenticationTokenValue)
             throws AuthenticationException {
 
@@ -200,7 +201,7 @@ public class CredentialService {
         return false;
     }
 
-    @Transactional(noRollbackForClassName = {"org.springframework.security.core.AuthenticationException","org.springframework.security.authentication.BadCredentialsException"})
+    @Transactional(noRollbackFor = {AuthenticationException.class, BadCredentialsException.class, SMPRuntimeException.class})
     public Authentication authenticateByCertificateToken(PreAuthenticatedCertificatePrincipal principal) {
         LOG.info("authenticateByCertificateToken:" + principal.getName());
 
@@ -216,7 +217,7 @@ public class CredentialService {
             try {
                 truststoreService.validateCertificateWithTruststore(x509Certificate);
             } catch (CertificateException e) {
-                String message = "Certificate is not trusted!";
+                String message = "Certificate is not trusted! Error: " + ExceptionUtils.getRootCauseMessage(e);
                 LOG.securityWarn(SMPMessageCode.SEC_USER_CERT_INVALID, certificateIdentifier, message
                         + " The cert chain is not in truststore or either subject regexp or allowed cert policies does not match");
                 throw new BadCredentialsException(message);
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/AbstractResourceHandler.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/AbstractResourceHandler.java
index b91c92acb69a34630fa5c4dfb18946d406354959..551820bc32b1d20635d551009101875e6366c640 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/AbstractResourceHandler.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/AbstractResourceHandler.java
@@ -32,7 +32,7 @@ public class AbstractResourceHandler {
     final List<ResourceDefinitionSpi> resourceDefinitionSpiList;
     final ResourceStorage resourceStorage;
 
-    public AbstractResourceHandler(List<ResourceDefinitionSpi> resourceDefinitionSpiList, ResourceStorage resourceStorage) {
+    protected AbstractResourceHandler(List<ResourceDefinitionSpi> resourceDefinitionSpiList, ResourceStorage resourceStorage) {
         this.resourceDefinitionSpiList = resourceDefinitionSpiList;
         this.resourceStorage = resourceStorage;
     }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/ResourceHandlerService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/ResourceHandlerService.java
index f1b0b2a2ffc10fbf77f6a3cfb8d42cd7f6367e5b..37147ec79a9fce9706173e4e102a56865cb8e57d 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/ResourceHandlerService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/ResourceHandlerService.java
@@ -28,8 +28,8 @@ import eu.europa.ec.smp.spi.resource.ResourceHandlerSpi;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.springframework.stereotype.Service;
-
 import org.springframework.transaction.annotation.Transactional;
+
 import java.io.ByteArrayOutputStream;
 import java.util.List;
 
@@ -47,12 +47,14 @@ public class ResourceHandlerService extends AbstractResourceHandler {
     protected static final SMPLogger LOG = SMPLoggerFactory.getLogger(ResourceHandlerService.class);
 
     final ResourceMemberDao resourceMemberDao;
-
     final GroupDao groupDao;
     final SMLIntegrationService integrationService;
 
-    public ResourceHandlerService(List<ResourceDefinitionSpi> resourceDefinitionSpiList, ResourceStorage resourceStorage,
-                                  ResourceMemberDao resourceMemberDao, GroupDao groupDao,SMLIntegrationService integrationService) {
+    public ResourceHandlerService(List<ResourceDefinitionSpi> resourceDefinitionSpiList,
+                                  ResourceMemberDao resourceMemberDao,
+                                  GroupDao groupDao,
+                                  ResourceStorage resourceStorage,
+                                  SMLIntegrationService integrationService) {
         super(resourceDefinitionSpiList, resourceStorage);
         this.resourceMemberDao = resourceMemberDao;
         this.groupDao = groupDao;
@@ -61,7 +63,6 @@ public class ResourceHandlerService extends AbstractResourceHandler {
 
     public void readResource(ResourceRequest resourceRequest,
                              ResourceResponse resourceResponse) {
-
         LOG.debug("Handle the READ action for resource request [{}]", resourceRequest);
         ResolvedData resolvedData = resourceRequest.getResolvedData();
         ResourceHandlerSpi handlerSpi = getResourceHandler(resolvedData.getResourceDef());
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/ResourceStorage.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/ResourceStorage.java
index 306eb5f674cf6fb4c4f108072ebbd93b630f857c..5e70ab99f596e7c2df667c3a4d2c7f32b69a7880 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/ResourceStorage.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/ResourceStorage.java
@@ -11,8 +11,8 @@ import eu.europa.ec.edelivery.smp.data.model.doc.DBSubresource;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
 import org.springframework.stereotype.Service;
-
 import org.springframework.transaction.annotation.Transactional;
+
 import java.util.Optional;
 
 /**
@@ -28,19 +28,22 @@ public class ResourceStorage {
     final ResourceDao resourceDao;
     final SubresourceDao subresourceDao;
 
-    public ResourceStorage(DocumentDao documentDao, ResourceDao resourceDao,SubresourceDao subresourceDao) {
+    public ResourceStorage(DocumentDao documentDao, ResourceDao resourceDao, SubresourceDao subresourceDao) {
         this.documentDao = documentDao;
         this.resourceDao = resourceDao;
         this.subresourceDao = subresourceDao;
     }
 
-    byte[] getDocumentContentForResource(DBResource dbResource) {
-        Optional<DBDocumentVersion> documentVersion = documentDao.getCurrentDocumentVersionForResource(dbResource);
+    public byte[] getDocumentContentForResource(DBResource dbResource) {
+        LOG.debug("getDocumentContentForResource: [{}]", dbResource);
+
+        Optional<DBDocumentVersion> documentVersion = this.documentDao.getCurrentDocumentVersionForResource(dbResource);
 
         return documentVersion.isPresent() ? documentVersion.get().getContent() : null;
     }
 
-    byte[] getDocumentContentForSubresource(DBSubresource subresource) {
+    public byte[] getDocumentContentForSubresource(DBSubresource subresource) {
+        LOG.debug("getDocumentContentForSubresource: [{}]", subresource);
         Optional<DBDocumentVersion> documentVersion = documentDao.getCurrentDocumentVersionForSubresource(subresource);
 
         return documentVersion.isPresent() ? documentVersion.get().getContent() : null;
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java
index 9c64132b37f1044e92be72597b90f55ed8ac2f9c..3e9b3314431e32ea63fd2334925a418f4e6acaed 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java
@@ -208,6 +208,7 @@ public class UITruststoreService extends BasicKeystoreService {
     public void validateCertificate(X509Certificate cert, CertificateRO cro) {
         validateCertificate(cert, cro, true);
     }
+
     public void validateCertificate(X509Certificate cert, CertificateRO cro, boolean validateDuplicate) {
         // first expect the worst
         cro.setInvalid(true);
@@ -253,6 +254,15 @@ public class UITruststoreService extends BasicKeystoreService {
             return;
         }
 
+        try {
+            if (truststore.size() == 0) {
+                LOG.warn("Truststore is empty! Skip trust validation against the truststore!");
+                return;
+            }
+        } catch (KeyStoreException e) {
+            throw new CertificateException("Error occurred when reading the truststore!", e);
+        }
+
         Pattern subjectRegExp = configurationService.getCertificateSubjectRegularExpression();
         List<String> allowedCertificatePolicies = configurationService.getAllowedCertificatePolicies();
         CertificateValidator certificateValidator = new CertificateValidator(
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDaoSearchTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDaoSearchTest.java
index a9b6c47f41cd02f04706e8b15142b350ea50275b..720808e898a230b4304d0eb0c34717f3a19124ab 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDaoSearchTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/ResourceDaoSearchTest.java
@@ -3,6 +3,8 @@ package eu.europa.ec.edelivery.smp.data.dao;
 
 import eu.europa.ec.edelivery.smp.data.model.doc.DBResource;
 import eu.europa.ec.edelivery.smp.data.model.doc.DBResourceFilter;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.MatcherAssert;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -46,12 +48,24 @@ public class ResourceDaoSearchTest extends AbstractBaseDao {
         assertResources(result, "1-1-1::pubPubPub");
 
         // user1 (admin) and user2 (viewer) are members of all resources
-        result = testInstance.getPublicResourcesSearch(-1,-1,testUtilsDao.getUser1(), null, null);
+        result = testInstance.getPublicResourcesSearch(-1,-1,testUtilsDao.getUser2(), null, null);
         Assert.assertEquals(8, result.size());
 
+        result = testInstance.getPublicResourcesSearch(-1,-1,testUtilsDao.getUser1(), null, "pubPub");
+        Assert.assertEquals(2, result.size());
+        result.forEach(resource -> MatcherAssert.assertThat(resource.getIdentifierValue(), CoreMatchers.containsString("pubPub")));
+
+        result = testInstance.getPublicResourcesSearch(-1,-1,testUtilsDao.getUser1(), "1-1",null);
+        Assert.assertEquals(1, result.size());
+        result.forEach(resource -> MatcherAssert.assertThat(resource.getIdentifierScheme(), CoreMatchers.containsString("1-1")));
+
+        result = testInstance.getPublicResourcesSearch(-1,-1,testUtilsDao.getUser1(), "1-1","priv");
+        Assert.assertEquals(0, result.size());
+
         result = testInstance.getPublicResourcesSearch(-1,-1,testUtilsDao.getUser2(), null, null);
         Assert.assertEquals(8, result.size());
 
+
         // user3 is direct member of private domain - can see only public resource on public groups
         result = testInstance.getPublicResourcesSearch(-1,-1,testUtilsDao.getUser3(), null, null);
         assertResources(result, "1-1-1::pubPubPub", "5-5-5::privPubPub");
@@ -84,6 +98,15 @@ public class ResourceDaoSearchTest extends AbstractBaseDao {
         result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser1(), null, null);
         Assert.assertEquals(8, result.intValue());
 
+        result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser1(), null, "pubPub");
+        Assert.assertEquals(2, result.intValue());
+
+        result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser1(), "1-1",null);
+        Assert.assertEquals(1, result.intValue());
+
+        result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser1(), "1-1","priv");
+        Assert.assertEquals(0, result.intValue());
+
         result = testInstance.getPublicResourcesSearchCount(testUtilsDao.getUser2(), null, null);
         Assert.assertEquals(8, result.intValue());
 
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SMPWebAppConfig.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SMPWebAppConfig.java
index 4a915929bf3f6170e8e53bb279178ace1d9775bb..d4f7519f31af9b19bc95ebeda181bfb5c902f44b 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SMPWebAppConfig.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SMPWebAppConfig.java
@@ -23,6 +23,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.FilterType;
 import org.springframework.context.annotation.Import;
 import org.springframework.http.converter.HttpMessageConverter;
 import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
@@ -38,9 +39,9 @@ import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE;
 
 /**
  * This is the entry point of the DomiSMP application (beans)configuration/setup.
- *
+ * <p>
  * The SMPWebAppConfig is initiated from the web.xml.
- *
+ * <p>
  * The following configurations: ServicesBeansConfiguration, SMPDatabaseConfig, UISecurityConfigurerAdapter, WSSecurityConfigurerAdapter
  * are configured from the SMPWebAppConfig
  *
@@ -64,8 +65,8 @@ import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE;
  * <tr><td>utils</td><td>smp-server-library</td><td>SMPWebAppConfig</td></tr>
  * <tr><td>ui</td><td>smp-webapp</td><td>SMPWebAppConfig</td></tr>
  * </table>
- *
- *
+ * <p>
+ * <p>
  *  @author gutowpa
  *  @since 3.0.0
  */
@@ -82,7 +83,9 @@ import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE;
         "eu.europa.ec.edelivery.smp.utils",
         "eu.europa.ec.edelivery.smp.cron",
         // spi properties
-        "eu.europa.ec.smp.spi",})
+        "eu.europa.ec.smp.spi"},
+        excludeFilters = {
+                @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = SMPWebAppConfig.class)})
 public class SMPWebAppConfig implements WebMvcConfigurer {
     private static final Logger LOG = LoggerFactory.getLogger(SMPWebAppConfig.class);
 
diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/monitor/MonitorResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/monitor/MonitorResource.java
index 8f8a3e45d50e5d612516dde11f5d50baf6a34af1..07046e1b4a20aa3dd224641b6392d02b8b4c1ac7 100644
--- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/monitor/MonitorResource.java
+++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/monitor/MonitorResource.java
@@ -1,7 +1,6 @@
 package eu.europa.ec.edelivery.smp.monitor;
 
 
-import eu.europa.ec.edelivery.smp.data.dao.DocumentDao;
 import eu.europa.ec.edelivery.smp.data.dao.DomainDao;
 import eu.europa.ec.edelivery.smp.data.model.DBDomain;
 import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority;
@@ -35,13 +34,9 @@ public class MonitorResource {
     private static final String TEST_NAME = "urn:test:document:is-alive";
     private static final String TEST_EXTENSION_XML = "<Extension xmlns=\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\"><ex:dummynode xmlns:ex=\"http://test.eu\">Sample not mandatory extension</ex:dummynode></Extension>";
     private static final String TEST_DB_SUCCESSFUL_ROLLBACK = "TEST_DB_SUCCESSFUL_ROLLBACK MESSAGE";
-
-
-    private final DocumentDao documentDao;
     private final DomainDao domainDao;
 
-    public MonitorResource(DocumentDao documentDao, DomainDao domainDao) {
-        this.documentDao = documentDao;
+    public MonitorResource(DomainDao domainDao) {
         this.domainDao = domainDao;
     }