Skip to content

Commit 40c4809

Browse files
committed
Support for okhttp scribejava#689
1 parent ab828cf commit 40c4809

File tree

9 files changed

+339
-0
lines changed

9 files changed

+339
-0
lines changed

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: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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 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+
</dependencies>
29+
30+
<build>
31+
<plugins>
32+
<plugin>
33+
<groupId>org.apache.felix</groupId>
34+
<artifactId>maven-bundle-plugin</artifactId>
35+
</plugin>
36+
<plugin>
37+
<groupId>org.apache.maven.plugins</groupId>
38+
<artifactId>maven-jar-plugin</artifactId>
39+
</plugin>
40+
</plugins>
41+
</build>
42+
</project>
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
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+
okHttpResponse.body().string(),
62+
null); // cannot return both body String and InputStream
63+
64+
@SuppressWarnings("unchecked")
65+
final T t = result = converter == null ? (T) response : converter.convert(response);
66+
if (callback != null) {
67+
callback.onCompleted(t);
68+
}
69+
} finally {
70+
latch.countDown();
71+
}
72+
}
73+
74+
@Override
75+
public boolean cancel(boolean mayInterruptIfRunning) {
76+
call.cancel();
77+
return call.isCanceled();
78+
}
79+
80+
@Override
81+
public boolean isCancelled() {
82+
return call.isCanceled();
83+
}
84+
85+
@Override
86+
public boolean isDone() {
87+
return call.isExecuted();
88+
}
89+
90+
@Override
91+
public T get() throws InterruptedException, ExecutionException {
92+
latch.await();
93+
return result;
94+
}
95+
96+
@Override
97+
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
98+
latch.await(timeout, unit);
99+
return result;
100+
}
101+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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+
15+
import java.io.IOException;
16+
import java.util.Map;
17+
import java.util.concurrent.Future;
18+
19+
import static com.github.scribejava.core.model.AbstractRequest.DEFAULT_CONTENT_TYPE;
20+
21+
public class OkHttpHttpClient implements HttpClient {
22+
23+
private final OkHttpClient client;
24+
25+
public OkHttpHttpClient(OkHttpHttpClientConfig config) {
26+
client = config.getClient();
27+
}
28+
29+
public OkHttpHttpClient(OkHttpClient client) {
30+
this.client = client;
31+
}
32+
33+
@Override
34+
public void close() throws IOException {
35+
//client.close();
36+
}
37+
38+
@Override
39+
public <T> Future<T> executeAsync(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
40+
String bodyContents, OAuthAsyncRequestCallback<T> callback,
41+
OAuthRequestAsync.ResponseConverter<T> converter) {
42+
final Request.Builder requestBuilder = new Request.Builder();
43+
requestBuilder.url(completeUrl);
44+
45+
switch (httpVerb) {
46+
case GET:
47+
requestBuilder.get();
48+
break;
49+
case POST:
50+
String contentType = headers.containsKey(AbstractRequest.CONTENT_TYPE) ?
51+
headers.get(AbstractRequest.CONTENT_TYPE) : DEFAULT_CONTENT_TYPE;
52+
53+
requestBuilder.post(RequestBody.create(MediaType.parse(contentType), bodyContents));
54+
break;
55+
default:
56+
throw new IllegalArgumentException("message build error: unknown verb type");
57+
}
58+
59+
for (Map.Entry<String, String> header : headers.entrySet()) {
60+
requestBuilder.addHeader(header.getKey(), header.getValue());
61+
}
62+
if (userAgent != null) {
63+
requestBuilder.header(OAuthConstants.USER_AGENT_HEADER_NAME, userAgent);
64+
}
65+
66+
final Call call = client.newCall(requestBuilder.build());
67+
return new OAuthAsyncCompletionHandler<>(callback, converter, call);
68+
}
69+
}
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)