From 8abbd141fc4c6e02a30d465fc7d5c96000b3532d Mon Sep 17 00:00:00 2001
From: Martin Vogel <martin.vogel@sinc.de>
Date: Thu, 16 Jun 2022 22:37:17 +0200
Subject: [PATCH] #414 Refactor client and add documentation to the step
 interfaces

---
 api/README.md                                 | 17 ++---
 .../client/AttachmentUploadError.java         | 14 ++++
 .../client/ClientNotAuthenticated.java        | 11 +++
 .../client/SubmissionCreationError.java       | 13 ++++
 .../client/SubmissionSendError.java           | 13 ++++
 .../AuthenticationException.java              |  2 +-
 .../{ => internal}/DecryptionException.java   |  2 +-
 .../{ => internal}/EncryptionException.java   |  2 +-
 .../InitializationException.java              |  2 +-
 .../api/schema/FitConnectSchemaScopes.java    | 27 --------
 .../fitko/fitconnect/api/services/Sender.java |  9 ++-
 .../fitconnect/api/services/Subscriber.java   |  1 +
 .../api/services/auth/OAuthService.java       |  2 +-
 .../api/services/crypto/CryptoService.java    |  4 +-
 .../services/metadata/MetadataService.java    |  2 +-
 .../java/de/fitko/fitconnect/TestRunner.java  |  8 ++-
 .../de/fitko/fitconnect/client/Client.java    | 14 ++++
 .../fitko/fitconnect/client/SenderClient.java | 68 +++++++++++++------
 .../fitconnect/client/SubscriberClient.java   |  9 +--
 .../fitconnect/impl/SubmissionSender.java     | 13 +++-
 .../fitconnect/impl/SubmissionSubscriber.java |  2 +-
 .../impl/auth/DefaultOAuthService.java        |  2 +-
 .../impl/crypto/JWECryptoService.java         |  4 +-
 .../impl/crypto/MetadataVerifier.java         |  2 +-
 24 files changed, 160 insertions(+), 83 deletions(-)
 create mode 100644 api/src/main/java/de/fitko/fitconnect/api/exceptions/client/AttachmentUploadError.java
 create mode 100644 api/src/main/java/de/fitko/fitconnect/api/exceptions/client/ClientNotAuthenticated.java
 create mode 100644 api/src/main/java/de/fitko/fitconnect/api/exceptions/client/SubmissionCreationError.java
 create mode 100644 api/src/main/java/de/fitko/fitconnect/api/exceptions/client/SubmissionSendError.java
 rename api/src/main/java/de/fitko/fitconnect/api/exceptions/{ => internal}/AuthenticationException.java (82%)
 rename api/src/main/java/de/fitko/fitconnect/api/exceptions/{ => internal}/DecryptionException.java (85%)
 rename api/src/main/java/de/fitko/fitconnect/api/exceptions/{ => internal}/EncryptionException.java (86%)
 rename api/src/main/java/de/fitko/fitconnect/api/exceptions/{ => internal}/InitializationException.java (84%)
 delete mode 100644 api/src/main/java/de/fitko/fitconnect/api/schema/FitConnectSchemaScopes.java
 create mode 100644 client/src/main/java/de/fitko/fitconnect/client/Client.java

diff --git a/api/README.md b/api/README.md
index 7f725bc41..c2be5e509 100644
--- a/api/README.md
+++ b/api/README.md
@@ -66,21 +66,22 @@ classDiagram
     + validateMetadataSchema
     + validateMetadataHashValues
   }
-
-  class SenderClient{
-        Sender
-  }
   
-   class SubscriberClient{
+  class SubscriberClient{
         Subscriber
   }
   
-  class SdkClientFactory {
+  class SenderClient{
+        Sender
+  }
+  
+    class AbstractClient {
         SdkModule (Guice DI)
   }
+  
 
-SdkClientFactory  ..> SenderClient : Creates
-SdkClientFactory  ..> SubscriberClient : Creates
+AbstractClient  <.. SenderClient : IsA
+AbstractClient  <.. SubscriberClient : IsA
 
 SenderClient ..> Sender : Uses
 SubscriberClient ..> Subscriber : Uses
diff --git a/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/AttachmentUploadError.java b/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/AttachmentUploadError.java
new file mode 100644
index 000000000..3843c9eb0
--- /dev/null
+++ b/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/AttachmentUploadError.java
@@ -0,0 +1,14 @@
+package de.fitko.fitconnect.api.exceptions.client;
+
+import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
+import de.fitko.fitconnect.api.domain.model.submission.Submission;
+
+/**
+ * Error during upload of the {@link Submission}s {@link Attachment}s
+ */
+public class AttachmentUploadError extends RuntimeException {
+
+    public AttachmentUploadError(String errorMessage) {
+        super(errorMessage);
+    }
+}
diff --git a/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/ClientNotAuthenticated.java b/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/ClientNotAuthenticated.java
new file mode 100644
index 000000000..f90c48a3e
--- /dev/null
+++ b/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/ClientNotAuthenticated.java
@@ -0,0 +1,11 @@
+package de.fitko.fitconnect.api.exceptions.client;
+
+/**
+ * Error during the authentication process of the client
+ */
+public class ClientNotAuthenticated extends RuntimeException {
+
+    public ClientNotAuthenticated(String errorMessage) {
+        super(errorMessage);
+    }
+}
diff --git a/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/SubmissionCreationError.java b/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/SubmissionCreationError.java
new file mode 100644
index 000000000..2074888d4
--- /dev/null
+++ b/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/SubmissionCreationError.java
@@ -0,0 +1,13 @@
+package de.fitko.fitconnect.api.exceptions.client;
+
+import de.fitko.fitconnect.api.domain.model.submission.Submission;
+
+/**
+ * Error during the creation process of a {@link Submission}
+ */
+public class SubmissionCreationError extends RuntimeException {
+
+    public SubmissionCreationError(String errorMessage) {
+        super(errorMessage);
+    }
+}
diff --git a/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/SubmissionSendError.java b/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/SubmissionSendError.java
new file mode 100644
index 000000000..6d0ea812c
--- /dev/null
+++ b/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/SubmissionSendError.java
@@ -0,0 +1,13 @@
+package de.fitko.fitconnect.api.exceptions.client;
+
+import de.fitko.fitconnect.api.domain.model.submission.Submission;
+
+/**
+ * Error during the creation process of a {@link Submission}
+ */
+public class SubmissionSendError extends RuntimeException {
+
+    public SubmissionSendError(String errorMessage) {
+        super(errorMessage);
+    }
+}
diff --git a/api/src/main/java/de/fitko/fitconnect/api/exceptions/AuthenticationException.java b/api/src/main/java/de/fitko/fitconnect/api/exceptions/internal/AuthenticationException.java
similarity index 82%
rename from api/src/main/java/de/fitko/fitconnect/api/exceptions/AuthenticationException.java
rename to api/src/main/java/de/fitko/fitconnect/api/exceptions/internal/AuthenticationException.java
index f2cf92a23..6ae103a95 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/exceptions/AuthenticationException.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/exceptions/internal/AuthenticationException.java
@@ -1,4 +1,4 @@
-package de.fitko.fitconnect.api.exceptions;
+package de.fitko.fitconnect.api.exceptions.internal;
 
 /**
  * An error that occurred during the OAuth authentication
diff --git a/api/src/main/java/de/fitko/fitconnect/api/exceptions/DecryptionException.java b/api/src/main/java/de/fitko/fitconnect/api/exceptions/internal/DecryptionException.java
similarity index 85%
rename from api/src/main/java/de/fitko/fitconnect/api/exceptions/DecryptionException.java
rename to api/src/main/java/de/fitko/fitconnect/api/exceptions/internal/DecryptionException.java
index 43bfc7a39..eea8127d6 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/exceptions/DecryptionException.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/exceptions/internal/DecryptionException.java
@@ -1,4 +1,4 @@
-package de.fitko.fitconnect.api.exceptions;
+package de.fitko.fitconnect.api.exceptions.internal;
 
 /**
  * An error that occurred decrypting data or attachments
diff --git a/api/src/main/java/de/fitko/fitconnect/api/exceptions/EncryptionException.java b/api/src/main/java/de/fitko/fitconnect/api/exceptions/internal/EncryptionException.java
similarity index 86%
rename from api/src/main/java/de/fitko/fitconnect/api/exceptions/EncryptionException.java
rename to api/src/main/java/de/fitko/fitconnect/api/exceptions/internal/EncryptionException.java
index eba2e516f..43cdf2bf4 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/exceptions/EncryptionException.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/exceptions/internal/EncryptionException.java
@@ -1,4 +1,4 @@
-package de.fitko.fitconnect.api.exceptions;
+package de.fitko.fitconnect.api.exceptions.internal;
 
 /**
  * An error that occurred whilst encrypting data or attachments
diff --git a/api/src/main/java/de/fitko/fitconnect/api/exceptions/InitializationException.java b/api/src/main/java/de/fitko/fitconnect/api/exceptions/internal/InitializationException.java
similarity index 84%
rename from api/src/main/java/de/fitko/fitconnect/api/exceptions/InitializationException.java
rename to api/src/main/java/de/fitko/fitconnect/api/exceptions/internal/InitializationException.java
index 3f042876b..02d40fe75 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/exceptions/InitializationException.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/exceptions/internal/InitializationException.java
@@ -1,4 +1,4 @@
-package de.fitko.fitconnect.api.exceptions;
+package de.fitko.fitconnect.api.exceptions.internal;
 
 public class InitializationException extends RuntimeException {
 
diff --git a/api/src/main/java/de/fitko/fitconnect/api/schema/FitConnectSchemaScopes.java b/api/src/main/java/de/fitko/fitconnect/api/schema/FitConnectSchemaScopes.java
deleted file mode 100644
index aa1cd451e..000000000
--- a/api/src/main/java/de/fitko/fitconnect/api/schema/FitConnectSchemaScopes.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package de.fitko.fitconnect.api.schema;
-
-public final class FitConnectSchemaScopes {
-
-    // Schema-Basis-URI für alle Services
-    private static final String BASE_URI = "https://schema.fitko.de/fit-connect";
-
-    // Events sind nicht API-spezifisch
-    public static final String EVENTS_BASE_URI = BASE_URI + "/events/";
-
-    // API-spezifische Schema-Basis-URI
-    private static final String API_BASE_URI = BASE_URI + "/submission-api";
-
-    // Callbacks sind API-spezifisch
-    public static final String CALLBACKS_BASE_URI = API_BASE_URI + "/callbacks/";
-
-    // Problems sind API-spezifisch
-    public static final String PROBLEMS_BASE_URI = API_BASE_URI + "/problems/";
-
-    // API-spezifische Schema-Basis-URI
-    private static final String SET_BASE_URI = BASE_URI + "/set-payload";
-
-    // static class only for constants
-    private FitConnectSchemaScopes() {
-    }
-}
-
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 8caa21758..2f5ef4aee 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
@@ -72,5 +72,12 @@ public interface Sender {
      * @param submission
      * @return
      */
-    Submission sendSubmission(Submission submission);
+    Optional<Submission> createSubmission(Submission submission);
+
+    /**
+     *
+     * @param submission
+     * @return
+     */
+    Optional<Submission> sendSubmission(Submission submission);
 }
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 2f8051ee8..9358d6ba2 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
@@ -69,6 +69,7 @@ public interface Subscriber {
      * @param submissionId
      * @param attachmentId
      * @return
+     *
      */
     Optional<Submission> getSubmission(String submissionId, String attachmentId);
 
diff --git a/api/src/main/java/de/fitko/fitconnect/api/services/auth/OAuthService.java b/api/src/main/java/de/fitko/fitconnect/api/services/auth/OAuthService.java
index 665ffbb1e..7a1891586 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/services/auth/OAuthService.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/services/auth/OAuthService.java
@@ -2,7 +2,7 @@ package de.fitko.fitconnect.api.services.auth;
 
 import de.fitko.fitconnect.api.domain.auth.OAuthToken;
 import de.fitko.fitconnect.api.domain.model.submission.Submission;
-import de.fitko.fitconnect.api.exceptions.AuthenticationException;
+import de.fitko.fitconnect.api.exceptions.internal.AuthenticationException;
 
 /**
  * A Service that provides an interface to authenticate against the Fit-Connect API in order
diff --git a/api/src/main/java/de/fitko/fitconnect/api/services/crypto/CryptoService.java b/api/src/main/java/de/fitko/fitconnect/api/services/crypto/CryptoService.java
index 817626780..465fdbb77 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/services/crypto/CryptoService.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/services/crypto/CryptoService.java
@@ -4,8 +4,8 @@ import com.nimbusds.jose.jwk.RSAKey;
 import de.fitko.fitconnect.api.domain.model.metadata.data.Data;
 import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
 import de.fitko.fitconnect.api.domain.model.submission.Submission;
-import de.fitko.fitconnect.api.exceptions.DecryptionException;
-import de.fitko.fitconnect.api.exceptions.EncryptionException;
+import de.fitko.fitconnect.api.exceptions.internal.DecryptionException;
+import de.fitko.fitconnect.api.exceptions.internal.EncryptionException;
 
 /**
  * A service that allows to encrypt and decrypt {@link Data} and {@link Attachment}s of a {@link Submission} via JWE.
diff --git a/api/src/main/java/de/fitko/fitconnect/api/services/metadata/MetadataService.java b/api/src/main/java/de/fitko/fitconnect/api/services/metadata/MetadataService.java
index a27af31d8..e43dbca1b 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/services/metadata/MetadataService.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/services/metadata/MetadataService.java
@@ -12,7 +12,7 @@ import java.util.List;
  *
  * @see
  * <a href="https://docs.fitko.de/fit-connect/docs/metadataoverview">Metadata</a> and
- * <a href="https://docs.fitko.de/fit-connect/docs/getting-started/submission/structure">Strcuture of a submission</a>
+ * <a href="https://docs.fitko.de/fit-connect/docs/getting-started/submission/structure">Structure of a submission</a>
  */
 public interface MetadataService {
 
diff --git a/client/src/main/java/de/fitko/fitconnect/TestRunner.java b/client/src/main/java/de/fitko/fitconnect/TestRunner.java
index 5af802242..029a25693 100644
--- a/client/src/main/java/de/fitko/fitconnect/TestRunner.java
+++ b/client/src/main/java/de/fitko/fitconnect/TestRunner.java
@@ -6,6 +6,9 @@ import de.fitko.fitconnect.api.domain.model.submission.Submission;
 import de.fitko.fitconnect.client.SenderClient;
 import de.fitko.fitconnect.client.SubscriberClient;
 
+import java.util.Collections;
+import java.util.Optional;
+
 public class TestRunner {
 
     public static void main(String[] args) {
@@ -13,10 +16,11 @@ public class TestRunner {
         var clientId = "781f6213-0f0f-4a79-9372-e7187ffda98b";
         var secret = "PnzR8Vbmhpv_VwTkT34wponqXWK8WBm-LADlryYdV4o";
 
-        final Submission sentSubmission = SenderClient.builder()
+        // sample calls to the fluent sender client
+        final Optional<Submission> sentSubmission =  SenderClient.builder()
                 .authenticate(clientId, secret)
                 .createSubmission(Submission.builder().build())
-                .uploadAttachments()
+                .uploadAttachments(Collections.emptyList())
                 .sendSubmission(Metadata.builder().build(), Data.builder().build());
 
         SubscriberClient.builder()
diff --git a/client/src/main/java/de/fitko/fitconnect/client/Client.java b/client/src/main/java/de/fitko/fitconnect/client/Client.java
new file mode 100644
index 000000000..d066e8637
--- /dev/null
+++ b/client/src/main/java/de/fitko/fitconnect/client/Client.java
@@ -0,0 +1,14 @@
+package de.fitko.fitconnect.client;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import de.fitko.fitconnect.dependency.SdkModule;
+
+public abstract class Client {
+
+    private static final Injector injector = Guice.createInjector(new SdkModule());
+
+    static <T> T getService(Class<T> clazz){
+        return injector.getInstance(clazz);
+    }
+}
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 bf67f2773..dde2aca18 100644
--- a/client/src/main/java/de/fitko/fitconnect/client/SenderClient.java
+++ b/client/src/main/java/de/fitko/fitconnect/client/SenderClient.java
@@ -1,60 +1,85 @@
 package de.fitko.fitconnect.client;
 
-import com.google.inject.Guice;
-import com.google.inject.Injector;
 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.metadata.data.Data;
 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 de.fitko.fitconnect.dependency.SdkModule;
 
+import java.util.List;
 import java.util.Optional;
 
 /**
- * A fluent client for handing in a {@link Submission}
+ * A fluent client for announcing and handing in a {@link Submission}
  */
-public class SenderClient {
-
-    private static final Injector injector = Guice.createInjector(new SdkModule());
+public class SenderClient extends Client {
 
     private SenderClient() {}
 
      public static Authenticate builder() {
-         Sender sender = injector.getInstance(Sender.class);
-         MetadataService metadataService = injector.getInstance(MetadataService.class);
+         final Sender sender = getService(Sender.class);
+         final MetadataService metadataService = getService(MetadataService.class);
          return new ClientBuilder(sender, metadataService);
     }
 
     public interface Authenticate {
         /**
+         * Authenticates the client against the FitConnect-Auth-API and retrieves an {@link OAuthToken}.
+         *
+         * @param clientId a unique client identifier
+         * @param secret the applications secret key
+         * @param scope 1 or more client scopes that determine if a submission is accepted by the client
+         * @return the step for creating a new submission if the authentication was successful
          *
-         * @param clientId
-         * @param secret
-         * @param scope
-         * @return
+         * @throws ClientNotAuthenticated if the OAuth token could not be retrieved
          */
-        CreateSubmission authenticate(String clientId, String secret, String... scope);
+        CreateSubmission authenticate(String clientId, String secret, String... scope) throws ClientNotAuthenticated;
     }
 
     public interface AttachmentUpload {
-        SendSubmission uploadAttachments();
+        /**
+         * Encrypts and Uploads all {@link Attachment}s to the FitConnect-API
+         *
+         * @param attachments a list of attachments that are uploaded
+         * @return the step for sending the submission if the creating step was successful
+         *
+         * @throws ClientNotAuthenticated if the client is not authenticated
+         * @throws AttachmentUploadError if the upload failed
+         */
+        SendSubmission uploadAttachments(List<Attachment> attachments);
     }
 
     public interface CreateSubmission {
+        /**
+         * Creates and announces a new {@link Submission}
+         *
+         * @param submission the new {@link Submission} that should be created on server-side
+         * @return the step for upload the attachments if the creation was successful
+         */
         AttachmentUpload createSubmission(Submission submission);
     }
 
     public interface SendSubmission {
-        Submission sendSubmission(Metadata metaData, Data data);
+        /**
+         * Encrypts and uploads  the {@link Metadata} and {@link Data} and hands in the {@link Submission} at
+         * the defined destination-id.
+         *
+         * @param metaData the submissions {@link Metadata}
+         * @param data the submissions {@link Data}
+         *
+         * @return the finally uploaded and sent submission, empty if an error occurred
+         */
+        Optional<Submission> sendSubmission(Metadata metaData, Data data);
     }
 
     public static class ClientBuilder implements Authenticate, AttachmentUpload, CreateSubmission, SendSubmission {
 
         private final MetadataService metadataService;
         private Sender sender;
-        private Submission submission;
         private Optional<OAuthToken> token;
 
         private ClientBuilder(Sender sender, MetadataService metadataService) {
@@ -65,32 +90,31 @@ public class SenderClient {
         @Override
         public CreateSubmission authenticate(String clientId, String secret, String... scope) {
             this.token = sender.retrieveOAuthToken(clientId, secret, scope);
+            checkIfAuthenticated();
             return this;
         }
 
         @Override
-        public SendSubmission uploadAttachments() {
+        public SendSubmission uploadAttachments(List<Attachment> attachments) {
             checkIfAuthenticated();
-            //metadataService.createMetadata();
             return this;
         }
 
         @Override
         public AttachmentUpload createSubmission(Submission submission) {
             checkIfAuthenticated();
-            sender.sendSubmission(submission);
             return this;
         }
 
         @Override
-        public Submission sendSubmission(Metadata metaData, Data data) {
+        public Optional<Submission> sendSubmission(Metadata metaData, Data data) {
             checkIfAuthenticated();
             return sender.sendSubmission(Submission.builder().build());
         }
 
         private void checkIfAuthenticated(){
             if(this.token == null || this.token.isEmpty()){
-                throw new IllegalStateException("Not authenticated, please authenticate first");
+                throw new ClientNotAuthenticated("Not authenticated, please authenticate first");
             }
         }
     }
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 77f3c9973..6b556c1c0 100644
--- a/client/src/main/java/de/fitko/fitconnect/client/SubscriberClient.java
+++ b/client/src/main/java/de/fitko/fitconnect/client/SubscriberClient.java
@@ -1,24 +1,19 @@
 package de.fitko.fitconnect.client;
 
-import com.google.inject.Guice;
-import com.google.inject.Injector;
 import de.fitko.fitconnect.api.domain.auth.OAuthToken;
 import de.fitko.fitconnect.api.services.Subscriber;
-import de.fitko.fitconnect.dependency.SdkModule;
 
 import java.util.Optional;
 
 /**
  * A fluent client for handing in a subscription for a {@link Subscriber}
  */
-public class SubscriberClient {
-
-    private static final Injector injector = Guice.createInjector(new SdkModule());
+public class SubscriberClient extends Client {
 
     private SubscriberClient() {}
 
      public static Authenticate builder() {
-         Subscriber subscriber = injector.getInstance(Subscriber.class);
+         final Subscriber subscriber = getService(Subscriber.class);
          return new ClientBuilder(subscriber);
     }
 
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 a2ff79758..250e8d77e 100644
--- a/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSender.java
+++ b/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSender.java
@@ -8,7 +8,7 @@ import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
 import de.fitko.fitconnect.api.domain.model.metadata.data.Data;
 import de.fitko.fitconnect.api.domain.model.submission.Submission;
 import de.fitko.fitconnect.api.domain.validation.ValidationResult;
-import de.fitko.fitconnect.api.exceptions.AuthenticationException;
+import de.fitko.fitconnect.api.exceptions.internal.AuthenticationException;
 import de.fitko.fitconnect.api.services.Sender;
 import de.fitko.fitconnect.api.services.auth.OAuthService;
 import de.fitko.fitconnect.api.services.crypto.CryptoService;
@@ -59,7 +59,9 @@ public class SubmissionSender implements Sender {
     @Override
     public Optional<OAuthToken> retrieveOAuthToken(String clientId, String clientSecret, String... scope) {
         try {
-            return Optional.of(authService.authenticate(clientId, clientSecret, scope));
+            final OAuthToken token = authService.authenticate(clientId, clientSecret, scope);
+            logger.debug("successfully retrieved token {}", token.getAccessToken());
+            return Optional.of(token);
         } catch (AuthenticationException e) {
             logger.error("client could not be authenticated", e.getMessage());
             return Optional.empty();
@@ -72,7 +74,12 @@ public class SubmissionSender implements Sender {
     }
 
     @Override
-    public Submission sendSubmission(Submission submission) {
+    public Optional<Submission> createSubmission(Submission submission) {
+        throw new UnsupportedOperationException("not yet implemented");
+    }
+
+    @Override
+    public Optional<Submission> sendSubmission(Submission submission) {
         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 654082bd4..b76f2df7a 100644
--- a/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSubscriber.java
+++ b/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSubscriber.java
@@ -9,7 +9,7 @@ import de.fitko.fitconnect.api.domain.model.metadata.data.Data;
 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 de.fitko.fitconnect.api.exceptions.AuthenticationException;
+import de.fitko.fitconnect.api.exceptions.internal.AuthenticationException;
 import de.fitko.fitconnect.api.services.Subscriber;
 import de.fitko.fitconnect.api.services.auth.OAuthService;
 import de.fitko.fitconnect.api.services.crypto.CryptoService;
diff --git a/impl/src/main/java/de/fitko/fitconnect/impl/auth/DefaultOAuthService.java b/impl/src/main/java/de/fitko/fitconnect/impl/auth/DefaultOAuthService.java
index 07dc2707d..3d808799a 100644
--- a/impl/src/main/java/de/fitko/fitconnect/impl/auth/DefaultOAuthService.java
+++ b/impl/src/main/java/de/fitko/fitconnect/impl/auth/DefaultOAuthService.java
@@ -1,7 +1,7 @@
 package de.fitko.fitconnect.impl.auth;
 
 import de.fitko.fitconnect.api.domain.auth.OAuthToken;
-import de.fitko.fitconnect.api.exceptions.AuthenticationException;
+import de.fitko.fitconnect.api.exceptions.internal.AuthenticationException;
 import de.fitko.fitconnect.api.services.auth.OAuthService;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpHeaders;
diff --git a/impl/src/main/java/de/fitko/fitconnect/impl/crypto/JWECryptoService.java b/impl/src/main/java/de/fitko/fitconnect/impl/crypto/JWECryptoService.java
index 087ac0006..50353fc42 100644
--- a/impl/src/main/java/de/fitko/fitconnect/impl/crypto/JWECryptoService.java
+++ b/impl/src/main/java/de/fitko/fitconnect/impl/crypto/JWECryptoService.java
@@ -5,8 +5,8 @@ import com.nimbusds.jose.crypto.RSADecrypter;
 import com.nimbusds.jose.crypto.RSAEncrypter;
 import com.nimbusds.jose.jwk.RSAKey;
 import de.fitko.fitconnect.api.services.crypto.CryptoService;
-import de.fitko.fitconnect.api.exceptions.DecryptionException;
-import de.fitko.fitconnect.api.exceptions.EncryptionException;
+import de.fitko.fitconnect.api.exceptions.internal.DecryptionException;
+import de.fitko.fitconnect.api.exceptions.internal.EncryptionException;
 
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
diff --git a/impl/src/main/java/de/fitko/fitconnect/impl/crypto/MetadataVerifier.java b/impl/src/main/java/de/fitko/fitconnect/impl/crypto/MetadataVerifier.java
index 54e282890..192e99ed7 100644
--- a/impl/src/main/java/de/fitko/fitconnect/impl/crypto/MetadataVerifier.java
+++ b/impl/src/main/java/de/fitko/fitconnect/impl/crypto/MetadataVerifier.java
@@ -1,6 +1,6 @@
 package de.fitko.fitconnect.impl.crypto;
 
-import de.fitko.fitconnect.api.exceptions.InitializationException;
+import de.fitko.fitconnect.api.exceptions.internal.InitializationException;
 
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
-- 
GitLab