From 60ab57ed2b95ae73fca8b80876073be6235ef294 Mon Sep 17 00:00:00 2001
From: Martin Vogel <martin.vogel@sinc.de>
Date: Wed, 14 Aug 2024 08:35:56 +0200
Subject: [PATCH] feat: add service provider for validation service
 (planning#2016)

---
 .../api/spi/ValidationServiceProvider.java    |  12 +++
 .../client/bootstrap/ClientFactory.java       |   5 +-
 .../client/bootstrap/ProviderUtil.java        |  20 ++++
 .../spi/DefaultValidationServiceProvider.java |  18 ++++
 .../spi/SkipValidationServiceProvider.java    | 101 ++++++++++++++++++
 ...tconnect.api.spi.ValidationServiceProvider |   6 ++
 6 files changed, 160 insertions(+), 2 deletions(-)
 create mode 100644 client/src/main/java/dev/fitko/fitconnect/api/spi/ValidationServiceProvider.java
 create mode 100644 client/src/main/java/dev/fitko/fitconnect/client/bootstrap/ProviderUtil.java
 create mode 100644 client/src/main/java/dev/fitko/fitconnect/client/bootstrap/spi/DefaultValidationServiceProvider.java
 create mode 100644 client/src/main/java/dev/fitko/fitconnect/client/bootstrap/spi/SkipValidationServiceProvider.java
 create mode 100644 client/src/main/resources/META-INF/services/dev.fitko.fitconnect.api.spi.ValidationServiceProvider

diff --git a/client/src/main/java/dev/fitko/fitconnect/api/spi/ValidationServiceProvider.java b/client/src/main/java/dev/fitko/fitconnect/api/spi/ValidationServiceProvider.java
new file mode 100644
index 000000000..02fc7a9af
--- /dev/null
+++ b/client/src/main/java/dev/fitko/fitconnect/api/spi/ValidationServiceProvider.java
@@ -0,0 +1,12 @@
+package dev.fitko.fitconnect.api.spi;
+
+import dev.fitko.fitconnect.api.config.ApplicationConfig;
+import dev.fitko.fitconnect.api.services.crypto.MessageDigestService;
+import dev.fitko.fitconnect.api.services.schema.SchemaProvider;
+import dev.fitko.fitconnect.api.services.validation.ValidationService;
+
+import java.util.List;
+
+public interface ValidationServiceProvider {
+        ValidationService create(ApplicationConfig config, SchemaProvider schemaProvider, MessageDigestService messageDigestService, List<String> trustedRootCertificates);
+}
diff --git a/client/src/main/java/dev/fitko/fitconnect/client/bootstrap/ClientFactory.java b/client/src/main/java/dev/fitko/fitconnect/client/bootstrap/ClientFactory.java
index bd1aa7d55..1bce83805 100644
--- a/client/src/main/java/dev/fitko/fitconnect/client/bootstrap/ClientFactory.java
+++ b/client/src/main/java/dev/fitko/fitconnect/client/bootstrap/ClientFactory.java
@@ -26,6 +26,7 @@ import dev.fitko.fitconnect.api.services.routing.RoutingService;
 import dev.fitko.fitconnect.api.services.schema.SchemaProvider;
 import dev.fitko.fitconnect.api.services.submission.SubmissionService;
 import dev.fitko.fitconnect.api.services.validation.ValidationService;
+import dev.fitko.fitconnect.api.spi.ValidationServiceProvider;
 import dev.fitko.fitconnect.client.RouterClient;
 import dev.fitko.fitconnect.client.SenderClient;
 import dev.fitko.fitconnect.client.SubscriberClient;
@@ -60,7 +61,6 @@ import dev.fitko.fitconnect.core.routing.RouteVerifier;
 import dev.fitko.fitconnect.core.routing.RoutingApiService;
 import dev.fitko.fitconnect.core.schema.SchemaResourceProvider;
 import dev.fitko.fitconnect.core.submission.SubmissionApiService;
-import dev.fitko.fitconnect.core.validation.DefaultValidationService;
 import okhttp3.Interceptor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -200,7 +200,8 @@ public final class ClientFactory {
                 .map(RessourceLoadingUtils::readResourceToString)
                 .collect(Collectors.toList());
         LOGGER.info("Initialised trusted root certificates");
-        return new DefaultValidationService(config, messageDigestService, schemaProvider, trustedRootCertificates);
+        final ValidationServiceProvider validationServiceProvider = ProviderUtil.provider(ProviderUtil.DEFAULT_PROVIDER);
+        return validationServiceProvider.create(config, schemaProvider, messageDigestService, trustedRootCertificates);
     }
 
     private static HttpClient createHttpClient(final ApplicationConfig config) {
diff --git a/client/src/main/java/dev/fitko/fitconnect/client/bootstrap/ProviderUtil.java b/client/src/main/java/dev/fitko/fitconnect/client/bootstrap/ProviderUtil.java
new file mode 100644
index 000000000..3a3f8eb4e
--- /dev/null
+++ b/client/src/main/java/dev/fitko/fitconnect/client/bootstrap/ProviderUtil.java
@@ -0,0 +1,20 @@
+package dev.fitko.fitconnect.client.bootstrap;
+
+import dev.fitko.fitconnect.api.spi.ValidationServiceProvider;
+
+import java.util.ServiceLoader;
+
+public final class ProviderUtil {
+
+    public static final String DEFAULT_PROVIDER = "dev.fitko.fitconnect.client.bootstrap.spi.DefaultValidationServiceProvider";
+
+    public static ValidationServiceProvider provider(String providerName) {
+        ServiceLoader<ValidationServiceProvider> loader = ServiceLoader.load(ValidationServiceProvider.class);
+        for (ValidationServiceProvider provider : loader) {
+            if (providerName.equals(provider.getClass().getName())) {
+                return provider;
+            }
+        }
+        throw new RuntimeException("ValidationService provider " + providerName + " not found");
+    }
+}
diff --git a/client/src/main/java/dev/fitko/fitconnect/client/bootstrap/spi/DefaultValidationServiceProvider.java b/client/src/main/java/dev/fitko/fitconnect/client/bootstrap/spi/DefaultValidationServiceProvider.java
new file mode 100644
index 000000000..0e79315f1
--- /dev/null
+++ b/client/src/main/java/dev/fitko/fitconnect/client/bootstrap/spi/DefaultValidationServiceProvider.java
@@ -0,0 +1,18 @@
+package dev.fitko.fitconnect.client.bootstrap.spi;
+
+import dev.fitko.fitconnect.api.config.ApplicationConfig;
+import dev.fitko.fitconnect.api.services.crypto.MessageDigestService;
+import dev.fitko.fitconnect.api.services.schema.SchemaProvider;
+import dev.fitko.fitconnect.api.services.validation.ValidationService;
+import dev.fitko.fitconnect.api.spi.ValidationServiceProvider;
+import dev.fitko.fitconnect.core.validation.DefaultValidationService;
+
+import java.util.List;
+
+public class DefaultValidationServiceProvider implements ValidationServiceProvider {
+
+    @Override
+    public ValidationService create(ApplicationConfig config, SchemaProvider schemaProvider, MessageDigestService messageDigestService, List<String> trustedRootCertificates) {
+        return new DefaultValidationService(config, messageDigestService, schemaProvider, trustedRootCertificates);
+    }
+}
diff --git a/client/src/main/java/dev/fitko/fitconnect/client/bootstrap/spi/SkipValidationServiceProvider.java b/client/src/main/java/dev/fitko/fitconnect/client/bootstrap/spi/SkipValidationServiceProvider.java
new file mode 100644
index 000000000..1c298c80c
--- /dev/null
+++ b/client/src/main/java/dev/fitko/fitconnect/client/bootstrap/spi/SkipValidationServiceProvider.java
@@ -0,0 +1,101 @@
+package dev.fitko.fitconnect.client.bootstrap.spi;
+
+import com.nimbusds.jose.jwk.KeyOperation;
+import com.nimbusds.jose.jwk.RSAKey;
+import dev.fitko.fitconnect.api.config.ApplicationConfig;
+import dev.fitko.fitconnect.api.domain.model.destination.Destination;
+import dev.fitko.fitconnect.api.domain.model.event.authtags.AuthenticationTags;
+import dev.fitko.fitconnect.api.domain.model.metadata.Metadata;
+import dev.fitko.fitconnect.api.domain.model.metadata.attachment.AttachmentForValidation;
+import dev.fitko.fitconnect.api.domain.model.reply.Reply;
+import dev.fitko.fitconnect.api.domain.model.submission.Submission;
+import dev.fitko.fitconnect.api.domain.validation.ValidationResult;
+import dev.fitko.fitconnect.api.services.crypto.MessageDigestService;
+import dev.fitko.fitconnect.api.services.schema.SchemaProvider;
+import dev.fitko.fitconnect.api.services.validation.ValidationService;
+import dev.fitko.fitconnect.api.spi.ValidationServiceProvider;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Returns ValidationResult.ok() for all validations
+ */
+public class SkipValidationServiceProvider implements ValidationServiceProvider {
+    @Override
+    public ValidationService create(ApplicationConfig config, SchemaProvider schemaProvider, MessageDigestService messageDigestService, List<String> trustedRootCertificates) {
+        return new ValidationService() {
+            @Override
+            public ValidationResult validatePublicKey(RSAKey publicKey, KeyOperation keyOperation) {
+                return ValidationResult.ok();
+            }
+
+            @Override
+            public ValidationResult validateMetadataSchema(Metadata metadata) {
+                return ValidationResult.ok();
+            }
+
+            @Override
+            public ValidationResult validateSubmissionMetadata(Metadata metadata, Submission submission, Destination destination, AuthenticationTags eventAuthenticationTags) {
+                return ValidationResult.ok();
+            }
+
+            @Override
+            public ValidationResult validateReplyMetadata(Metadata metadata, Reply reply, Destination destination, AuthenticationTags eventAuthenticationTags) {
+                return ValidationResult.ok();
+            }
+
+            @Override
+            public ValidationResult validateAttachments(List<AttachmentForValidation> attachmentsForValidation, AuthenticationTags authenticationTags) {
+                return ValidationResult.ok();
+            }
+
+            @Override
+            public ValidationResult validateData(byte[] decryptedData, String encryptedData, Metadata metadata, String eventAuthenticationTags) {
+                return ValidationResult.ok();
+            }
+
+            @Override
+            public ValidationResult validateSetEventSchema(String setEventPayload) {
+                return ValidationResult.ok();
+            }
+
+            @Override
+            public ValidationResult validateDestinationSchema(Map<String, Object> destinationPayload) {
+                return ValidationResult.ok();
+            }
+
+            @Override
+            public ValidationResult validateHashIntegrity(String originalHexHash, byte[] data) {
+                return ValidationResult.ok();
+            }
+
+            @Override
+            public ValidationResult validateHashIntegrity(String originalHexHash, InputStream inputStream) {
+                return ValidationResult.ok();
+            }
+
+            @Override
+            public ValidationResult validateSubmissionDataSchema(String json, URI schemaUri) {
+                return ValidationResult.ok();
+            }
+
+            @Override
+            public ValidationResult validateJsonFormat(String json) {
+                return ValidationResult.ok();
+            }
+
+            @Override
+            public ValidationResult validateXmlFormat(String xml) {
+                return ValidationResult.ok();
+            }
+
+            @Override
+            public ValidationResult validateCallback(String hmac, Long timestampInSeconds, String httpBody, String callbackSecret) {
+                return ValidationResult.ok();
+            }
+        };
+    }
+}
diff --git a/client/src/main/resources/META-INF/services/dev.fitko.fitconnect.api.spi.ValidationServiceProvider b/client/src/main/resources/META-INF/services/dev.fitko.fitconnect.api.spi.ValidationServiceProvider
new file mode 100644
index 000000000..7cc9bc55e
--- /dev/null
+++ b/client/src/main/resources/META-INF/services/dev.fitko.fitconnect.api.spi.ValidationServiceProvider
@@ -0,0 +1,6 @@
+dev.fitko.fitconnect.client.bootstrap.spi.DefaultValidationServiceProvider
+dev.fitko.fitconnect.client.bootstrap.spi.SkipValidationServiceProvider
+
+
+
+
-- 
GitLab