Skip to content

Commit 36d48a2

Browse files
Merge pull request #48 from Mastercard/feature/webflux-support
Adding webflux support
2 parents 819b05a + b1b7b4f commit 36d48a2

5 files changed

Lines changed: 147 additions & 0 deletions

File tree

README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ Usage briefly described below, but you can also refer to the test package for ex
9696
+ [Java HttpsURLConnection](#java-httpsurlconnection)
9797
+ [Apache HTTP Client 4](#apache-http-client-4)
9898
+ [OkHttp 3](#okhttp-3)
99+
+ [Spring Webflux](#spring-webflux)
99100

100101
#### Java HttpsURLConnection <a name="java-httpsurlconnection"></a>
101102
```java
@@ -138,6 +139,19 @@ OkHttpSigner signer = new OkHttpSigner(consumerKey, signingKey);
138139
signer.sign(request);
139140
```
140141

142+
#### Spring Webflux <a name="spring-webflux"></a>
143+
```java
144+
WebClient client = WebClient.create();
145+
ClientRequest request = ClientRequest.create(HttpMethod.POST, URI.create("https://api.mastercard.com/service"))
146+
.header("Content-Type", MediaType.APPLICATION_JSON_VALUE)
147+
.body(BodyInserters.fromValue(yourRequestObject))
148+
.build();
149+
150+
SpringWebfluxSigner signer = new SpringWebfluxSigner(consumerKey, signingKey);
151+
ClientRequest signedRequest = signer.sign(request);
152+
client.exchange(signedRequest);
153+
```
154+
141155
### Integrating with OpenAPI Generator API Client Libraries <a name="integrating-with-openapi-generator-api-client-libraries"></a>
142156

143157
[OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator) generates API client libraries from [OpenAPI Specs](https://github.com/OAI/OpenAPI-Specification).
@@ -151,6 +165,7 @@ Library options currently supported for the `java` generator:
151165
+ [retrofit](#retrofit)
152166
+ [retrofit2](#retrofit2)
153167
+ [google-api-client](#google-api-client)
168+
+ [spring-webflux](#spring-webflux-interceptor)
154169

155170
See also:
156171
* [OpenAPI Generator (maven Plugin)](https://mvnrepository.com/artifact/org.openapitools/openapi-generator-maven-plugin)
@@ -284,3 +299,25 @@ ApiClient client = new ApiClient("https://sandbox.api.mastercard.com", null, ini
284299
ServiceApi serviceApi = client.serviceApi();
285300
// ...
286301
```
302+
303+
#### spring-webflux <a name="spring-webflux-interceptor"></a>
304+
##### OpenAPI Generator Plugin Configuration
305+
```xml
306+
<configuration>
307+
<inputSpec>${project.basedir}/src/main/resources/openapi-spec.yaml</inputSpec>
308+
<generatorName>spring</generatorName>
309+
<library>spring-cloud</library>
310+
<!-- ... -->
311+
</configuration>
312+
```
313+
314+
##### Usage of the `HttpExecuteOAuth1Interceptor`
315+
```java
316+
WebClient.Builder webClientBuilder = WebClient.builder()
317+
.baseUrl("https://api.mastercard.com/service")
318+
.filter(new SpringWebfluxOAuth1Interceptor(consumerKey, signingKey));
319+
320+
ApiClient apiClient = new ApiClient(webClientBuilder);
321+
ServiceApi serviceApi = client.serviceApi();
322+
// ...
323+
```

pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
<properties>
1616
<spring-version>5.3.33</spring-version>
17+
<spring-webflux-version>3.5.3</spring-webflux-version>
1718
<okhttp2-version>2.7.5</okhttp2-version>
1819
<okhttp3-version>4.12.0</okhttp3-version>
1920
<google-api-client-version>2.3.0</google-api-client-version>
@@ -85,6 +86,13 @@
8586
<scope>provided</scope>
8687
</dependency>
8788

89+
<dependency>
90+
<groupId>org.springframework.boot</groupId>
91+
<artifactId>spring-boot-starter-webflux</artifactId>
92+
<version>${spring-webflux-version}</version>
93+
<scope>provided</scope>
94+
</dependency>
95+
8896
<dependency>
8997
<groupId>junit</groupId>
9098
<artifactId>junit</artifactId>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.mastercard.developer.interceptors;
2+
3+
import com.mastercard.developer.signers.SpringWebfluxSigner;
4+
import org.springframework.web.reactive.function.client.ClientRequest;
5+
import org.springframework.web.reactive.function.client.ClientResponse;
6+
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
7+
import org.springframework.web.reactive.function.client.ExchangeFunction;
8+
import reactor.core.publisher.Mono;
9+
10+
import java.security.PrivateKey;
11+
12+
/**
13+
* A Spring webflux request interceptor for handling OAuth1.0a
14+
*/
15+
public class SpringWebfluxOAuth1Interceptor implements ExchangeFilterFunction {
16+
17+
private final SpringWebfluxSigner signer;
18+
19+
public SpringWebfluxOAuth1Interceptor(String consumerKey, PrivateKey signingKey) {
20+
this.signer = new SpringWebfluxSigner(consumerKey, signingKey);
21+
}
22+
23+
@Override
24+
public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next) {
25+
try {
26+
ClientRequest req = signer.sign(request);
27+
return next.exchange(req).doOnNext(response -> {});
28+
} catch (Exception e) {
29+
throw new RuntimeException(e);
30+
}
31+
}
32+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.mastercard.developer.signers;
2+
3+
import com.mastercard.developer.oauth.OAuth;
4+
import org.springframework.web.reactive.function.client.ClientRequest;
5+
import reactor.core.publisher.Mono;
6+
7+
import java.net.URI;
8+
import java.security.PrivateKey;
9+
10+
/**
11+
* Utility class for signing Spring webflux requests
12+
*/
13+
public class SpringWebfluxSigner extends AbstractSigner {
14+
15+
public SpringWebfluxSigner(String consumerKey, PrivateKey signingKey) {
16+
super(consumerKey, signingKey);
17+
}
18+
19+
public ClientRequest sign(ClientRequest request) throws Exception {
20+
URI uri = request.url();
21+
String method = request.method().name();
22+
23+
String authHeader = OAuth.getAuthorizationHeader(uri, method, request.body().toString(), charset, consumerKey, signingKey);
24+
25+
// Add auth header
26+
return Mono.just(ClientRequest.from(request)
27+
.headers(headers -> headers.add(OAuth.AUTHORIZATION_HEADER_NAME, authHeader))
28+
.build()).block();
29+
}
30+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.mastercard.developer.signers;
2+
3+
import com.squareup.okhttp.MediaType;
4+
import com.squareup.okhttp.RequestBody;
5+
import org.junit.Assert;
6+
import org.junit.Test;
7+
import org.springframework.http.HttpMethod;
8+
import org.springframework.http.ReactiveHttpOutputMessage;
9+
import org.springframework.web.reactive.function.BodyInserter;
10+
import org.springframework.web.reactive.function.BodyInserters;
11+
import org.springframework.web.reactive.function.client.ClientRequest;
12+
13+
import java.net.URI;
14+
import java.security.PrivateKey;
15+
16+
import static com.mastercard.developer.test.TestUtils.UTF8_CHARSET;
17+
import static com.mastercard.developer.test.TestUtils.getTestSigningKey;
18+
19+
public class SpringWebfluxSignerTest {
20+
21+
@Test
22+
public void testSign_ShouldAddOAuth1HeaderToPostRequest() throws Exception {
23+
24+
// GIVEN
25+
PrivateKey signingKey = getTestSigningKey();
26+
String consumerKey = "Some key";
27+
MediaType jsonMediaType = MediaType.parse("application/json; charset=" + UTF8_CHARSET.name());
28+
RequestBody body = RequestBody.create(jsonMediaType, "{\"foo\":\"bår\"}");
29+
BodyInserter<RequestBody, ReactiveHttpOutputMessage> inserter = BodyInserters.fromValue(body);
30+
ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("https://api.mastercard.com/service")).body(inserter).build();
31+
32+
// WHEN
33+
SpringWebfluxSigner instanceUnderTest = new SpringWebfluxSigner(consumerKey, signingKey);
34+
ClientRequest signedRequest = instanceUnderTest.sign(request);
35+
36+
// THEN
37+
String authorizationHeaderValue = signedRequest.headers().getFirst("Authorization");
38+
Assert.assertNotNull(authorizationHeaderValue);
39+
}
40+
}

0 commit comments

Comments
 (0)