Skip to content

Commit 38ee9cf

Browse files
Add basic functionality for running graphql requests (#182)
* WIP: enable automerge * Test enableAutoMerge * Add factory methods for configuring graphqlUrl * javadoc... * chores... * Make generic graphql method in GithubClient instead * Update src/main/java/com/spotify/github/v3/clients/GitHubClient.java Co-authored-by: Abhishek Jain <[email protected]> * Javadoc --------- Co-authored-by: Abhishek Jain <[email protected]>
1 parent b8e8ae6 commit 38ee9cf

File tree

8 files changed

+95
-29
lines changed

8 files changed

+95
-29
lines changed

src/main/java/com/spotify/github/v3/clients/GitHubClient.java

Lines changed: 80 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ public class GitHubClient {
118118
private static final int FORBIDDEN = 403;
119119

120120
private final URI baseUrl;
121+
122+
private final Optional<URI> graphqlUrl;
121123
private final Json json = Json.create();
122124
private final OkHttpClient client;
123125
private final String token;
@@ -131,11 +133,13 @@ public class GitHubClient {
131133
private GitHubClient(
132134
final OkHttpClient client,
133135
final URI baseUrl,
136+
final URI graphqlUrl,
134137
final String accessToken,
135138
final byte[] privateKey,
136139
final Integer appId,
137140
final Integer installationId) {
138141
this.baseUrl = baseUrl;
142+
this.graphqlUrl = Optional.ofNullable(graphqlUrl);
139143
this.token = accessToken;
140144
this.client = client;
141145
this.privateKey = privateKey;
@@ -152,7 +156,11 @@ private GitHubClient(
152156
* @return github api client
153157
*/
154158
public static GitHubClient create(final URI baseUrl, final String token) {
155-
return new GitHubClient(new OkHttpClient(), baseUrl, token, null, null, null);
159+
return new GitHubClient(new OkHttpClient(), baseUrl, null, token, null, null, null);
160+
}
161+
162+
public static GitHubClient create(final URI baseUrl, final URI graphqlUri, final String token) {
163+
return new GitHubClient(new OkHttpClient(), baseUrl, graphqlUri, token, null, null, null);
156164
}
157165

158166
/**
@@ -164,7 +172,7 @@ public static GitHubClient create(final URI baseUrl, final String token) {
164172
* @return github api client
165173
*/
166174
public static GitHubClient create(final URI baseUrl, final File privateKey, final Integer appId) {
167-
return createOrThrow(new OkHttpClient(), baseUrl, privateKey, appId, null);
175+
return createOrThrow(new OkHttpClient(), baseUrl, null, privateKey, appId, null);
168176
}
169177

170178
/**
@@ -176,7 +184,7 @@ public static GitHubClient create(final URI baseUrl, final File privateKey, fina
176184
* @return github api client
177185
*/
178186
public static GitHubClient create(final URI baseUrl, final byte[] privateKey, final Integer appId) {
179-
return new GitHubClient(new OkHttpClient(), baseUrl, null, privateKey, appId, null);
187+
return new GitHubClient(new OkHttpClient(), baseUrl, null, null, privateKey, appId, null);
180188
}
181189

182190
/**
@@ -190,7 +198,7 @@ public static GitHubClient create(final URI baseUrl, final byte[] privateKey, fi
190198
*/
191199
public static GitHubClient create(
192200
final URI baseUrl, final File privateKey, final Integer appId, final Integer installationId) {
193-
return createOrThrow(new OkHttpClient(), baseUrl, privateKey, appId, installationId);
201+
return createOrThrow(new OkHttpClient(), baseUrl, null, privateKey, appId, installationId);
194202
}
195203

196204
/**
@@ -204,7 +212,7 @@ public static GitHubClient create(
204212
*/
205213
public static GitHubClient create(
206214
final URI baseUrl, final byte[] privateKey, final Integer appId, final Integer installationId) {
207-
return new GitHubClient(new OkHttpClient(), baseUrl, null, privateKey, appId, installationId);
215+
return new GitHubClient(new OkHttpClient(), baseUrl, null, null, privateKey, appId, installationId);
208216
}
209217

210218
/**
@@ -221,7 +229,25 @@ public static GitHubClient create(
221229
final URI baseUrl,
222230
final File privateKey,
223231
final Integer appId) {
224-
return createOrThrow(httpClient, baseUrl, privateKey, appId, null);
232+
return createOrThrow(httpClient, baseUrl, null, privateKey, appId, null);
233+
}
234+
235+
/**
236+
* Create a github api client with a given base URL and a path to a key.
237+
*
238+
* @param httpClient an instance of OkHttpClient
239+
* @param baseUrl base URL
240+
* @param privateKey the private key PEM file
241+
* @param appId the github app ID
242+
* @return github api client
243+
*/
244+
public static GitHubClient create(
245+
final OkHttpClient httpClient,
246+
final URI baseUrl,
247+
final URI graphqlUrl,
248+
final File privateKey,
249+
final Integer appId) {
250+
return createOrThrow(httpClient, baseUrl, graphqlUrl, privateKey, appId, null);
225251
}
226252

227253
/**
@@ -238,9 +264,11 @@ public static GitHubClient create(
238264
final URI baseUrl,
239265
final byte[] privateKey,
240266
final Integer appId) {
241-
return new GitHubClient(httpClient, baseUrl, null, privateKey, appId, null);
267+
return new GitHubClient(httpClient, baseUrl, null, null, privateKey, appId, null);
242268
}
243269

270+
271+
244272
/**
245273
* Create a github api client with a given base URL and a path to a key.
246274
*
@@ -256,7 +284,7 @@ public static GitHubClient create(
256284
final File privateKey,
257285
final Integer appId,
258286
final Integer installationId) {
259-
return createOrThrow(httpClient, baseUrl, privateKey, appId, installationId);
287+
return createOrThrow(httpClient, baseUrl, null, privateKey, appId, installationId);
260288
}
261289

262290
/**
@@ -274,7 +302,7 @@ public static GitHubClient create(
274302
final byte[] privateKey,
275303
final Integer appId,
276304
final Integer installationId) {
277-
return new GitHubClient(httpClient, baseUrl, null, privateKey, appId, installationId);
305+
return new GitHubClient(httpClient, baseUrl, null, null, privateKey, appId, installationId);
278306
}
279307

280308
/**
@@ -287,7 +315,12 @@ public static GitHubClient create(
287315
*/
288316
public static GitHubClient create(
289317
final OkHttpClient httpClient, final URI baseUrl, final String token) {
290-
return new GitHubClient(httpClient, baseUrl, token, null, null, null);
318+
return new GitHubClient(httpClient, baseUrl, null, token, null, null, null);
319+
}
320+
321+
public static GitHubClient create(
322+
final OkHttpClient httpClient, final URI baseUrl, final URI graphqlUrl, final String token) {
323+
return new GitHubClient(httpClient, baseUrl, graphqlUrl, token, null, null, null);
291324
}
292325

293326
/**
@@ -306,6 +339,7 @@ public static GitHubClient scopeForInstallationId(
306339
client.client,
307340
client.baseUrl,
308341
null,
342+
null,
309343
client.getPrivateKey().get(),
310344
client.appId,
311345
installationId);
@@ -327,6 +361,7 @@ public GitHubClient withScopeForInstallationId(final int installationId) {
327361
client,
328362
baseUrl,
329363
null,
364+
null,
330365
privateKey,
331366
appId,
332367
installationId);
@@ -565,6 +600,23 @@ <T> CompletableFuture<T> post(final String path, final String data, final Class<
565600
response -> json().fromJsonUncheckedNotNull(responseBodyUnchecked(response), clazz));
566601
}
567602

603+
/**
604+
* Make a POST request to the graphql endpoint of Github
605+
*
606+
* @param data request body as stringified JSON
607+
* @return response
608+
*
609+
* @see "https://docs.github.com/en/[email protected]/graphql/guides/forming-calls-with-graphql#communicating-with-graphql"
610+
*/
611+
public CompletableFuture<Response> postGraphql(final String data) {
612+
final Request request =
613+
graphqlRequestBuilder()
614+
.method("POST", RequestBody.create(parse(MediaType.APPLICATION_JSON), data))
615+
.build();
616+
log.info("Making POST request to {}", request.url());
617+
return call(request);
618+
}
619+
568620
/**
569621
* Make an http PUT request for the given path with provided JSON body.
570622
*
@@ -698,6 +750,22 @@ private Request.Builder requestBuilder(final String path) {
698750
return builder;
699751
}
700752

753+
private Request.Builder graphqlRequestBuilder() {
754+
URI url = graphqlUrl.orElseThrow(() -> new IllegalStateException("No graphql url set"));
755+
final Request.Builder builder =
756+
new Request.Builder()
757+
.url(url.toString())
758+
.addHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON)
759+
.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
760+
builder.addHeader(HttpHeaders.AUTHORIZATION, getAuthorizationHeader("/graphql"));
761+
return builder;
762+
}
763+
764+
public boolean isGraphqlEnabled() {
765+
return graphqlUrl.isPresent();
766+
}
767+
768+
701769
/*
702770
Generates the Authentication header, given the API endpoint and the credentials provided.
703771
@@ -870,9 +938,9 @@ CompletableFuture<Response> processPossibleRedirects(
870938
/**
871939
* Wrapper to Constructors that expose File object for the privateKey argument
872940
* */
873-
private static GitHubClient createOrThrow(final OkHttpClient httpClient, final URI baseUrl, final File privateKey, final Integer appId, final Integer installationId) {
941+
private static GitHubClient createOrThrow(final OkHttpClient httpClient, final URI baseUrl, final URI graphqlUrl, final File privateKey, final Integer appId, final Integer installationId) {
874942
try {
875-
return new GitHubClient(httpClient, baseUrl, null, FileUtils.readFileToByteArray(privateKey), appId, installationId);
943+
return new GitHubClient(httpClient, baseUrl, graphqlUrl, null, FileUtils.readFileToByteArray(privateKey), appId, installationId);
876944
} catch (IOException e) {
877945
throw new RuntimeException("There was an error generating JWT token", e);
878946
}

src/main/java/com/spotify/github/v3/clients/PullRequestClient.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
* Licensed under the Apache License, Version 2.0 (the "License");
88
* you may not use this file except in compliance with the License.
99
* You may obtain a copy of the License at
10-
*
10+
*
1111
* http://www.apache.org/licenses/LICENSE-2.0
12-
*
12+
*
1313
* Unless required by applicable law or agreed to in writing, software
1414
* distributed under the License is distributed on an "AS IS" BASIS,
1515
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -269,5 +269,4 @@ private CompletableFuture<List<PullRequestItem>> list(final String parameterPath
269269
log.debug("Fetching pull requests from " + path);
270270
return github.request(path, LIST_PR_TYPE_REFERENCE);
271271
}
272-
273272
}

src/main/java/com/spotify/github/v3/prs/PullRequest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
@JsonDeserialize(as = ImmutablePullRequest.class)
3939
public interface PullRequest extends PullRequestItem {
4040

41+
String nodeId();
42+
4143
/** Is it merged. */
4244
@Nullable
4345
Boolean merged();

src/test/java/com/spotify/github/v3/clients/PullRequestClientTest.java

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,15 @@
2424
import static java.nio.charset.Charset.defaultCharset;
2525
import static org.hamcrest.MatcherAssert.assertThat;
2626
import static org.hamcrest.core.Is.is;
27-
import static org.junit.jupiter.api.Assertions.assertEquals;
28-
import static org.junit.jupiter.api.Assertions.assertThrows;
27+
import static org.junit.jupiter.api.Assertions.*;
2928
import static org.mockito.ArgumentMatchers.any;
30-
import static org.mockito.Mockito.doNothing;
31-
import static org.mockito.Mockito.mock;
32-
import static org.mockito.Mockito.when;
29+
import static org.mockito.Mockito.*;
3330

3431
import com.google.common.collect.ImmutableList;
3532
import com.google.common.io.Resources;
3633
import com.spotify.github.v3.exceptions.RequestNotOkException;
3734
import com.spotify.github.v3.prs.ImmutableRequestReviewParameters;
35+
import com.spotify.github.v3.prs.MergeMethod;
3836
import com.spotify.github.v3.prs.PullRequest;
3937
import com.spotify.github.v3.prs.ReviewRequests;
4038
import com.spotify.github.v3.prs.requests.ImmutablePullRequestCreate;
@@ -46,14 +44,9 @@
4644
import java.net.URI;
4745
import java.util.concurrent.CompletableFuture;
4846
import java.util.concurrent.ExecutionException;
49-
import okhttp3.Call;
50-
import okhttp3.Callback;
51-
import okhttp3.MediaType;
52-
import okhttp3.OkHttpClient;
53-
import okhttp3.Protocol;
54-
import okhttp3.Request;
55-
import okhttp3.Response;
56-
import okhttp3.ResponseBody;
47+
48+
import okhttp3.*;
49+
import okio.Buffer;
5750
import org.apache.commons.io.IOUtils;
5851
import org.junit.jupiter.api.BeforeEach;
5952
import org.junit.jupiter.api.Test;
@@ -71,7 +64,7 @@ private static String getFixture(String resource) throws IOException {
7164
@BeforeEach
7265
public void setUp() {
7366
client = mock(OkHttpClient.class);
74-
github = GitHubClient.create(client, URI.create("http://bogus"), "token");
67+
github = GitHubClient.create(client, URI.create("http://bogus"), URI.create("https://bogus/graphql"), "token");
7568
}
7669

7770
@Test

src/test/java/com/spotify/github/v3/prs/PullRequestTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public void testDeserializationPr() throws IOException {
3838
String fixture =
3939
Resources.toString(getResource(this.getClass(), "pull_request.json"), defaultCharset());
4040
final PullRequest pr = Json.create().fromJson(fixture, PullRequest.class);
41+
assertThat(pr.nodeId(), is("MDExOlB1bGxSZXF1ZXN0NDI3NDI0Nw=="));
4142
assertThat(pr.mergeCommitSha().get(), is("e5bd3914e2e596debea16f433f57875b5b90bcd6"));
4243
assertThat(pr.merged(), is(false));
4344
assertThat(pr.mergeable().get(), is(true));

src/test/resources/com/spotify/github/v3/activity/events/fixtures/pull_request_event.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"pull_request": {
55
"url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1",
66
"id": 34778301,
7+
"node_id": "MDExOlB1bGxSZXF1ZXN0NDI3NDI0Nw==",
78
"html_url": "https://github.com/baxterthehacker/public-repo/pull/1",
89
"diff_url": "https://github.com/baxterthehacker/public-repo/pull/1.diff",
910
"patch_url": "https://github.com/baxterthehacker/public-repo/pull/1.patch",

src/test/resources/com/spotify/github/v3/hooks/requests/pull-request-closed.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"pull_request": {
55
"url": "https://github.com/api/v3/repos/abba/custom-abba-metric-web/pulls/1",
66
"id": 320629,
7+
"node_id": "MDExOlB1bGxSZXF1ZXN0NDI3NDI0Nw==",
78
"html_url": "https://github.com/abba/custom-abba-metric-web/pull/1",
89
"diff_url": "https://github.com/abba/custom-abba-metric-web/pull/1.diff",
910
"patch_url": "https://github.com/abba/custom-abba-metric-web/pull/1.patch",

src/test/resources/com/spotify/github/v3/prs/pull_request.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"id": 1,
33
"url": "https://api.github.com/repos/octocat/Hello-World/pulls/1347",
4+
"node_id": "MDExOlB1bGxSZXF1ZXN0NDI3NDI0Nw==",
45
"html_url": "https://github.com/octocat/Hello-World/pull/1347",
56
"diff_url": "https://github.com/octocat/Hello-World/pull/1347.diff",
67
"patch_url": "https://github.com/octocat/Hello-World/pull/1347.patch",

0 commit comments

Comments
 (0)