Skip to content

Commit d4e9733

Browse files
committed
Merge branch 'async-okhttp' of https://github.com/arcao/scribejava into arcao-async-okhttp
2 parents 43ea452 + fa96ffb commit d4e9733

10 files changed

Lines changed: 461 additions & 0 deletions

File tree

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<module>scribejava-apis</module>
2020
<module>scribejava-httpclient-ahc</module>
2121
<module>scribejava-httpclient-ning</module>
22+
<module>scribejava-httpclient-okhttp</module>
2223
</modules>
2324

2425
<licenses>

scribejava-apis/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@
3232
<version>${project.version}</version>
3333
<scope>test</scope>
3434
</dependency>
35+
<dependency>
36+
<groupId>com.github.scribejava</groupId>
37+
<artifactId>scribejava-httpclient-okhttp</artifactId>
38+
<version>${project.version}</version>
39+
<scope>test</scope>
40+
</dependency>
3541
</dependencies>
3642

3743
<build>
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package com.github.scribejava.apis.examples;
2+
3+
import com.github.scribejava.apis.GitHubApi;
4+
import com.github.scribejava.core.builder.ServiceBuilder;
5+
import com.github.scribejava.core.model.OAuth2AccessToken;
6+
import com.github.scribejava.core.model.OAuthRequestAsync;
7+
import com.github.scribejava.core.model.Response;
8+
import com.github.scribejava.core.model.Verb;
9+
import com.github.scribejava.core.oauth.OAuth20Service;
10+
import com.github.scribejava.httpclient.okhttp.OkHttpHttpClient;
11+
import okhttp3.OkHttpClient;
12+
13+
import java.io.IOException;
14+
import java.util.Random;
15+
import java.util.Scanner;
16+
import java.util.concurrent.ExecutionException;
17+
18+
public final class GitHubAsyncOkHttpExample {
19+
20+
private static final String NETWORK_NAME = "GitHub";
21+
private static final String PROTECTED_RESOURCE_URL = "https://api.github.com/user";
22+
23+
private GitHubAsyncOkHttpExample() {
24+
}
25+
26+
public static void main(String... args) throws IOException, ExecutionException, InterruptedException {
27+
// Replace these with your client id and secret
28+
final String clientId = "your client id";
29+
final String clientSecret = "your client secret";
30+
final String secretState = "secret" + new Random().nextInt(999_999);
31+
final OAuth20Service service = new ServiceBuilder()
32+
.apiKey(clientId)
33+
.apiSecret(clientSecret)
34+
.state(secretState)
35+
.callback("http://www.example.com/oauth_callback/")
36+
.httpClient(new OkHttpHttpClient(new OkHttpClient()))
37+
.build(GitHubApi.instance());
38+
final Scanner in = new Scanner(System.in, "UTF-8");
39+
40+
System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ===");
41+
System.out.println();
42+
43+
// Obtain the Authorization URL
44+
System.out.println("Fetching the Authorization URL...");
45+
final String authorizationUrl = service.getAuthorizationUrl();
46+
System.out.println("Got the Authorization URL!");
47+
System.out.println("Now go and authorize ScribeJava here:");
48+
System.out.println(authorizationUrl);
49+
System.out.println("And paste the authorization code here");
50+
System.out.print(">>");
51+
final String code = in.nextLine();
52+
System.out.println();
53+
54+
System.out.println("And paste the state from server here. We have set 'secretState'='" + secretState + "'.");
55+
System.out.print(">>");
56+
final String value = in.nextLine();
57+
if (secretState.equals(value)) {
58+
System.out.println("State value does match!");
59+
} else {
60+
System.out.println("Ooops, state value does not match!");
61+
System.out.println("Expected = " + secretState);
62+
System.out.println("Got = " + value);
63+
System.out.println();
64+
}
65+
66+
// Trade the Request Token and Verfier for the Access Token
67+
System.out.println("Trading the Request Token for an Access Token...");
68+
final OAuth2AccessToken accessToken = service.getAccessTokenAsync(code, null).get();
69+
System.out.println("Got the Access Token!");
70+
System.out.println("(if your curious it looks like this: " + accessToken
71+
+ ", 'rawResponse'='" + accessToken.getRawResponse() + "')");
72+
System.out.println();
73+
74+
// Now let's go and ask for a protected resource!
75+
System.out.println("Now we're going to access a protected resource...");
76+
final OAuthRequestAsync request = new OAuthRequestAsync(Verb.GET, PROTECTED_RESOURCE_URL, service);
77+
service.signRequest(accessToken, request);
78+
final Response response = request.sendAsync(null).get();
79+
System.out.println("Got it! Lets see what we found...");
80+
System.out.println();
81+
System.out.println(response.getCode());
82+
System.out.println(response.getBody());
83+
84+
System.out.println();
85+
System.out.println("Thats it man! Go and build something awesome with ScribeJava! :)");
86+
}
87+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<parent>
6+
<groupId>com.github.scribejava</groupId>
7+
<artifactId>scribejava</artifactId>
8+
<version>3.3.1-SNAPSHOT</version>
9+
<relativePath>../pom.xml</relativePath>
10+
</parent>
11+
12+
<groupId>com.github.scribejava</groupId>
13+
<artifactId>scribejava-httpclient-okhttp</artifactId>
14+
<name>ScribeJava Async OkHttp Client support</name>
15+
<packaging>jar</packaging>
16+
17+
<dependencies>
18+
<dependency>
19+
<groupId>com.github.scribejava</groupId>
20+
<artifactId>scribejava-core</artifactId>
21+
<version>${project.version}</version>
22+
</dependency>
23+
<dependency>
24+
<groupId>com.squareup.okhttp3</groupId>
25+
<artifactId>okhttp</artifactId>
26+
<version>3.4.2</version>
27+
</dependency>
28+
<dependency>
29+
<groupId>com.squareup.okhttp3</groupId>
30+
<artifactId>mockwebserver</artifactId>
31+
<version>3.4.2</version>
32+
<scope>test</scope>
33+
</dependency>
34+
</dependencies>
35+
36+
<build>
37+
<plugins>
38+
<plugin>
39+
<groupId>org.apache.felix</groupId>
40+
<artifactId>maven-bundle-plugin</artifactId>
41+
</plugin>
42+
<plugin>
43+
<groupId>org.apache.maven.plugins</groupId>
44+
<artifactId>maven-jar-plugin</artifactId>
45+
</plugin>
46+
</plugins>
47+
</build>
48+
</project>
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package com.github.scribejava.httpclient.okhttp;
2+
3+
import com.github.scribejava.core.model.OAuthAsyncRequestCallback;
4+
import com.github.scribejava.core.model.OAuthRequestAsync;
5+
import com.github.scribejava.core.model.Response;
6+
import okhttp3.Call;
7+
import okhttp3.Callback;
8+
import okhttp3.Headers;
9+
10+
import java.io.IOException;
11+
import java.util.HashMap;
12+
import java.util.Map;
13+
import java.util.concurrent.CountDownLatch;
14+
import java.util.concurrent.ExecutionException;
15+
import java.util.concurrent.Future;
16+
import java.util.concurrent.TimeUnit;
17+
import java.util.concurrent.TimeoutException;
18+
19+
class OAuthAsyncCompletionHandler<T> implements Callback, Future<T> {
20+
21+
private final OAuthAsyncRequestCallback<T> callback;
22+
private final OAuthRequestAsync.ResponseConverter<T> converter;
23+
private final Call call;
24+
private final CountDownLatch latch;
25+
private T result;
26+
27+
OAuthAsyncCompletionHandler(OAuthAsyncRequestCallback<T> callback,
28+
OAuthRequestAsync.ResponseConverter<T> converter, Call call) {
29+
this.callback = callback;
30+
this.converter = converter;
31+
this.call = call;
32+
this.latch = new CountDownLatch(1);
33+
34+
call.enqueue(this);
35+
}
36+
37+
@Override
38+
public void onFailure(Call call, IOException e) {
39+
try {
40+
if (callback != null) {
41+
callback.onThrowable(e);
42+
}
43+
} finally {
44+
latch.countDown();
45+
}
46+
}
47+
48+
@Override
49+
public void onResponse(Call call, okhttp3.Response okHttpResponse) throws IOException {
50+
try {
51+
final Headers headers = okHttpResponse.headers();
52+
final Map<String, String> headersMap = new HashMap<>();
53+
54+
for (String name : headers.names()) {
55+
headersMap.put(name, headers.get(name));
56+
}
57+
58+
final Response response = new Response(okHttpResponse.code(),
59+
okHttpResponse.message(),
60+
headersMap,
61+
null, // cannot return both body String and InputStream
62+
okHttpResponse.body().byteStream());
63+
64+
@SuppressWarnings("unchecked")
65+
final T t = converter == null ? (T) response : converter.convert(response);
66+
result = t;
67+
if (callback != null) {
68+
callback.onCompleted(t);
69+
}
70+
} finally {
71+
latch.countDown();
72+
}
73+
}
74+
75+
@Override
76+
public boolean cancel(boolean mayInterruptIfRunning) {
77+
call.cancel();
78+
return call.isCanceled();
79+
}
80+
81+
@Override
82+
public boolean isCancelled() {
83+
return call.isCanceled();
84+
}
85+
86+
@Override
87+
public boolean isDone() {
88+
return call.isExecuted();
89+
}
90+
91+
@Override
92+
public T get() throws InterruptedException, ExecutionException {
93+
latch.await();
94+
return result;
95+
}
96+
97+
@Override
98+
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
99+
latch.await(timeout, unit);
100+
return result;
101+
}
102+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.github.scribejava.httpclient.okhttp;
2+
3+
import com.github.scribejava.core.model.AbstractRequest;
4+
import com.github.scribejava.core.model.HttpClient;
5+
import com.github.scribejava.core.model.OAuthAsyncRequestCallback;
6+
import com.github.scribejava.core.model.OAuthConstants;
7+
import com.github.scribejava.core.model.OAuthRequestAsync;
8+
import com.github.scribejava.core.model.Verb;
9+
import okhttp3.Call;
10+
import okhttp3.MediaType;
11+
import okhttp3.OkHttpClient;
12+
import okhttp3.Request;
13+
import okhttp3.RequestBody;
14+
import okhttp3.internal.http.HttpMethod;
15+
16+
import java.io.IOException;
17+
import java.util.Map;
18+
import java.util.concurrent.Future;
19+
20+
import static com.github.scribejava.core.model.AbstractRequest.DEFAULT_CONTENT_TYPE;
21+
22+
public class OkHttpHttpClient implements HttpClient {
23+
24+
private final OkHttpClient client;
25+
26+
public OkHttpHttpClient(OkHttpHttpClientConfig config) {
27+
client = config.getClient();
28+
}
29+
30+
public OkHttpHttpClient(OkHttpClient client) {
31+
this.client = client;
32+
}
33+
34+
@Override
35+
public void close() throws IOException {
36+
//client.close();
37+
}
38+
39+
@Override
40+
public <T> Future<T> executeAsync(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
41+
String bodyContents, OAuthAsyncRequestCallback<T> callback,
42+
OAuthRequestAsync.ResponseConverter<T> converter) {
43+
final Request.Builder requestBuilder = new Request.Builder();
44+
requestBuilder.url(completeUrl);
45+
46+
final String method = httpVerb.name();
47+
48+
// prepare body
49+
RequestBody body = null;
50+
if (bodyContents != null && HttpMethod.permitsRequestBody(method)) {
51+
final String contentType = headers.containsKey(AbstractRequest.CONTENT_TYPE) ?
52+
headers.get(AbstractRequest.CONTENT_TYPE) : DEFAULT_CONTENT_TYPE;
53+
body = RequestBody.create(MediaType.parse(contentType), bodyContents);
54+
}
55+
56+
// fill HTTP method and body
57+
requestBuilder.method(method, body);
58+
59+
// fill headers
60+
for (Map.Entry<String, String> header : headers.entrySet()) {
61+
requestBuilder.addHeader(header.getKey(), header.getValue());
62+
}
63+
if (userAgent != null) {
64+
requestBuilder.header(OAuthConstants.USER_AGENT_HEADER_NAME, userAgent);
65+
}
66+
67+
// create a new call
68+
final Call call = client.newCall(requestBuilder.build());
69+
return new OAuthAsyncCompletionHandler<>(callback, converter, call);
70+
}
71+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.github.scribejava.httpclient.okhttp;
2+
3+
import com.github.scribejava.core.model.HttpClient;
4+
import okhttp3.OkHttpClient;
5+
6+
public class OkHttpHttpClientConfig implements HttpClient.Config {
7+
8+
private final OkHttpClient client;
9+
10+
public OkHttpHttpClientConfig(OkHttpClient client) {
11+
this.client = client;
12+
}
13+
14+
public OkHttpClient getClient() {
15+
return client;
16+
}
17+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.github.scribejava.httpclient.okhttp;
2+
3+
import com.github.scribejava.core.httpclient.HttpClientProvider;
4+
import com.github.scribejava.core.model.HttpClient;
5+
6+
public class OkHttpProvider implements HttpClientProvider {
7+
8+
@Override
9+
public HttpClient createClient(HttpClient.Config config) {
10+
if (config instanceof OkHttpHttpClientConfig) {
11+
return new OkHttpHttpClient((OkHttpHttpClientConfig) config);
12+
}
13+
return null;
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
com.github.scribejava.httpclient.okhttp.OkHttpProvider

0 commit comments

Comments
 (0)