From f1eb34f140b22ed0d2b872b6d2e414c860f3441e Mon Sep 17 00:00:00 2001
From: RIHTARSIC Joze <joze.rihtarsic@ext.ec.europa.eu>
Date: Mon, 17 Jul 2023 10:56:21 +0200
Subject: [PATCH] Add example resource extension SPI unit tests

---
 pom.xml                                       |   2 +-
 .../def/DomiSMPJsonResourceExample.java       |   8 +-
 .../def/DomiSMPPropertyResourceExample.java   |   6 +-
 .../handler/DomiSMPJSONHandlerExample.java    |  30 +++--
 .../DomiSMPPropertyHandlerExample.java        |   8 +-
 .../DomiSMPResourceExampleExtensionTest.java  |  59 +++++++++
 .../def/DomiSMPJsonResourceExampleTest.java   |  75 +++++++++++
 .../DomiSMPPropertyResourceExampleTest.java   |  76 ++++++++++++
 .../examples/handler/AbstractHandlerTest.java | 116 ++++++++++++++++++
 .../DomiSMPJSONHandlerExampleTest.java        |  67 ++++++++++
 .../DomiSMPPropertyHandlerExampleTest.java    |  68 ++++++++++
 .../src/test/resources/examples/json_ok.json  |   6 +
 .../examples/properties_ok.properties         |   5 +
 .../spi/handler/OasisCppa3CppHandlerTest.java |  18 +--
 .../smp/services/CredentialService.java       |   5 -
 .../edelivery/smp/data/dao/TestUtilsDao.java  |   7 +-
 .../smp/services/CredentialServiceTest.java   |  39 ++++++
 .../edelivery/smp/testutil/TestConstants.java |  20 +--
 .../edelivery/smp/testutil/TestDBUtils.java   |  44 +++++--
 .../edelivery/smp/testutil/TestROUtils.java   |  55 +--------
 20 files changed, 586 insertions(+), 128 deletions(-)
 create mode 100644 smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/DomiSMPResourceExampleExtensionTest.java
 create mode 100644 smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/def/DomiSMPJsonResourceExampleTest.java
 create mode 100644 smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/def/DomiSMPPropertyResourceExampleTest.java
 create mode 100644 smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/handler/AbstractHandlerTest.java
 create mode 100644 smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/handler/DomiSMPJSONHandlerExampleTest.java
 create mode 100644 smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/handler/DomiSMPPropertyHandlerExampleTest.java
 create mode 100644 smp-examples/resource-spi-example/src/test/resources/examples/json_ok.json
 create mode 100644 smp-examples/resource-spi-example/src/test/resources/examples/properties_ok.properties

diff --git a/pom.xml b/pom.xml
index e6c061539..b21407bab 100644
--- a/pom.xml
+++ b/pom.xml
@@ -36,7 +36,7 @@
         <maven.compiler.target>1.8</maven.compiler.target>
         <maven.compiler.source>1.8</maven.compiler.source>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <edelivery.ssl-auth.version>1.13</edelivery.ssl-auth.version>
+        <edelivery.ssl-auth.version>1.14-SNAPSHOT</edelivery.ssl-auth.version>
         <edelivery.dynamic-discovery-client.version>2.0</edelivery.dynamic-discovery-client.version>
 
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
diff --git a/smp-examples/resource-spi-example/src/main/java/eu/europa/ec/smp/spi/examples/def/DomiSMPJsonResourceExample.java b/smp-examples/resource-spi-example/src/main/java/eu/europa/ec/smp/spi/examples/def/DomiSMPJsonResourceExample.java
index 440e23089..8ac1dbfa6 100644
--- a/smp-examples/resource-spi-example/src/main/java/eu/europa/ec/smp/spi/examples/def/DomiSMPJsonResourceExample.java
+++ b/smp-examples/resource-spi-example/src/main/java/eu/europa/ec/smp/spi/examples/def/DomiSMPJsonResourceExample.java
@@ -64,10 +64,10 @@ public class DomiSMPJsonResourceExample implements ResourceDefinitionSpi {
     @Override
     public String toString() {
         return "DomiSMPJsonResourceExample {" +
-                "identifier=" + identifier() +
-                "defaultUrlSegment=" + defaultUrlSegment() +
-                "name=" + name() +
-                "mimeType=" + mimeType() +
+                " identifier=" + identifier() +
+                ", defaultUrlSegment=" + defaultUrlSegment() +
+                ", name=" + name() +
+                ", mimeType=" + mimeType() +
                 '}';
     }
 }
diff --git a/smp-examples/resource-spi-example/src/main/java/eu/europa/ec/smp/spi/examples/def/DomiSMPPropertyResourceExample.java b/smp-examples/resource-spi-example/src/main/java/eu/europa/ec/smp/spi/examples/def/DomiSMPPropertyResourceExample.java
index d98bea295..14fbc84be 100644
--- a/smp-examples/resource-spi-example/src/main/java/eu/europa/ec/smp/spi/examples/def/DomiSMPPropertyResourceExample.java
+++ b/smp-examples/resource-spi-example/src/main/java/eu/europa/ec/smp/spi/examples/def/DomiSMPPropertyResourceExample.java
@@ -65,9 +65,9 @@ public class DomiSMPPropertyResourceExample implements ResourceDefinitionSpi {
     public String toString() {
         return "DomiSMPPropertyResourceExample {" +
                 "identifier=" + identifier() +
-                "defaultUrlSegment=" + defaultUrlSegment() +
-                "name=" + name() +
-                "mimeType=" + mimeType() +
+                ", defaultUrlSegment=" + defaultUrlSegment() +
+                ", name=" + name() +
+                ", mimeType=" + mimeType() +
                 '}';
     }
 }
diff --git a/smp-examples/resource-spi-example/src/main/java/eu/europa/ec/smp/spi/examples/handler/DomiSMPJSONHandlerExample.java b/smp-examples/resource-spi-example/src/main/java/eu/europa/ec/smp/spi/examples/handler/DomiSMPJSONHandlerExample.java
index bcf149967..cac90952f 100644
--- a/smp-examples/resource-spi-example/src/main/java/eu/europa/ec/smp/spi/examples/handler/DomiSMPJSONHandlerExample.java
+++ b/smp-examples/resource-spi-example/src/main/java/eu/europa/ec/smp/spi/examples/handler/DomiSMPJSONHandlerExample.java
@@ -20,6 +20,7 @@ import org.springframework.stereotype.Component;
 import org.springframework.util.StreamUtils;
 
 import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.math.BigInteger;
@@ -137,18 +138,21 @@ public class DomiSMPJSONHandlerExample extends AbstractHandler {
     public void storeResource(RequestData resourceData, ResponseData responseData) throws ResourceException {
         InputStream inputStream = resourceData.getResourceInputStream();
         // reading resource multiple time make sure it can be rest
-        if (!inputStream.markSupported()) {
-            inputStream = new BufferedInputStream(inputStream);
+        ByteArrayInputStream bios;
+        try {
+            bios = new ByteArrayInputStream(StreamUtils.copyToByteArray(inputStream));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
         }
         inputStream.mark(Integer.MAX_VALUE - 2);
-        ExampleEntityRo properties = validateAndParse(resourceData);
+
+
+        validateAndParse(bios, getResourceIdentifier(resourceData));
         try {
-            inputStream.reset();
-            StreamUtils.copy(inputStream, responseData.getOutputStream());
-            // need to save serviceGroup because of the update on the resource identifier values
-            //reader.serializeNative(cppDocument, responseData.getOutputStream(), true);
+            bios.reset();
+            StreamUtils.copy(bios, responseData.getOutputStream());
         } catch (IOException e) {
-            throw new ResourceException(PARSE_ERROR, "Error occurred while copying the ServiceGroup", e);
+            throw new ResourceException(PARSE_ERROR, "Error occurred while storing the resource", e);
         }
     }
 
@@ -165,13 +169,19 @@ public class DomiSMPJSONHandlerExample extends AbstractHandler {
     public ExampleEntityRo validateAndParse(RequestData resourceData) throws ResourceException {
         // get service group identifier
         ResourceIdentifier identifier = getResourceIdentifier(resourceData);
+       return  validateAndParse(resourceData.getResourceInputStream(), identifier);
+    }
+
+    public ExampleEntityRo validateAndParse(InputStream inputStream,  ResourceIdentifier identifier ) throws ResourceException {
+        // get service group identifier
+
         Properties properties = new Properties();
         // validate by schema
         ObjectMapper mapper = new ObjectMapper();
         mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
         ExampleEntityRo entityRo;
         try {
-            entityRo = mapper.readValue(resourceData.getResourceInputStream(), ExampleEntityRo.class);
+            entityRo = mapper.readValue(inputStream, ExampleEntityRo.class);
         } catch (IOException ex) {
             throw new ResourceException(INVALID_RESOURCE, "Error occurred while reading example property document: [" + identifier + "] with error: " + ExceptionUtils.getRootCauseMessage(ex), ex);
         }
@@ -202,8 +212,6 @@ public class DomiSMPJSONHandlerExample extends AbstractHandler {
         } catch (MalformedURLException e) {
             throw new ResourceException(INVALID_RESOURCE, "Bad property value: [url]!. Value ["+entityRo.getUrl()+"]  is not URL" );
         }
-
-
         return entityRo;
     }
 
diff --git a/smp-examples/resource-spi-example/src/main/java/eu/europa/ec/smp/spi/examples/handler/DomiSMPPropertyHandlerExample.java b/smp-examples/resource-spi-example/src/main/java/eu/europa/ec/smp/spi/examples/handler/DomiSMPPropertyHandlerExample.java
index 284289707..c95d1059d 100644
--- a/smp-examples/resource-spi-example/src/main/java/eu/europa/ec/smp/spi/examples/handler/DomiSMPPropertyHandlerExample.java
+++ b/smp-examples/resource-spi-example/src/main/java/eu/europa/ec/smp/spi/examples/handler/DomiSMPPropertyHandlerExample.java
@@ -65,10 +65,8 @@ public class DomiSMPPropertyHandlerExample extends AbstractHandler {
     }
 
     public void generateResource(RequestData resourceData, ResponseData responseData, List<String> fields) throws ResourceException {
-
         ResourceIdentifier identifier = getResourceIdentifier(resourceData);
 
-
         try {
             String identifierString = smpIdentifierApi.formatResourceIdentifier(identifier);
             Properties properties = new Properties();
@@ -142,14 +140,12 @@ public class DomiSMPPropertyHandlerExample extends AbstractHandler {
             inputStream = new BufferedInputStream(inputStream);
         }
         inputStream.mark(Integer.MAX_VALUE - 2);
-        Properties properties = validateAndParse(resourceData);
+        validateAndParse(resourceData);
         try {
             inputStream.reset();
             StreamUtils.copy(inputStream, responseData.getOutputStream());
-            // need to save serviceGroup because of the update on the resource identifier values
-            //reader.serializeNative(cppDocument, responseData.getOutputStream(), true);
         } catch (IOException e) {
-            throw new ResourceException(PARSE_ERROR, "Error occurred while copying the ServiceGroup", e);
+            throw new ResourceException(PARSE_ERROR, "Error occurred while storing the resource", e);
         }
     }
 
diff --git a/smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/DomiSMPResourceExampleExtensionTest.java b/smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/DomiSMPResourceExampleExtensionTest.java
new file mode 100644
index 000000000..1aa002e61
--- /dev/null
+++ b/smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/DomiSMPResourceExampleExtensionTest.java
@@ -0,0 +1,59 @@
+package eu.europa.ec.smp.spi.examples;
+
+import eu.europa.ec.smp.spi.PayloadValidatorSpi;
+import eu.europa.ec.smp.spi.examples.def.DomiSMPJsonResourceExample;
+import eu.europa.ec.smp.spi.examples.def.DomiSMPPropertyResourceExample;
+import eu.europa.ec.smp.spi.resource.ResourceDefinitionSpi;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+
+class DomiSMPResourceExampleExtensionTest {
+    DomiSMPPropertyResourceExample mockDomiSMPPropertyResourceExample = Mockito.mock(DomiSMPPropertyResourceExample.class);
+    DomiSMPJsonResourceExample mocDomiSMPJsonResourceExample = Mockito.mock(DomiSMPJsonResourceExample.class);
+
+    DomiSMPResourceExampleExtension testInstance = new DomiSMPResourceExampleExtension(mockDomiSMPPropertyResourceExample, mocDomiSMPJsonResourceExample );
+
+    @Test
+    void testIdentifier() {
+        String result = testInstance.identifier();
+
+        assertEquals("domismp-resource-example-extension", result);
+    }
+
+    @Test
+    void testName() {
+        String result = testInstance.name();
+        assertEquals("Resource example extension", result);
+    }
+
+    @Test
+    void testDescription() {
+        String result = testInstance.description();
+        assertEquals("The extension implements json and property examples", result);
+    }
+
+    @Test
+    void testVersion() {
+        String  result = testInstance.version();
+        assertEquals("1.0", result);
+    }
+
+    @Test
+    void testResourceTypes() {
+        List<ResourceDefinitionSpi> result = testInstance.resourceTypes();
+        assertEquals(2, result.size());
+        assertEquals(mocDomiSMPJsonResourceExample, result.get(0));
+        assertEquals(mockDomiSMPPropertyResourceExample, result.get(1));
+    }
+
+    @Test
+    void testPayloadValidators() {
+        List<PayloadValidatorSpi> result = testInstance.payloadValidators();
+        assertEquals(0, result.size());
+    }
+}
diff --git a/smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/def/DomiSMPJsonResourceExampleTest.java b/smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/def/DomiSMPJsonResourceExampleTest.java
new file mode 100644
index 000000000..9cfed6fa7
--- /dev/null
+++ b/smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/def/DomiSMPJsonResourceExampleTest.java
@@ -0,0 +1,75 @@
+package eu.europa.ec.smp.spi.examples.def;
+
+import eu.europa.ec.smp.spi.examples.handler.DomiSMPJSONHandlerExample;
+import eu.europa.ec.smp.spi.resource.ResourceHandlerSpi;
+import eu.europa.ec.smp.spi.resource.SubresourceDefinitionSpi;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.MatcherAssert;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class DomiSMPJsonResourceExampleTest {
+
+    DomiSMPJSONHandlerExample mockDomiSMPJSONHandlerExample = Mockito.mock(DomiSMPJSONHandlerExample.class);
+    DomiSMPJsonResourceExample testInstance = new DomiSMPJsonResourceExample(mockDomiSMPJSONHandlerExample);
+
+    @Test
+    void identifier() {
+        String result = testInstance.identifier();
+
+        assertEquals("domismp-resource-example-json", result);
+    }
+
+    @Test
+    void defaultUrlSegment() {
+        String result = testInstance.defaultUrlSegment();
+
+        assertEquals("json", result);
+    }
+
+    @Test
+    void name() {
+        String result = testInstance.name();
+
+        assertEquals("DomiSMP JSON example", result);
+    }
+
+    @Test
+    void description() {
+        String result = testInstance.description();
+
+        assertEquals("DomiSMP JSON example", result);
+    }
+
+    @Test
+    void mimeType() {
+        String result = testInstance.mimeType();
+
+        assertEquals("application/json", result);
+    }
+
+    @Test
+    void getSubresourceSpiList() {
+        List<SubresourceDefinitionSpi> result = testInstance.getSubresourceSpiList();
+
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    void getResourceHandler() {
+        ResourceHandlerSpi result = testInstance.getResourceHandler();
+
+        assertEquals(mockDomiSMPJSONHandlerExample, result);
+    }
+
+    @Test
+    void testToString() {
+        String result = testInstance.toString();
+
+        MatcherAssert.assertThat(result, CoreMatchers.containsString("domismp-resource-example-json"));
+    }
+}
diff --git a/smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/def/DomiSMPPropertyResourceExampleTest.java b/smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/def/DomiSMPPropertyResourceExampleTest.java
new file mode 100644
index 000000000..edd6a0e28
--- /dev/null
+++ b/smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/def/DomiSMPPropertyResourceExampleTest.java
@@ -0,0 +1,76 @@
+package eu.europa.ec.smp.spi.examples.def;
+
+import eu.europa.ec.smp.spi.examples.handler.DomiSMPPropertyHandlerExample;
+import eu.europa.ec.smp.spi.resource.ResourceHandlerSpi;
+import eu.europa.ec.smp.spi.resource.SubresourceDefinitionSpi;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.MatcherAssert;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class DomiSMPPropertyResourceExampleTest {
+
+    DomiSMPPropertyHandlerExample mockDomiSMPPropertyHandlerExample = Mockito.mock(DomiSMPPropertyHandlerExample.class);
+    DomiSMPPropertyResourceExample testInstance = new DomiSMPPropertyResourceExample(mockDomiSMPPropertyHandlerExample);
+
+    @Test
+    void identifier() {
+        String result = testInstance.identifier();
+
+        assertEquals("domismp-resource-example-properties", result);
+    }
+
+    @Test
+    void defaultUrlSegment() {
+        String result = testInstance.defaultUrlSegment();
+
+        assertEquals("prop", result);
+    }
+
+    @Test
+    void name() {
+        String result = testInstance.name();
+
+        assertEquals("DomiSMP property example", result);
+    }
+
+    @Test
+    void description() {
+        String result = testInstance.description();
+
+        assertEquals("DomiSMP property example", result);
+    }
+
+    @Test
+    void mimeType() {
+        String result = testInstance.mimeType();
+
+        assertEquals("text/x-properties", result);
+    }
+
+    @Test
+    void getSubresourceSpiList() {
+        List<SubresourceDefinitionSpi> result = testInstance.getSubresourceSpiList();
+
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    void getResourceHandler() {
+        ResourceHandlerSpi result = testInstance.getResourceHandler();
+
+        assertEquals(mockDomiSMPPropertyHandlerExample, result);
+    }
+
+    @Test
+    void testToString() {
+        String result = testInstance.toString();
+
+        MatcherAssert.assertThat(result, CoreMatchers.containsString("domismp-resource-example-properties"));
+    }
+}
diff --git a/smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/handler/AbstractHandlerTest.java b/smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/handler/AbstractHandlerTest.java
new file mode 100644
index 000000000..5985697e3
--- /dev/null
+++ b/smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/handler/AbstractHandlerTest.java
@@ -0,0 +1,116 @@
+package eu.europa.ec.smp.spi.examples.handler;
+
+import eu.europa.ec.smp.spi.api.SmpDataServiceApi;
+import eu.europa.ec.smp.spi.api.SmpIdentifierServiceApi;
+import eu.europa.ec.smp.spi.api.SmpXmlSignatureApi;
+import eu.europa.ec.smp.spi.api.model.RequestData;
+import eu.europa.ec.smp.spi.api.model.ResourceIdentifier;
+import eu.europa.ec.smp.spi.api.model.ResponseData;
+import eu.europa.ec.smp.spi.exceptions.ResourceException;
+import org.mockito.Mockito;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.Collections;
+
+import static org.junit.Assert.assertTrue;
+
+abstract class AbstractHandlerTest {
+    protected SmpDataServiceApi mockSmpDataApi = Mockito.mock(SmpDataServiceApi.class);
+    protected SmpIdentifierServiceApi mockSmpIdentifierServiceApi = Mockito.mock(SmpIdentifierServiceApi.class);
+    protected SmpXmlSignatureApi mockSignatureApi = Mockito.mock(SmpXmlSignatureApi.class);
+
+
+    protected RequestData requestData = Mockito.mock(RequestData.class);
+    protected ResponseData responseData = Mockito.mock(ResponseData.class);
+
+    void readResourceAction(String resourceName, ResourceIdentifier resourceIdentifier) throws ResourceException {
+        readResourceAction(resourceName, resourceIdentifier, null);
+    }
+
+    void readResourceAction(String resourceName, ResourceIdentifier resourceIdentifier, ResourceIdentifier subresourceIdentifier) throws ResourceException {
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Mockito.doReturn(baos).when(responseData).getOutputStream();
+        Mockito.doReturn(AbstractHandlerTest.class.getResourceAsStream(resourceName)).when(requestData).getResourceInputStream();
+        Mockito.doReturn(resourceIdentifier).when(requestData).getResourceIdentifier();
+        if (subresourceIdentifier != null) {
+            Mockito.doReturn(subresourceIdentifier).when(requestData).getSubresourceIdentifier();
+        }
+
+        Mockito.when(mockSmpIdentifierServiceApi.normalizeResourceIdentifier(Mockito.anyString(), Mockito.anyString())).thenAnswer(i -> new ResourceIdentifier((String) i.getArguments()[0], (String) i.getArguments()[1]));
+        getTestInstance().readResource(requestData, responseData);
+
+        assertTrue(baos.size() > 0);
+    }
+
+    void storeResourceAction(String resourceName, ResourceIdentifier resourceIdentifier) throws ResourceException {
+        storeResourceAction(resourceName, resourceIdentifier, null);
+    }
+
+    void storeResourceAction(String resourceName, ResourceIdentifier resourceIdentifier, ResourceIdentifier subresourceIdentifier) throws ResourceException {
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Mockito.doReturn(baos).when(responseData).getOutputStream();
+        Mockito.doReturn(AbstractHandlerTest.class.getResourceAsStream(resourceName)).when(requestData).getResourceInputStream();
+        Mockito.doReturn(resourceIdentifier).when(requestData).getResourceIdentifier();
+        if (subresourceIdentifier != null) {
+            Mockito.doReturn(subresourceIdentifier).when(requestData).getSubresourceIdentifier();
+            Mockito.when(mockSmpIdentifierServiceApi.normalizeSubresourceIdentifier(Mockito.anyString(), Mockito.anyString())).thenAnswer(i -> new ResourceIdentifier((String) i.getArguments()[0], (String) i.getArguments()[1]));
+        }
+        Mockito.when(mockSmpIdentifierServiceApi.normalizeResourceIdentifier(Mockito.anyString(), Mockito.anyString())).thenAnswer(i -> new ResourceIdentifier((String) i.getArguments()[0], (String) i.getArguments()[1]));
+        Mockito.doReturn(resourceIdentifier.getScheme()+"::"+resourceIdentifier.getValue()).when(mockSmpIdentifierServiceApi).formatResourceIdentifier(resourceIdentifier);
+
+        getTestInstance().storeResource(requestData, responseData);
+    }
+
+    void validateResourceAction(String resourceName, ResourceIdentifier resourceIdentifier) throws ResourceException {
+        validateResourceAction(resourceName, resourceIdentifier, null);
+    }
+
+    void validateResourceAction(String resourceName, ResourceIdentifier resourceIdentifier, ResourceIdentifier subresourceIdentifier) throws ResourceException {
+        // validate
+        if (subresourceIdentifier != null) {
+            Mockito.doReturn(subresourceIdentifier).when(requestData).getSubresourceIdentifier();
+            Mockito.when(mockSmpIdentifierServiceApi.normalizeSubresourceIdentifier(Mockito.anyString(), Mockito.anyString())).thenAnswer(i -> new ResourceIdentifier((String) i.getArguments()[0], (String) i.getArguments()[1]));
+        }
+        Mockito.doReturn(AbstractHandlerTest.class.getResourceAsStream(resourceName)).when(requestData).getResourceInputStream();
+        Mockito.doReturn(resourceIdentifier).when(requestData).getResourceIdentifier();
+        Mockito.when(mockSmpIdentifierServiceApi.normalizeResourceIdentifier(Mockito.anyString(), Mockito.anyString())).thenAnswer(i -> new ResourceIdentifier((String) i.getArguments()[0], (String) i.getArguments()[1]));
+        Mockito.doReturn(resourceIdentifier.getScheme()+"::"+resourceIdentifier.getValue()).when(mockSmpIdentifierServiceApi).formatResourceIdentifier(resourceIdentifier);
+
+
+        getTestInstance().validateResource(requestData);
+    }
+
+
+    void generateResourceAction(ResourceIdentifier resourceIdentifier) throws ResourceException {
+        generateResourceAction(resourceIdentifier, null);
+    }
+
+    void generateResourceAction(ResourceIdentifier resourceIdentifier, ResourceIdentifier subresourceIdentifier) throws ResourceException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Mockito.doReturn(resourceIdentifier).when(requestData).getResourceIdentifier();
+        Mockito.doReturn(resourceIdentifier.getScheme()+"::"+resourceIdentifier.getValue()).when(mockSmpIdentifierServiceApi).formatResourceIdentifier(resourceIdentifier);
+
+        if (subresourceIdentifier != null) {
+            Mockito.doReturn(subresourceIdentifier).when(requestData).getSubresourceIdentifier();
+            Mockito.when(mockSmpIdentifierServiceApi.normalizeSubresourceIdentifier(Mockito.anyString(), Mockito.anyString())).thenAnswer(i -> new ResourceIdentifier((String) i.getArguments()[0], (String) i.getArguments()[1]));
+
+        }
+        Mockito.doReturn(baos).when(responseData).getOutputStream();
+
+        getTestInstance().generateResource(requestData, responseData, Collections.emptyList());
+        assertTrue(baos.size() > 0);
+
+        // The generated resource should be valid
+        ByteArrayInputStream bios = new ByteArrayInputStream(baos.toByteArray());
+        Mockito.doReturn(bios).when(requestData).getResourceInputStream();
+        Mockito.doReturn(resourceIdentifier).when(mockSmpIdentifierServiceApi).normalizeResourceIdentifier(Mockito.anyString(), Mockito.anyString());
+        getTestInstance().validateResource(requestData);
+
+        System.out.println("Generated resource: " + new String(baos.toByteArray()));
+    }
+
+    abstract AbstractHandler getTestInstance();
+}
diff --git a/smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/handler/DomiSMPJSONHandlerExampleTest.java b/smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/handler/DomiSMPJSONHandlerExampleTest.java
new file mode 100644
index 000000000..df97e38fd
--- /dev/null
+++ b/smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/handler/DomiSMPJSONHandlerExampleTest.java
@@ -0,0 +1,67 @@
+package eu.europa.ec.smp.spi.examples.handler;
+
+import eu.europa.ec.smp.spi.api.model.ResourceIdentifier;
+import eu.europa.ec.smp.spi.exceptions.ResourceException;
+import org.hamcrest.MatcherAssert;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.Assert.assertThrows;
+
+
+class DomiSMPJSONHandlerExampleTest extends AbstractHandlerTest {
+
+    @Override
+    AbstractHandler getTestInstance() {
+        return new DomiSMPJSONHandlerExample(mockSmpDataApi, mockSmpIdentifierServiceApi, mockSignatureApi);
+    }
+
+    @Test
+    void testGenerateResource() throws ResourceException {
+
+        ResourceIdentifier resourceIdentifier = new ResourceIdentifier("test-identifier", "test-test-test");
+
+        generateResourceAction(resourceIdentifier);
+    }
+
+    @Test
+    void validateResourceOK() throws ResourceException {
+        ResourceIdentifier resourceIdentifier = new ResourceIdentifier("test-identifier", "test-test-test");
+        // validate
+        validateResourceAction("/examples/json_ok.json", resourceIdentifier);
+    }
+
+
+    @Test
+    void validateResourceInvalidIdentifier() {
+        ResourceIdentifier resourceIdentifier = new ResourceIdentifier("urn:poland:ncpb:utestt", "test-test-test");
+        // validate
+        ResourceException result = assertThrows(ResourceException.class,
+                () -> validateResourceAction("/examples/json_ok.json", resourceIdentifier));
+        MatcherAssert.assertThat(result.getMessage(), org.hamcrest.Matchers.containsString("Property: [identifier] does not match value for the resource"));
+    }
+
+    @Test
+    void validateResourceInvalidScheme() {
+
+        ResourceIdentifier resourceIdentifier = new ResourceIdentifier("test-identifier", "test1-test-test");
+        // validate
+        ResourceException result = assertThrows(ResourceException.class,
+                () -> validateResourceAction("/examples/json_ok.json", resourceIdentifier));
+        MatcherAssert.assertThat(result.getMessage(), org.hamcrest.Matchers.containsString("Property: [identifier] does not match value for the resource"));
+    }
+
+    @Test
+    void readResourceOK() throws ResourceException {
+        String resourceName = "/examples/json_ok.json";
+        ResourceIdentifier resourceIdentifier = new ResourceIdentifier("test-identifier", "test-test-test");
+
+        readResourceAction(resourceName, resourceIdentifier);
+    }
+
+    @Test
+    void storeResourceOK() throws ResourceException {
+        String resourceName = "/examples/json_ok.json";
+        ResourceIdentifier resourceIdentifier = new ResourceIdentifier("test-identifier", "test-test-test");
+        storeResourceAction(resourceName, resourceIdentifier);
+    }
+}
diff --git a/smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/handler/DomiSMPPropertyHandlerExampleTest.java b/smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/handler/DomiSMPPropertyHandlerExampleTest.java
new file mode 100644
index 000000000..0a0fee699
--- /dev/null
+++ b/smp-examples/resource-spi-example/src/test/java/eu/europa/ec/smp/spi/examples/handler/DomiSMPPropertyHandlerExampleTest.java
@@ -0,0 +1,68 @@
+package eu.europa.ec.smp.spi.examples.handler;
+
+import eu.europa.ec.smp.spi.api.model.ResourceIdentifier;
+import eu.europa.ec.smp.spi.exceptions.ResourceException;
+import org.hamcrest.MatcherAssert;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.Assert.assertThrows;
+
+class DomiSMPPropertyHandlerExampleTest extends AbstractHandlerTest {
+
+    @Override
+    AbstractHandler getTestInstance() {
+        return new DomiSMPPropertyHandlerExample(mockSmpDataApi, mockSmpIdentifierServiceApi, mockSignatureApi);
+    }
+
+    @Test
+    void testGenerateResource() throws ResourceException {
+
+        ResourceIdentifier resourceIdentifier = new ResourceIdentifier("test-identifier", "test-test-test");
+
+        generateResourceAction(resourceIdentifier);
+    }
+
+    @Test
+    void validateResourceOK() throws ResourceException {
+        ResourceIdentifier resourceIdentifier = new ResourceIdentifier("test-identifier", "test-test-test");
+        // validate
+        validateResourceAction("/examples/properties_ok.properties", resourceIdentifier);
+    }
+
+
+    @Test
+    void validateResourceInvalidIdentifier() {
+        ResourceIdentifier resourceIdentifier = new ResourceIdentifier("urn:poland:ncpb:utestt", "test-test-test");
+        // validate
+        ResourceException result = assertThrows(ResourceException.class,
+                () -> validateResourceAction("/examples/properties_ok.properties", resourceIdentifier));
+        MatcherAssert.assertThat(result.getMessage(), org.hamcrest.Matchers.containsString("Property: [domismp.extension.example.identifier] does not match value for the resource"));
+    }
+
+    @Test
+    void validateResourceInvalidScheme() {
+
+        ResourceIdentifier resourceIdentifier = new ResourceIdentifier("test-identifier", "test1-test-test");
+        // validate
+        ResourceException result = assertThrows(ResourceException.class,
+                () -> validateResourceAction("/examples/properties_ok.properties", resourceIdentifier));
+        MatcherAssert.assertThat(result.getMessage(), org.hamcrest.Matchers.containsString("Property: [domismp.extension.example.identifier] does not match value for the resource"));
+    }
+
+    @Test
+    void readResourceOK() throws ResourceException {
+        String resourceName = "/examples/properties_ok.properties";
+        ResourceIdentifier resourceIdentifier = new ResourceIdentifier("test-identifier", "test-test-test");
+
+        readResourceAction(resourceName, resourceIdentifier);
+    }
+
+    @Test
+    void storeResourceOK() throws ResourceException {
+        String resourceName = "/examples/properties_ok.properties";
+        ResourceIdentifier resourceIdentifier = new ResourceIdentifier("test-identifier", "test-test-test");
+
+        storeResourceAction(resourceName, resourceIdentifier);
+    }
+
+}
diff --git a/smp-examples/resource-spi-example/src/test/resources/examples/json_ok.json b/smp-examples/resource-spi-example/src/test/resources/examples/json_ok.json
new file mode 100644
index 000000000..e7132807d
--- /dev/null
+++ b/smp-examples/resource-spi-example/src/test/resources/examples/json_ok.json
@@ -0,0 +1,6 @@
+{
+  "identifier" : "test-test-test::test-identifier",
+  "url" : "http://example.local/test",
+  "email" : "test.address@example.local",
+  "certificate" : "MIIDDzCCAfegAwIBAgIBCjANBgkqhkiG9w0BAQsFADBLMSgwJgYDVQQDDB90ZXN0LXRlc3QtdGVzdDo6dGVzdC1pZGVudGlmaWVyMRIwEAYDVQQKDAllZGVsaXZlcnkxCzAJBgNVBAYTAkVVMB4XDTIzMDcxNjA4MjQ1N1oXDTI0MDcxNzA4MjQ1N1owSzEoMCYGA1UEAwwfdGVzdC10ZXN0LXRlc3Q6OnRlc3QtaWRlbnRpZmllcjESMBAGA1UECgwJZWRlbGl2ZXJ5MQswCQYDVQQGEwJFVTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJgeUTg1Lko98jFhnM0WjtozpS90jjIPYU6X4Qq2XmvQQ9gotxxwoXOZWm/o/ls9BJvBydav7fB3EktROQhGdFBWgpSu40zJJNBbHdaIRJsAvJkdBnGJIpHtetG91MoH8FiiGhaZQhBDiJ37jFYkLTIl86gX2X/iv/eTqvCw8FDxKjve1Rl6FKANhgidLb0+EXiLcDLpFutPfifYxyKLt5ngqFd01uVxQAdYYDNXX1aHzvLFODiFINqufk2CIsFZ3BuYa0tLK60bF8ZrY+hNSowE2DGd8MpMuFEQnCkOaF1PbmiZnDo3GH2GWIPemRWhtugt+Rm07z3NMtClWemHQWsCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAG45OPK/iWLzCIOWDp85iFrjNmJxZSSP88j2TWObFa+frb6VBMr0QLczclU9SbB3wS8c3udQ7uNCvySyDbY/jHmqZk8U5dkgwzQ5LPK97tgQvCgf/FI3SuHkqaQRo5MLl2iVu+1R8RcriKPe6Q91pwknp+D2+YImVoGADpWL7J+pHnPxL9Ns8bHmBP03XuM/CVTh5U6z0X17yHJ/Z/JSxDqtFzbutMlFnBG9u/+g19U/eevcte0lNVeDFFtWRcEllzmWEO53CZb/qMm6zRV27M+E5F04iAulQKp8qi95ruMoOIl0DcRMCsGo0uwZ/oB66i25CP3XKj3o4d+JDLTb+dg=="
+}
diff --git a/smp-examples/resource-spi-example/src/test/resources/examples/properties_ok.properties b/smp-examples/resource-spi-example/src/test/resources/examples/properties_ok.properties
new file mode 100644
index 000000000..22f591a72
--- /dev/null
+++ b/smp-examples/resource-spi-example/src/test/resources/examples/properties_ok.properties
@@ -0,0 +1,5 @@
+#Mon Jul 17 10:13:00 CEST 2023
+domismp.extension.example.email=test.address@example.local
+domismp.extension.example.identifier=test-test-test\:\:test-identifier
+domismp.extension.example.url=http\://example.local/test
+domismp.extension.example.certificate=MIIDDzCCAfegAwIBAgIBCjANBgkqhkiG9w0BAQsFADBLMSgwJgYDVQQDDB90ZXN0LXRlc3QtdGVzdDo6dGVzdC1pZGVudGlmaWVyMRIwEAYDVQQKDAllZGVsaXZlcnkxCzAJBgNVBAYTAkVVMB4XDTIzMDcxNjA4MTMwMFoXDTI0MDcxNzA4MTMwMFowSzEoMCYGA1UEAwwfdGVzdC10ZXN0LXRlc3Q6OnRlc3QtaWRlbnRpZmllcjESMBAGA1UECgwJZWRlbGl2ZXJ5MQswCQYDVQQGEwJFVTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJzIAawzfe96c5Gjbh2Ne6+VOcRnLW4N3JENakAoyGuwHSmP0T31xaVhMx2WCj+AhelSjDqhaFC5/q94+ThCtm+BcY++cUJwjW6rdh3UN++EaMQiy/PKfmlqDWwakHRwI0U3Kq+qjU1TEJRQJlTIeI6DTY0sj2pd+rSIeSBlICnGWaHqc/tJsnczf3oIA+AnsTeSpFe/UzLlwZkMxrV+6lbyVJ7mpVGnue2KFyaGD3RuEk8h4838P1x2mapFIdplAFWr9c7fba/Dg/7AKd5HGpAn5bRVAC9L7bPGdk0LLL3om9tPwfujf7kgwkO17qy0vAx4qaTSanPj+xfEjTPuumkCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAi1PFmo8Lk6Xskti2vMeYjhD4wE2E7TBch5ecdh3AhTuoSMdlXIQuGEsRhgbD9Pispq7U5cYXKwwKw82pCGhAxItqa8m4Y2hPhZpmJuT3g0pEyz19FDPSA8UJ2pvCVFWUWnyy5jzE6Wh1RndInOIfbHJovhjoQApyYmPyzJzeps+0H72xkyX/Dz4pvs+eAoulwdMkVUT169p4AqtQaH7uwPPT7cdaRBJggm/QVp0v8bgxKK+hv/h8gdi6dm4s3Txe5O14doDTnEj1IFKsqaZBWs5z7lXvBsiMrZ95fMIm1W5NVJwQ2nhfMLGZuJkM/Bf2dahkknn3qz3TtwW7jKl4vg\=\=
diff --git a/smp-resource-extensions/oasis-cppa3-spi/src/test/java/eu/europa/ec/smp/spi/handler/OasisCppa3CppHandlerTest.java b/smp-resource-extensions/oasis-cppa3-spi/src/test/java/eu/europa/ec/smp/spi/handler/OasisCppa3CppHandlerTest.java
index 2b0799338..f7a005809 100644
--- a/smp-resource-extensions/oasis-cppa3-spi/src/test/java/eu/europa/ec/smp/spi/handler/OasisCppa3CppHandlerTest.java
+++ b/smp-resource-extensions/oasis-cppa3-spi/src/test/java/eu/europa/ec/smp/spi/handler/OasisCppa3CppHandlerTest.java
@@ -1,31 +1,19 @@
 package eu.europa.ec.smp.spi.handler;
 
-import eu.europa.ec.smp.spi.api.SmpDataServiceApi;
-import eu.europa.ec.smp.spi.api.SmpIdentifierServiceApi;
-import eu.europa.ec.smp.spi.api.SmpXmlSignatureApi;
-import eu.europa.ec.smp.spi.api.model.RequestData;
 import eu.europa.ec.smp.spi.api.model.ResourceIdentifier;
-import eu.europa.ec.smp.spi.api.model.ResponseData;
 import eu.europa.ec.smp.spi.exceptions.CPPARuntimeException;
 import eu.europa.ec.smp.spi.exceptions.ResourceException;
 import org.hamcrest.MatcherAssert;
 import org.junit.jupiter.api.Test;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.xml.sax.SAXParseException;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.util.Collections;
+import static org.junit.Assert.assertThrows;
 
-import static org.junit.Assert.*;
-
-public class OasisCppa3CppHandlerTest extends AbstractHandlerTest{
+public class OasisCppa3CppHandlerTest extends AbstractHandlerTest {
 
 
     @Override
     AbstractHandler getTestInstance() {
-        return  new OasisCppa3CppHandler(mockSmpDataApi, mockSmpIdentifierServiceApi, mockSignatureApi);
+        return new OasisCppa3CppHandler(mockSmpDataApi, mockSmpIdentifierServiceApi, mockSignatureApi);
     }
 
     @Test
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 3ceb397bd..668c9d063 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
@@ -203,15 +203,10 @@ public class CredentialService {
     @Transactional(noRollbackFor = {AuthenticationException.class, BadCredentialsException.class, SMPRuntimeException.class})
     public Authentication authenticateByCertificateToken(PreAuthenticatedCertificatePrincipal principal) {
         LOG.info("authenticateByCertificateToken:" + principal.getName());
-
-
         X509Certificate x509Certificate = principal.getCertificate();
         String certificateIdentifier = principal.getName();
-
-
         long startTime = Calendar.getInstance().getTimeInMillis();
 
-
         if (x509Certificate != null) {
             try {
                 truststoreService.validateCertificateWithTruststore(x509Certificate);
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/TestUtilsDao.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/TestUtilsDao.java
index 30f7b3f9f..3c40d7ab7 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/TestUtilsDao.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/data/dao/TestUtilsDao.java
@@ -1,5 +1,7 @@
 package eu.europa.ec.edelivery.smp.data.dao;
 
+import eu.europa.ec.edelivery.smp.data.enums.CredentialTargetType;
+import eu.europa.ec.edelivery.smp.data.enums.CredentialType;
 import eu.europa.ec.edelivery.smp.data.enums.MembershipRoleType;
 import eu.europa.ec.edelivery.smp.data.enums.VisibilityType;
 import eu.europa.ec.edelivery.smp.data.model.DBDomain;
@@ -223,9 +225,12 @@ public class TestUtilsDao {
         DBCredential c3 = TestDBUtils.createDBCredentialForUserAccessToken(user3, null, null, null);
         c3.setValue(BCrypt.hashpw(USERNAME_3_AT_PASSWORD, BCrypt.gensalt()));
         c3.setName(USERNAME_3_AT);
+        DBCredential cCert3 = TestDBUtils.createDBCredential(user3, USER_CERT_3, "", CredentialType.CERTIFICATE, CredentialTargetType.REST_API);
+
         user3.getUserCredentials().add(c3);
+        user3.getUserCredentials().add(cCert3);
 
-        user4 = createDBUserByUsername(USERNAME_4);
+        user4 = createDBUserByUsername(USER_CERT_2);
         user5 = createDBUserByUsername(USERNAME_5);
 
         persistFlushDetach(user1);
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/CredentialServiceTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/CredentialServiceTest.java
index c57fc2ec5..38c7b4eb7 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/CredentialServiceTest.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/CredentialServiceTest.java
@@ -1,8 +1,11 @@
 package eu.europa.ec.edelivery.smp.services;
 
 
+import eu.europa.ec.edelivery.security.PreAuthenticatedCertificatePrincipal;
+import eu.europa.ec.edelivery.security.utils.X509CertificateUtils;
 import eu.europa.ec.edelivery.smp.data.model.user.DBCredential;
 import eu.europa.ec.edelivery.smp.testutil.TestConstants;
+import eu.europa.ec.edelivery.smp.testutil.X509CertificateTestUtils;
 import org.hamcrest.MatcherAssert;
 import org.junit.Before;
 import org.junit.Ignore;
@@ -15,7 +18,10 @@ import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringRunner;
 
 import java.io.IOException;
+import java.math.BigInteger;
+import java.security.cert.X509Certificate;
 import java.time.OffsetDateTime;
+import java.util.Collections;
 
 import static org.junit.Assert.*;
 
@@ -225,4 +231,37 @@ public class CredentialServiceTest extends AbstractServiceIntegrationTest {
         assertEquals(TestConstants.USERNAME_3_AT, authentication.getName());
     }
 
+
+    @Test
+    public void authenticateByCertificateTokenOkWithRole() throws Exception {
+        // given
+
+        // must match the TestConstants.USER_CERT_3
+        X509Certificate cert = X509CertificateTestUtils.createX509CertificateForTest("CN=test example,O=European Commission,C=BE",
+                new BigInteger("0dd0d2f98cc25205bc6c854d1cd88411", 16), Collections.emptyList());
+
+        PreAuthenticatedCertificatePrincipal principal = X509CertificateUtils.extractPrincipalFromCertificate(cert);
+
+        // when
+        Authentication authentication = testInstance.authenticateByCertificateToken(principal);
+        // then
+        assertEquals(TestConstants.USER_CERT_3, authentication.getName());
+        assertTrue(authentication.isAuthenticated());
+        assertEquals(1, authentication.getAuthorities().size());
+        assertEquals("ROLE_WS_USER", authentication.getAuthorities().iterator().next().getAuthority());
+    }
+
+    @Test
+    public void authenticateByCertificateTokenNotTrusted() throws Exception {
+        // given
+        X509Certificate cert = X509CertificateTestUtils.createX509CertificateForTest("CN=NotRegistered,O=European Commission,C=BE",
+                new BigInteger("111111", 16), Collections.emptyList());
+
+        PreAuthenticatedCertificatePrincipal principal = X509CertificateUtils.extractPrincipalFromCertificate(cert);
+
+        // when
+        BadCredentialsException result = assertThrows(BadCredentialsException.class, () -> testInstance.authenticateByCertificateToken(principal));
+        // then
+        MatcherAssert.assertThat(result.getMessage(), org.hamcrest.Matchers.startsWith("Login failed"));
+    }
 }
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
index d0337010b..aa795b06a 100644
--- 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
@@ -60,15 +60,7 @@ public class TestConstants {
 
     public static final String USER_CERT_1 = "CN=utest common name 01,O=org,C=BE:0000000000000066";
     public static final String USER_CERT_2 = "CN=utest common name 02,O=org,C=BE:0000000000000077";
-    public static final String USER_CERT_3 = "CN=utest common name 03,O=org,C=BE:0000000000000077";
-
-
-    public static final String SERVICE_GROUP_POLAND_XML_PATH = "/examples/services/ServiceGroupPoland.xml";
-    public static final String SERVICE_GROUP_TEST2_XML_PATH = "/examples/services/ServiceGroupTestSgId2.xml";
-    public static final String SERVICE_METADATA_XML_PATH = "/examples/services/ServiceMetadataPoland.xml";
-    public static final String SIGNED_SERVICE_METADATA_XML_PATH = "/examples/services/SignedServiceMetadataPoland.xml";
-
-    //public static final ParticipantIdentifierType SERVICE_GROUP_ID = new ParticipantIdentifierType("urn:eu:ncpb", "participant-scheme-qns");
+    public static final String USER_CERT_3 = "CN=test example,O=European Commission,C=BE:0dd0d2f98cc25205bc6c854d1cd88411";
 
 
     public static final String ADMIN_USERNAME = "test_admin";
@@ -77,14 +69,6 @@ public class TestConstants {
 
     // parameter: custom string as content
     public static final String SIMPLE_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: %s</ex:dummynode></Extension>";
-    //5 parameters: ParticipantScheme, ParticipantIdentifier, DocumentScheme, DocumentIdentifier, custom value
-    public static final String SIMPLE_DOCUMENT_XML = "<ServiceMetadata xmlns=\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\"><ServiceInformation><ParticipantIdentifier scheme=\"%s\">%s</ParticipantIdentifier><DocumentIdentifier scheme=\"%s\">%s</DocumentIdentifier><ProcessList><Process><ProcessIdentifier scheme=\"cenbii-procid-ubl\">urn:www.cenbii.eu:profile:bii04:ver1.0</ProcessIdentifier><ServiceEndpointList><Endpoint transportProfile=\"bdxr-transport-ebms3-as4-v1p0\"><EndpointURI>http://localhost:8080/domibus-weblogic/services/msh</EndpointURI><RequireBusinessLevelSignature>true</RequireBusinessLevelSignature><ServiceActivationDate>2003-01-01T00:00:00</ServiceActivationDate><ServiceExpirationDate>2099-05-01T00:00:00</ServiceExpirationDate>" +
-            "<Certificate>MIID7jCCA1egAwIBAgICA+YwDQYJKoZIhvcNAQENBQAwOjELMAkGA1UEBhMCRlIxEzARBgNVBAoMCklIRSBFdXJvcGUxFjAUBgNVBAMMDUlIRSBFdXJvcGUgQ0EwHhcNMTYwNjAxMTQzNTUzWhcNMjYwNjAxMTQzNTUzWjCBgzELMAkGA1UEBhMCUFQxDDAKBgNVBAoMA01vSDENMAsGA1UECwwEU1BNUzENMAsGA1UEKgwESm9hbzEOMAwGA1UEBRMFQ3VuaGExHTAbBgNVBAMMFHFhZXBzb3MubWluLXNhdWRlLnB0MRkwFwYDVQQMDBBTZXJ2aWNlIFByb3ZpZGVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1eN4qPSSRZqjVFG9TlcPlxf2WiSimQK9L1nf9Z/s0ezeGQjCukDeDq/Wzqd9fpHhaMMq+XSSOtyEtIr5K/As4kFrViONUUkG12J6UllSWogp0NYFwA4wIqKSFiTnQS5/nRTs05oONCCGILCyJNNeO53JzPlaq3/QbPLssuSAr6XucPE8wBBGM8b/TsB2G/zjG8yuSTgGbhaZekq/Vnf9ftj1fr/vJDDAQgH6Yvzd88Z0DACJPHfW1p4F/OWLI386Bq7g/bo1DUPAyEwlf+CkLgJWRKki3yJlOCIZ9enMA5O7rfeG3rXdgYGmWS7tNEgKXxgC+heiYvi7ZWd7M+/SUwIDAQABo4IBMzCCAS8wPgYDVR0fBDcwNTAzoDGgL4YtaHR0cHM6Ly9nYXplbGxlLmloZS5uZXQvcGtpL2NybC82NDMvY2FjcmwuY3JsMDwGCWCGSAGG+EIBBAQvFi1odHRwczovL2dhemVsbGUuaWhlLm5ldC9wa2kvY3JsLzY0My9jYWNybC5jcmwwPAYJYIZIAYb4QgEDBC8WLWh0dHBzOi8vZ2F6ZWxsZS5paGUubmV0L3BraS9jcmwvNjQzL2NhY3JsLmNybDAfBgNVHSMEGDAWgBTsMw4TyCJeouFrr0N7el3Sd3MdfjAdBgNVHQ4EFgQU1GQ/K1ykIwWFgiONzWJLQzufF/8wDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBSAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQENBQADgYEAZ7t1Qkr9wz3q6+WcF6p/YX7Jr0CzVe7w58FvJFk2AsHeYkSlOyO5hxNpQbs1L1v6JrcqziNFrh2QKGT2v6iPdWtdCT8HBLjmuvVWxxnfzYjdQ0J+kdKMAEV6EtWU78OqL60CCtUZKXE/NKJUq7TTUCFP2fwiARy/t1dTD2NZo8c=</Certificate><ServiceDescription>Sample description of %s</ServiceDescription><TechnicalContactUrl>https://example.com</TechnicalContactUrl></Endpoint></ServiceEndpointList></Process></ProcessList></ServiceInformation></ServiceMetadata>";
-
-    public static final String SIMPLE_REDIRECT_DOCUMENT_XML ="<ServiceMetadata xmlns=\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\">" +
-            "   <Redirect href=\"%s\">" +
-            "    <CertificateUID>smptest</CertificateUID>" +
-            "  </Redirect>" +
-            "</ServiceMetadata>";
+
 
 }
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java
index 3b1e5f9d1..83334a266 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java
@@ -20,6 +20,7 @@ import eu.europa.ec.edelivery.smp.data.model.user.DBUser;
 import eu.europa.ec.edelivery.smp.data.ui.enums.AlertLevelEnum;
 import eu.europa.ec.edelivery.smp.data.ui.enums.AlertStatusEnum;
 import eu.europa.ec.edelivery.smp.data.ui.enums.AlertTypeEnum;
+import org.apache.commons.lang3.StringUtils;
 
 import java.time.OffsetDateTime;
 import java.util.UUID;
@@ -141,18 +142,10 @@ public class TestDBUtils {
         return grp;
     }
 
-    public static byte[] generateDocumentSample(String partcId, String partcSch, String docId, String docSch, String desc) {
-        return String.format(SIMPLE_DOCUMENT_XML, partcSch, partcId, docSch, docId, desc).getBytes();
-    }
-
     public static byte[] generateExtension() {
         return String.format(SIMPLE_EXTENSION_XML, anyString()).getBytes();
     }
 
-    public static byte[] generateRedirectDocumentSample(String url) {
-        return String.format(SIMPLE_REDIRECT_DOCUMENT_XML, url).getBytes();
-
-    }
 
     public static DBResource createDBResource(String id, String sch) {
         return createDBResource(id, sch, true);
@@ -214,15 +207,21 @@ public class TestDBUtils {
 
     public static DBCredential createDBCredentialForUserCertificate(DBUser user, OffsetDateTime from , OffsetDateTime to, OffsetDateTime lastAlertSent ) {
         DBCredential credential =  createDBCredential(user, user.getUsername(), "value", CredentialType.CERTIFICATE, CredentialTargetType.REST_API);
-        credential.setExpireOn(to);
-        credential.setActiveFrom(from);
         credential.setExpireAlertOn(lastAlertSent);
+        if (to != null) {
+            credential.setExpireOn(to);
+        }
+        if (from != null) {
+            credential.setActiveFrom(from);
+        }
+
         return credential;
     }
 
 
     public static DBCredential createDBCredential(DBUser dbUser, String name, String value, CredentialType credentialType, CredentialTargetType credentialTargetType) {
         DBCredential dbCredential = new DBCredential();
+        dbCredential.setActive(true);
         dbCredential.setValue(value);
         dbCredential.setName(name);
         dbCredential.setCredentialType(credentialType);
@@ -233,11 +232,34 @@ public class TestDBUtils {
         dbCredential.setExpireAlertOn(OffsetDateTime.now());
         dbCredential.setSequentialLoginFailureCount(1);
         dbCredential.setUser(dbUser);
+
+        if (CredentialType.CERTIFICATE.equals(credentialType)) {
+
+            DBCertificate certificate = new DBCertificate();
+            certificate.setCertificateId(name);
+            certificate.setValidFrom(dbCredential.getActiveFrom());
+            certificate.setValidTo(dbCredential.getExpireOn());
+
+            int iSplit = name.lastIndexOf(':');
+            if (iSplit>0) {
+                String subject = name.substring(0, iSplit);
+                certificate.setSubject(subject);
+                certificate.setIssuer(subject);
+                certificate.setSerialNumber(name.substring(iSplit+1));
+            } else {
+                certificate.setSubject(name);
+                certificate.setIssuer(name);
+                certificate.setSerialNumber("1234567890");
+            }
+            dbCredential.setCertificate(certificate);
+        }
+
         return dbCredential;
     }
 
     public static DBCredential createDBCredential(String name, String value, CredentialType credentialType, CredentialTargetType credentialTargetType) {
         DBCredential dbCredential = new DBCredential();
+        dbCredential.setActive(true);
         dbCredential.setValue(value);
         dbCredential.setName(name);
         dbCredential.setCredentialType(credentialType);
@@ -306,7 +328,7 @@ public class TestDBUtils {
         dbuser.getUserCredentials().add(credential);
         return dbuser;
     }
-    
+
     public static String anyString(){
         return UUID.randomUUID().toString();
     }
diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestROUtils.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestROUtils.java
index 7a444f72c..8e5a1dc79 100644
--- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestROUtils.java
+++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestROUtils.java
@@ -2,52 +2,17 @@ package eu.europa.ec.edelivery.smp.testutil;
 
 import eu.europa.ec.edelivery.smp.conversion.X509CertificateToCertificateROConverter;
 import eu.europa.ec.edelivery.smp.data.enums.VisibilityType;
-import eu.europa.ec.edelivery.smp.data.model.DBDomain;
-import eu.europa.ec.edelivery.smp.data.ui.*;
+import eu.europa.ec.edelivery.smp.data.ui.CertificateRO;
+import eu.europa.ec.edelivery.smp.data.ui.ResourceRO;
 import eu.europa.ec.edelivery.smp.data.ui.enums.EntityROStatus;
 
 import java.math.BigInteger;
 import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.UUID;
 
-import static eu.europa.ec.edelivery.smp.testutil.TestConstants.SIMPLE_DOCUMENT_XML;
-import static eu.europa.ec.edelivery.smp.testutil.TestConstants.SIMPLE_EXTENSION_XML;
 
 public class TestROUtils {
 
     public static final X509CertificateToCertificateROConverter CERT_CONVERTER = new X509CertificateToCertificateROConverter();
-    private static final String RES_PATH = "";
-
-
-    public static ServiceMetadataRO createServiceMetadataDomain(DBDomain domain, ServiceGroupRO sgo, String docid, String docSch) {
-        ServiceMetadataRO sgdmd = new ServiceMetadataRO();
-        sgdmd.setDomainCode(domain.getDomainCode());
-        sgdmd.setSmlSubdomain(domain.getSmlSubdomain());
-        sgdmd.setDocumentIdentifier(docid);
-        sgdmd.setDocumentIdentifierScheme(docSch);
-        sgdmd.setXmlContent(generateServiceMetadata(sgo.getParticipantIdentifier(), sgo.getParticipantScheme(), docid, docSch));
-        return sgdmd;
-    }
-
-    public static ServiceGroupDomainRO createServiceGroupDomain(DBDomain domain) {
-
-        ServiceGroupDomainRO sgd = new ServiceGroupDomainRO();
-        sgd.setDomainId(domain.getId());
-        sgd.setDomainCode(domain.getDomainCode());
-        sgd.setSmlSubdomain(domain.getSmlSubdomain());
-        return sgd;
-    }
-
-    public static ResourceRO createResource() {
-        return createResource(TestConstants.TEST_SG_ID_1, TestConstants.TEST_SG_SCHEMA_1);
-    }
-
-
-
-    public static ResourceRO createResource(String id, String sch) {
-        return createResource(id, sch, null);
-    }
 
     public static ResourceRO createResource(String id, String sch, String resourceType) {
         ResourceRO resourceRO = new ResourceRO();
@@ -59,22 +24,6 @@ public class TestROUtils {
         return resourceRO;
     }
 
-    public static String generateExtension() {
-        return String.format(SIMPLE_EXTENSION_XML, UUID.randomUUID().toString());
-    }
-
-    public static String generateServiceMetadata(String partId, String partSch, String docId, String docSch) {
-        return String.format(SIMPLE_DOCUMENT_XML, partSch, partId, docSch, docId, UUID.randomUUID().toString());
-    }
-
-    public static ServiceGroupValidationRO getExtensionRO(String extension) {
-        ServiceGroupValidationRO sg = new ServiceGroupValidationRO();
-        sg.setServiceGroupId((long) 1);
-        sg.setExtension(extension);
-        return sg;
-    }
-
-
     public static CertificateRO createCertificateRO(String certSubject, BigInteger serial) throws Exception {
         X509Certificate cert = X509CertificateTestUtils.createX509CertificateForTest(certSubject, serial, null);
         return CERT_CONVERTER.convert(cert);
-- 
GitLab