Skip to content
Snippets Groups Projects
Commit 02716fe8 authored by Martin Vogel's avatar Martin Vogel
Browse files

#414 Use WebClient to enable future async http calls

parent bbba7c7a
No related branches found
No related tags found
2 merge requests!2#414 Remaining changes from MR,!1planning#414 Methoden Signaturen (Zwischenstand)
/**
* This module is providing the internal sdk api
* <p>
*
* </p>
*
* @since 1.0
* @author FitConnect
* @version 1.0
*/
package fitconnect.api;
\ No newline at end of file
......@@ -8,7 +8,7 @@ import fitconnect.api.services.validation.CertificateValidator;
import fitconnect.api.services.validation.MetadataValidator;
import fitconnect.impl.SubmissionSender;
import fitconnect.impl.SubmissionSubscriber;
import fitconnect.impl.auth.FitCoAuthService;
import fitconnect.impl.auth.MonoPublisherOAuthService;
import fitconnect.impl.crypto.JWECryptoService;
import fitconnect.impl.validation.KeyValidator;
import fitconnect.impl.validation.MetadataSubmissionValidator;
......@@ -38,7 +38,7 @@ public class ClientFactory {
return new JWECryptoService();
}
private static FitCoAuthService getAuthService() {
return new FitCoAuthService(HttpClient.newHttpClient(), TOKEN_URL);
private static MonoPublisherOAuthService getAuthService() {
return new MonoPublisherOAuthService(TOKEN_URL);
}
}
......@@ -13,30 +13,30 @@ import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;
public class FitConnectClient {
public class SenderClient {
private static final Logger logger = SdkLogger.customLogger(FitConnectClient.class);
private static final Logger logger = SdkLogger.customLogger(SenderClient.class);
private final Sender sender;
private Optional<OAuthToken> token = Optional.empty();
public FitConnectClient(){
public SenderClient(){
this.sender = ClientFactory.submissionSender();
}
public FitConnectClient authenticate(String clientId, String secret, String...scope){
public SenderClient authenticate(String clientId, String secret, String...scope){
this.token = sender.retrieveOAuthToken(clientId,secret,scope);
return this;
}
public FitConnectClient createSubmission(final Submission submission){
public SenderClient createSubmission(final Submission submission){
checkIfAuthenticated();
// TODO implement sendSubmission
logger.log(Level.INFO, "created new submission");
return this;
}
public FitConnectClient sendSubmission(final Metadata metadata, final Data data){
public SenderClient sendSubmission(final Metadata metadata, final Data data){
checkIfAuthenticated();
// TODO implement
logger.log(Level.INFO, "successfully sent submission");
......@@ -44,14 +44,14 @@ public class FitConnectClient {
return this;
}
public FitConnectClient uploadAttachments(final List<Attachment> attachments){
public SenderClient uploadAttachments(final List<Attachment> attachments){
checkIfAuthenticated();
// TODO implement
logger.log(Level.INFO, "uploaded " + attachments.size() + " attachments");
return this;
}
public FitConnectClient printToken(){
public SenderClient printToken(){
checkIfAuthenticated();
logger.log(Level.INFO, "retrieved access token: " + this.token.get().getAccessToken());
return this;
......@@ -59,7 +59,7 @@ public class FitConnectClient {
private void checkIfAuthenticated() {
if(token.isEmpty()){
throw new IllegalStateException("not authenticated, please authenticate first with authenticate(client, secret)");
throw new IllegalStateException("not authenticated, please authenticate first");
}
}
......
......@@ -13,7 +13,7 @@ public class TestRunner {
var clientId = "781f6213-0f0f-4a79-9372-e7187ffda98b";
var secret = "PnzR8Vbmhpv_VwTkT34wponqXWK8WBm-LADlryYdV4o";
FitConnectClient client = new FitConnectClient();
SenderClient client = new SenderClient();
// sample high -level- api calls to send a submission
client.authenticate(clientId,secret)
......
......@@ -32,6 +32,10 @@
<groupId>com.github.erosb</groupId>
<artifactId>everit-json-schema</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
</dependencies>
......
......@@ -13,7 +13,7 @@ import fitconnect.api.exceptions.EncryptionException;
import fitconnect.impl.logger.SdkLogger;
import fitconnect.api.services.validation.CertificateValidator;
import fitconnect.api.domain.validation.ValidationResult;
import fitconnect.impl.auth.FitCoAuthService;
import fitconnect.impl.auth.MonoPublisherOAuthService;
import java.nio.charset.StandardCharsets;
import java.util.List;
......@@ -24,7 +24,7 @@ import java.util.logging.Logger;
public class SubmissionSender implements Sender {
private static final Logger logger = SdkLogger.defaultLogger(FitCoAuthService.class);
private static final Logger logger = SdkLogger.defaultLogger(MonoPublisherOAuthService.class);
private final OAuthService authService;
private final CertificateValidator certificateValidator;
......
......@@ -13,7 +13,7 @@ import fitconnect.api.exceptions.DecryptionException;
import fitconnect.impl.logger.SdkLogger;
import fitconnect.api.services.validation.MetadataValidator;
import fitconnect.api.domain.validation.ValidationResult;
import fitconnect.impl.auth.FitCoAuthService;
import fitconnect.impl.auth.MonoPublisherOAuthService;
import java.util.Optional;
import java.util.logging.Level;
......@@ -22,7 +22,7 @@ import java.util.logging.Logger;
public class SubmissionSubscriber implements Subscriber {
private static final Logger logger = SdkLogger.defaultLogger(FitCoAuthService.class);
private static final Logger logger = SdkLogger.defaultLogger(MonoPublisherOAuthService.class);
private final OAuthService authService;
private final CryptoService cryptoService;
......
package fitconnect.impl.auth;
import com.fasterxml.jackson.databind.ObjectMapper;
import fitconnect.api.services.auth.OAuthService;
import fitconnect.api.domain.auth.OAuthToken;
import fitconnect.api.exceptions.AuthenticationException;
import fitconnect.api.services.auth.OAuthService;
import fitconnect.impl.logger.SdkLogger;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.List;
import java.util.logging.Logger;
import static java.util.stream.Collectors.joining;
public class FitCoAuthService implements OAuthService {
public class MonoPublisherOAuthService implements OAuthService {
private static final Logger logger = SdkLogger.defaultLogger(FitCoAuthService.class);
private static final ObjectMapper mapper = new ObjectMapper();
private static final Logger logger = SdkLogger.defaultLogger(MonoPublisherOAuthService.class);
private final HttpClient client;
private final String tokenUrl;
public FitCoAuthService(final HttpClient client, final String tokenUrl) {
this.client = client;
public MonoPublisherOAuthService(final String tokenUrl) {
this.tokenUrl = tokenUrl;
}
@Override
public OAuthToken authenticate(String clientId, String clientSecret, String... scope) throws AuthenticationException {
final String requestBody = buildRequestBody(clientId, clientSecret, scope);
try {
return performTokenRequest(requestBody);
} catch (IOException | InterruptedException e) {
logger.log(Level.SEVERE, "error retrieving access token", e);
throw new AuthenticationException(e.getMessage(),e);
}
return performTokenRequestAsync(requestBody).block();
}
private String buildRequestBody(String clientId, String clientSecret, String... scope) {
......@@ -51,20 +44,25 @@ public class FitCoAuthService implements OAuthService {
Arrays.stream(scope).forEach(s -> data.put("scope", s));
return data.entrySet()
.stream()
.map(e -> e.getKey() + "=" + e.getValue())
.collect(joining("&"));
return data.entrySet().stream().map(e -> e.getKey() + "=" + e.getValue()).collect(joining("&"));
}
private OAuthToken performTokenRequest(final String requestBody) throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder()
.header("Accept", "application/json")
.header("Content-Type","application/x-www-form-urlencoded;charset=UTF-8")
.uri(URI.create(tokenUrl))
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
var responseBody = client.send(request, HttpResponse.BodyHandlers.ofString()).body();
return mapper.readValue(responseBody,OAuthToken.class);
// TODO generalize HTTP requests in separate common service
private Mono<OAuthToken> performTokenRequestAsync(final String requestBody){
return WebClient.builder()
.defaultHeaders(this::setHeaders)
.build()
.post()
.uri(tokenUrl)
.bodyValue(requestBody)
.retrieve()
.bodyToMono(OAuthToken.class);
}
private void setHeaders(HttpHeaders headers) {
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.setAcceptCharset(List.of(StandardCharsets.UTF_8));
}
}
package fitconnect.impl.auth;
import fitconnect.api.services.Sender;
import fitconnect.api.domain.auth.OAuthToken;
import fitconnect.api.services.Sender;
import fitconnect.impl.SubmissionSender;
import org.junit.jupiter.api.Test;
import java.net.http.HttpClient;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
......@@ -21,8 +20,7 @@ class OAuthTokenIntegrationTest {
var secret = "PnzR8Vbmhpv_VwTkT34wponqXWK8WBm-LADlryYdV4o";
var scope = "send:region:DE";
var httpClient = HttpClient.newHttpClient();
var authService = new FitCoAuthService(httpClient, tokenUrl);
var authService = new MonoPublisherOAuthService(tokenUrl);
final Sender sender = new SubmissionSender(authService, null, null);
// When
......
......@@ -73,6 +73,11 @@
<artifactId>everit-json-schema</artifactId>
<version>1.14.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment