From b134813998d7f717c232f1d4fb3f8dc3b9b9fecd Mon Sep 17 00:00:00 2001
From: Martin Vogel <martin.vogel@sinc.de>
Date: Fri, 17 Jun 2022 14:26:01 +0200
Subject: [PATCH] #414 Refactor subscriber client and add step interfaces

---
 .../fitko/fitconnect/api/services/Sender.java | 13 ++-
 .../fitconnect/api/services/Subscriber.java   | 23 +++--
 .../java/de/fitko/fitconnect/TestRunner.java  | 27 +++++-
 .../fitko/fitconnect/client/SenderClient.java | 14 +--
 .../fitconnect/client/SubscriberClient.java   | 92 +++++++++++++++----
 .../fitconnect/impl/SubmissionSender.java     |  2 +-
 .../fitconnect/impl/SubmissionSubscriber.java |  8 +-
 7 files changed, 130 insertions(+), 49 deletions(-)

diff --git a/api/src/main/java/de/fitko/fitconnect/api/services/Sender.java b/api/src/main/java/de/fitko/fitconnect/api/services/Sender.java
index 2f5ef4aee..d9ba7a1e3 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/services/Sender.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/services/Sender.java
@@ -68,16 +68,19 @@ public interface Sender {
     Optional<Metadata> createMetadata(final Data data, final List<Attachment> attachments);
 
     /**
+     * Creates and announces a new {@link Submission}
      *
-     * @param submission
-     * @return
+     * @param submission with a destinationId, a list of attachmentIds and a serviceType
+     * @return the created submission
      */
     Optional<Submission> createSubmission(Submission submission);
 
     /**
+     * Posts the announced {@link Submission}
+     * @param submissionId identifier of the announced submission
+     * @param metadata the encrypted metadata
      *
-     * @param submission
-     * @return
+     * @return the submission
      */
-    Optional<Submission> sendSubmission(Submission submission);
+    Optional<Submission> sendSubmission(String submissionId, Metadata metadata);
 }
diff --git a/api/src/main/java/de/fitko/fitconnect/api/services/Subscriber.java b/api/src/main/java/de/fitko/fitconnect/api/services/Subscriber.java
index 9358d6ba2..9dd45d25a 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/services/Subscriber.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/services/Subscriber.java
@@ -9,6 +9,7 @@ import de.fitko.fitconnect.api.domain.model.event.SecurityEventToken;
 import de.fitko.fitconnect.api.domain.model.submission.Submission;
 import de.fitko.fitconnect.api.domain.validation.ValidationResult;
 
+import java.util.List;
 import java.util.Optional;
 
 /**
@@ -65,21 +66,27 @@ public interface Subscriber {
     ValidationResult validateMetadataHashValues(final Metadata metadata);
 
     /**
+     * Polls for available {@link Submission}s on the given destinationId
      *
-     * @param submissionId
-     * @param attachmentId
-     * @return
+     * @param destinationId restricts the query to a specific destination
+     * @param limit number of submissions in result (max. is 500)
+     * @param offset position in the dataset
      *
+     * @return list of found submissions
      */
-    Optional<Submission> getSubmission(String submissionId, String attachmentId);
+    List<Submission> pollAvailableSubmissions(String destinationId, int limit, int offset);
 
     /**
+     * Gets a specific {@link Submission}.
+     *
+     * @param submissionId the unique identifier of a {@link Submission}
+     *
+     * @return the optional submission, is empty if none was found
      *
-     * @param data
-     * @param attachment
-     * @param privateKey
-     * @return
      */
+    Optional<Submission> getSubmission(String submissionId);
+
+
     Optional<SecurityEventToken> createSecurityEventToken(Data data, Attachment attachment, RSAKey privateKey);
 
 }
diff --git a/client/src/main/java/de/fitko/fitconnect/TestRunner.java b/client/src/main/java/de/fitko/fitconnect/TestRunner.java
index 029a25693..ec74ce06d 100644
--- a/client/src/main/java/de/fitko/fitconnect/TestRunner.java
+++ b/client/src/main/java/de/fitko/fitconnect/TestRunner.java
@@ -7,6 +7,7 @@ import de.fitko.fitconnect.client.SenderClient;
 import de.fitko.fitconnect.client.SubscriberClient;
 
 import java.util.Collections;
+import java.util.List;
 import java.util.Optional;
 
 public class TestRunner {
@@ -16,15 +17,35 @@ public class TestRunner {
         var clientId = "781f6213-0f0f-4a79-9372-e7187ffda98b";
         var secret = "PnzR8Vbmhpv_VwTkT34wponqXWK8WBm-LADlryYdV4o";
 
-        // sample calls to the fluent sender client
+        senderSample(clientId, secret);
+        subscriberSample(clientId, secret);
+    }
+
+    private static void senderSample(String clientId, String secret) {
         final Optional<Submission> sentSubmission =  SenderClient.builder()
                 .authenticate(clientId, secret)
                 .createSubmission(Submission.builder().build())
                 .uploadAttachments(Collections.emptyList())
                 .sendSubmission(Metadata.builder().build(), Data.builder().build());
+    }
+
+    private static void subscriberSample(String clientId, String secret) {
+        // #1 authenticate
+        var authenticatedClient = SubscriberClient.builder().authenticate(clientId, secret);
+
+        // #2 poll for available submissions
+        List<Submission> availableSubmissions = authenticatedClient.getAvailableSubmissions("someDestinationId");
+
+        // #3 get a submission and its data
+        var confirmedSubmission = authenticatedClient
+                .requestSubmission(Submission.builder().build())
+                .requestMetadata()
+                .requestAttachments()
+                .confirmSubmission();
 
-        SubscriberClient.builder()
-                .authenticate(clientId, secret);
+        // access request submission data
+        var attachments = confirmedSubmission.getAttachments();
+        var metadata = confirmedSubmission.getMetadata();
 
     }
 
diff --git a/client/src/main/java/de/fitko/fitconnect/client/SenderClient.java b/client/src/main/java/de/fitko/fitconnect/client/SenderClient.java
index dde2aca18..ebadcbcf3 100644
--- a/client/src/main/java/de/fitko/fitconnect/client/SenderClient.java
+++ b/client/src/main/java/de/fitko/fitconnect/client/SenderClient.java
@@ -8,7 +8,6 @@ import de.fitko.fitconnect.api.domain.model.submission.Submission;
 import de.fitko.fitconnect.api.exceptions.client.AttachmentUploadError;
 import de.fitko.fitconnect.api.exceptions.client.ClientNotAuthenticated;
 import de.fitko.fitconnect.api.services.Sender;
-import de.fitko.fitconnect.api.services.metadata.MetadataService;
 
 import java.util.List;
 import java.util.Optional;
@@ -21,9 +20,7 @@ public class SenderClient extends Client {
     private SenderClient() {}
 
      public static Authenticate builder() {
-         final Sender sender = getService(Sender.class);
-         final MetadataService metadataService = getService(MetadataService.class);
-         return new ClientBuilder(sender, metadataService);
+         return new ClientBuilder(getService(Sender.class));
     }
 
     public interface Authenticate {
@@ -78,13 +75,11 @@ public class SenderClient extends Client {
 
     public static class ClientBuilder implements Authenticate, AttachmentUpload, CreateSubmission, SendSubmission {
 
-        private final MetadataService metadataService;
         private Sender sender;
         private Optional<OAuthToken> token;
 
-        private ClientBuilder(Sender sender, MetadataService metadataService) {
+        private ClientBuilder(Sender sender) {
             this.sender = sender;
-            this.metadataService = metadataService;
         }
 
         @Override
@@ -96,20 +91,17 @@ public class SenderClient extends Client {
 
         @Override
         public SendSubmission uploadAttachments(List<Attachment> attachments) {
-            checkIfAuthenticated();
             return this;
         }
 
         @Override
         public AttachmentUpload createSubmission(Submission submission) {
-            checkIfAuthenticated();
             return this;
         }
 
         @Override
         public Optional<Submission> sendSubmission(Metadata metaData, Data data) {
-            checkIfAuthenticated();
-            return sender.sendSubmission(Submission.builder().build());
+            throw new UnsupportedOperationException("not yet implemented");
         }
 
         private void checkIfAuthenticated(){
diff --git a/client/src/main/java/de/fitko/fitconnect/client/SubscriberClient.java b/client/src/main/java/de/fitko/fitconnect/client/SubscriberClient.java
index 6b556c1c0..7faaa4d01 100644
--- a/client/src/main/java/de/fitko/fitconnect/client/SubscriberClient.java
+++ b/client/src/main/java/de/fitko/fitconnect/client/SubscriberClient.java
@@ -1,8 +1,13 @@
 package de.fitko.fitconnect.client;
 
 import de.fitko.fitconnect.api.domain.auth.OAuthToken;
+import de.fitko.fitconnect.api.domain.model.metadata.Metadata;
+import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
+import de.fitko.fitconnect.api.domain.model.submission.Submission;
 import de.fitko.fitconnect.api.services.Subscriber;
 
+import java.util.Collections;
+import java.util.List;
 import java.util.Optional;
 
 /**
@@ -18,23 +23,41 @@ public class SubscriberClient extends Client {
     }
 
     public interface Authenticate {
-        /**
-         *
-         * @param clientId
-         * @param secret
-         * @param scope
-         * @return
-         */
-        AttachmentUpload authenticate(String clientId, String secret, String... scope);
+        PollSubmissions authenticate(String clientId, String secret, String... scope);
     }
 
-    public interface AttachmentUpload {
-        void uploadAttachments();
+    public interface PollSubmissions {
+
+        List<Submission> getAvailableSubmissions(String destinationId);
+        RequestMetadata requestSubmission(Submission submission);
+    }
+
+    public interface RequestMetadata {
+        RequestAttachments requestMetadata();
+    }
+
+    public interface  RequestAttachments {
+        ConfirmSubmission requestAttachments();
+    }
+
+    public interface ConfirmSubmission {
+        AccessData confirmSubmission();
+    }
+
+    public interface AccessData {
+        Submission getSubmission();
+        List<Attachment> getAttachments();
+        Metadata getMetadata();
     }
 
-    public static class ClientBuilder implements Authenticate, AttachmentUpload{
 
-        private Subscriber subscriber;
+    public static class ClientBuilder implements Authenticate, PollSubmissions, RequestMetadata, RequestAttachments, ConfirmSubmission, AccessData {
+
+        private final Subscriber subscriber;
+
+        private Optional<Submission> submission = Optional.empty();
+        private Optional<Metadata> metadata = Optional.empty();
+        private List<Attachment> attachments = Collections.emptyList();
         private Optional<OAuthToken> token;
 
         private ClientBuilder(Subscriber subscriber) {
@@ -42,21 +65,50 @@ public class SubscriberClient extends Client {
         }
 
         @Override
-        public AttachmentUpload authenticate(String clientId, String secret, String... scope) {
+        public PollSubmissions authenticate(String clientId, String secret, String... scope) {
             this.token = subscriber.retrieveOAuthToken(clientId, secret, scope);
             return this;
         }
 
         @Override
-        public void uploadAttachments() {
-            checkIfAuthenticated();
-            //metadataService.createMetadata();
+        public List<Submission> getAvailableSubmissions(String destinationId) {
+            throw new UnsupportedOperationException("not yet implemented");
+        }
+
+        @Override
+        public RequestMetadata requestSubmission(Submission submission) {
+            throw new UnsupportedOperationException("not yet implemented");
         }
 
-        private void checkIfAuthenticated(){
-            if(this.token == null || this.token.isEmpty()){
-                throw new IllegalStateException("Not authenticated, please authenticate first");
-            }
+
+        @Override
+        public RequestAttachments requestMetadata() {
+            throw new UnsupportedOperationException("not yet implemented");
+        }
+
+        @Override
+        public ConfirmSubmission requestAttachments() {
+            throw new UnsupportedOperationException("not yet implemented");
+        }
+
+        @Override
+        public AccessData confirmSubmission() {
+            throw new UnsupportedOperationException("not yet implemented");
+        }
+
+        @Override
+        public Submission getSubmission() {
+            return this.submission.orElseThrow();
+        }
+
+        @Override
+        public List<Attachment> getAttachments() {
+            return this.attachments;
+        }
+
+        @Override
+        public Metadata getMetadata() {
+            return this.metadata.orElseThrow();
         }
     }
 }
\ No newline at end of file
diff --git a/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSender.java b/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSender.java
index 250e8d77e..ed9e91748 100644
--- a/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSender.java
+++ b/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSender.java
@@ -79,7 +79,7 @@ public class SubmissionSender implements Sender {
     }
 
     @Override
-    public Optional<Submission> sendSubmission(Submission submission) {
+    public Optional<Submission> sendSubmission(String submissionId, Metadata metadata) {
         throw new UnsupportedOperationException("not yet implemented");
     }
 }
diff --git a/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSubscriber.java b/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSubscriber.java
index b76f2df7a..2faf8217e 100644
--- a/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSubscriber.java
+++ b/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSubscriber.java
@@ -17,6 +17,7 @@ import de.fitko.fitconnect.api.services.validation.MetadataValidator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.List;
 import java.util.Optional;
 
 
@@ -68,7 +69,12 @@ public class SubmissionSubscriber implements Subscriber {
     }
 
     @Override
-    public Optional<Submission> getSubmission(String submissionId, String attachmentId) {
+    public List<Submission> pollAvailableSubmissions(String destinationId, int limit, int offset) {
+        throw new UnsupportedOperationException("not yet implemented");
+    }
+
+    @Override
+    public Optional<Submission> getSubmission(String submissionId) {
         throw new UnsupportedOperationException("not yet implemented");
     }
 
-- 
GitLab