Skip to content

Commit 65363d3

Browse files
committed
Clean up and code coverage
1 parent 9db400d commit 65363d3

18 files changed

+218
-133
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@
165165
<exclude>org.kohsuke.github.GHCompare.User</exclude>
166166

167167
<!-- TODO: Some coverage, but more needed -->
168-
<exclude>org.kohsuke.github.GitHubResponseInfoHttpURLConnectionAdapter</exclude>
168+
<exclude>org.kohsuke.github.GitHubConnectorResponseHttpUrlConnectionAdapter</exclude>
169169
<exclude>org.kohsuke.github.GHPullRequestReviewBuilder.DraftReviewComment</exclude>
170170
<exclude>org.kohsuke.github.GHIssue.PullRequest</exclude>
171171
<exclude>org.kohsuke.github.GHCommitSearchBuilder</exclude>

src/main/java/org/kohsuke/github/AbuseLimitHandler.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import java.io.InterruptedIOException;
77
import java.net.HttpURLConnection;
88

9+
import javax.annotation.Nonnull;
10+
911
/**
1012
* Pluggable strategy to determine what to do when the API abuse limit is hit.
1113
*
@@ -34,12 +36,12 @@ public abstract class AbuseLimitHandler {
3436
* with abuse rate limits</a>
3537
*
3638
*/
37-
void onError(GitHubConnectorResponse connectorResponse) throws IOException {
39+
public void onError(@Nonnull GitHubConnectorResponse connectorResponse) throws IOException {
3840
GHIOException e = new HttpException("Abuse limit violation",
3941
connectorResponse.statusCode(),
4042
connectorResponse.header("Status"),
41-
connectorResponse.url().toString()).withResponseHeaderFields(connectorResponse.allHeaders());
42-
onError(e, new GitHubResponseInfoHttpURLConnectionAdapter(connectorResponse));
43+
connectorResponse.request().url().toString()).withResponseHeaderFields(connectorResponse.allHeaders());
44+
onError(e, new GitHubConnectorResponseHttpUrlConnectionAdapter(connectorResponse));
4345
}
4446

4547
/**
@@ -63,7 +65,9 @@ void onError(GitHubConnectorResponse connectorResponse) throws IOException {
6365
* with abuse rate limits</a>
6466
*
6567
*/
66-
public abstract void onError(IOException e, HttpURLConnection uc) throws IOException;
68+
@Deprecated
69+
public void onError(IOException e, HttpURLConnection uc) throws IOException {
70+
}
6771

6872
/**
6973
* Wait until the API abuse "wait time" is passed.

src/main/java/org/kohsuke/github/GitHub.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ public boolean isOffline() {
473473
*
474474
* @return the connector
475475
* @deprecated HttpConnector has been replaced by GitHubConnector which is generally not useful outside of this
476-
* library. If you are using
476+
* library. If you are using this method, file an issue describing your use case.
477477
*/
478478
@Deprecated
479479
public HttpConnector getConnector() {

src/main/java/org/kohsuke/github/GitHubClient.java

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import org.kohsuke.github.authorization.AuthorizationProvider;
77
import org.kohsuke.github.authorization.UserAuthorizationProvider;
88
import org.kohsuke.github.connector.GitHubConnector;
9+
import org.kohsuke.github.connector.GitHubConnectorRequest;
910
import org.kohsuke.github.connector.GitHubConnectorResponse;
1011
import org.kohsuke.github.function.BodyHandler;
1112

@@ -368,24 +369,26 @@ public <T> GitHubResponse<T> sendRequest(@Nonnull GitHubRequest.Builder<?> build
368369
public <T> GitHubResponse<T> sendRequest(GitHubRequest request, @CheckForNull BodyHandler<T> handler)
369370
throws IOException {
370371
int retries = CONNECTION_ERROR_RETRIES;
371-
request = prepareRequest(request);
372+
GitHubConnectorRequest connectorRequest = prepareConnectorRequest(request);
373+
372374
do {
373375
// if we fail to create a connection we do not retry and we do not wrap
374376

375377
GitHubConnectorResponse connectorResponse = null;
376378
try {
377379
try {
378-
logRequest(request);
380+
logRequest(connectorRequest);
379381
rateLimitChecker.checkRateLimit(this, request.rateLimitTarget());
380-
connectorResponse = connector.send(request);
382+
connectorResponse = connector.send(connectorRequest);
381383
noteRateLimit(request.rateLimitTarget(), connectorResponse);
382384
detectOTPRequired(connectorResponse);
383385

384386
if (isInvalidCached404Response(connectorResponse)) {
385387
// Setting "Cache-Control" to "no-cache" stops the cache from supplying
386388
// "If-Modified-Since" or "If-None-Match" values.
387389
// This makes GitHub give us current data (not incorrectly cached data)
388-
request = request.toBuilder().setHeader("Cache-Control", "no-cache").build();
390+
connectorRequest = prepareConnectorRequest(
391+
request.toBuilder().setHeader("Cache-Control", "no-cache").build());
389392
continue;
390393
}
391394
if (!(isRateLimitResponse(connectorResponse) || isAbuseLimitResponse(connectorResponse))) {
@@ -397,7 +400,7 @@ public <T> GitHubResponse<T> sendRequest(GitHubRequest request, @CheckForNull Bo
397400
continue;
398401
}
399402

400-
throw interpretApiError(e, request, connectorResponse);
403+
throw interpretApiError(e, connectorRequest, connectorResponse);
401404
}
402405

403406
handleLimitingErrors(connectorResponse);
@@ -410,7 +413,7 @@ public <T> GitHubResponse<T> sendRequest(GitHubRequest request, @CheckForNull Bo
410413
throw new GHIOException("Ran out of retries for URL: " + request.url().toString());
411414
}
412415

413-
private GitHubRequest prepareRequest(GitHubRequest request) throws IOException {
416+
private GitHubConnectorRequest prepareConnectorRequest(GitHubRequest request) throws IOException {
414417
GitHubRequest.Builder<?> builder = request.toBuilder();
415418
// if the authentication is needed but no credential is given, try it anyway (so that some calls
416419
// that do work with anonymous access in the reduced form should still work.)
@@ -442,7 +445,7 @@ private GitHubRequest prepareRequest(GitHubRequest request) throws IOException {
442445
return builder.build();
443446
}
444447

445-
private void logRequest(@Nonnull final GitHubRequest request) {
448+
private void logRequest(@Nonnull final GitHubConnectorRequest request) {
446449
LOGGER.log(FINE,
447450
() -> "GitHub API request [" + (getLogin() == null ? "anonymous" : getLogin()) + "]: "
448451
+ request.method() + " " + request.url().toString());
@@ -471,7 +474,7 @@ private static <T> GitHubResponse<T> createResponse(@Nonnull GitHubConnectorResp
471474
// workflow run cancellation - See https://docs.github.com/en/rest/reference/actions#cancel-a-workflow-run
472475

473476
LOGGER.log(FINE,
474-
"Received HTTP_ACCEPTED(202) from " + connectorResponse.url().toString()
477+
"Received HTTP_ACCEPTED(202) from " + connectorResponse.request().url().toString()
475478
+ " . Please try again in 5 seconds.");
476479
} else if (handler != null) {
477480
body = handler.apply(connectorResponse);
@@ -483,7 +486,7 @@ private static <T> GitHubResponse<T> createResponse(@Nonnull GitHubConnectorResp
483486
* Handle API error by either throwing it or by returning normally to retry.
484487
*/
485488
private static IOException interpretApiError(IOException e,
486-
@Nonnull GitHubRequest request,
489+
@Nonnull GitHubConnectorRequest connectorRequest,
487490
@CheckForNull GitHubConnectorResponse connectorResponse) throws IOException {
488491
// If we're already throwing a GHIOException, pass through
489492
if (e instanceof GHIOException) {
@@ -508,12 +511,12 @@ private static IOException interpretApiError(IOException e,
508511
e = new GHFileNotFoundException(e.getMessage() + " " + errorMessage, e)
509512
.withResponseHeaderFields(headers);
510513
} else if (statusCode >= 0) {
511-
e = new HttpException(errorMessage, statusCode, message, request.url().toString(), e);
514+
e = new HttpException(errorMessage, statusCode, message, connectorRequest.url().toString(), e);
512515
} else {
513516
e = new GHIOException(errorMessage).withResponseHeaderFields(headers);
514517
}
515518
} else if (!(e instanceof FileNotFoundException)) {
516-
e = new HttpException(statusCode, message, request.url().toString(), e);
519+
e = new HttpException(statusCode, message, connectorRequest.url().toString(), e);
517520
}
518521
return e;
519522
}
@@ -548,7 +551,7 @@ private static boolean retryConnectionError(IOException e, URL url, int retries)
548551

549552
private static boolean isInvalidCached404Response(GitHubConnectorResponse connectorResponse) {
550553
// WORKAROUND FOR ISSUE #669:
551-
// When the Requester detects a 404 response with an ETag (only happpens when the server's 304
554+
// When the Requester detects a 404 response with an ETag (only happens when the server's 304
552555
// is bogus and would cause cache corruption), try the query again with new request header
553556
// that forces the server to not return 304 and return new data instead.
554557
//
@@ -561,7 +564,7 @@ private static boolean isInvalidCached404Response(GitHubConnectorResponse connec
561564
&& connectorResponse.header("ETag") != null
562565
&& !Objects.equals(connectorResponse.request().header("Cache-Control"), "no-cache")) {
563566
LOGGER.log(FINE,
564-
"Encountered GitHub invalid cached 404 from " + connectorResponse.url()
567+
"Encountered GitHub invalid cached 404 from " + connectorResponse.request().url()
565568
+ ". Retrying with \"Cache-Control\"=\"no-cache\"...");
566569
return true;
567570
}
@@ -735,7 +738,11 @@ static ObjectReader getMappingObjectReader(@CheckForNull GitHubConnectorResponse
735738

736739
if (connectorResponse != null) {
737740
injected.put(GitHubConnectorResponse.class.getName(), connectorResponse);
738-
injected.putAll(connectorResponse.request().injectedMappingValues());
741+
GitHubConnectorRequest request = connectorResponse.request();
742+
// This is cheating, but it is an acceptable cheat for now.
743+
if (request instanceof GitHubRequest) {
744+
injected.putAll(((GitHubRequest) connectorResponse.request()).injectedMappingValues());
745+
}
739746
}
740747
return MAPPER.reader(new InjectableValues.Std(injected));
741748
}

src/main/java/org/kohsuke/github/GitHubResponseInfoHttpURLConnectionAdapter.java renamed to src/main/java/org/kohsuke/github/GitHubConnectorResponseHttpUrlConnectionAdapter.java

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,19 @@
88
import java.io.OutputStream;
99
import java.net.HttpURLConnection;
1010
import java.net.ProtocolException;
11-
import java.net.URL;
1211
import java.nio.charset.StandardCharsets;
1312
import java.security.Permission;
1413
import java.util.*;
1514

16-
class GitHubResponseInfoHttpURLConnectionAdapter extends HttpURLConnection {
15+
class GitHubConnectorResponseHttpUrlConnectionAdapter extends HttpURLConnection {
1716

1817
private static final Comparator<String> nullableCaseInsensitiveComparator = Comparator
1918
.nullsFirst(String.CASE_INSENSITIVE_ORDER);
2019

2120
private final GitHubConnectorResponse connectorResponse;
2221

23-
public GitHubResponseInfoHttpURLConnectionAdapter(GitHubConnectorResponse connectorResponse) {
24-
super(connectorResponse.url());
22+
public GitHubConnectorResponseHttpUrlConnectionAdapter(GitHubConnectorResponse connectorResponse) {
23+
super(connectorResponse.request().url());
2524
this.connectorResponse = connectorResponse;
2625
}
2726

@@ -121,11 +120,6 @@ public int getReadTimeout() {
121120
return super.getReadTimeout();
122121
}
123122

124-
@Override
125-
public URL getURL() {
126-
return connectorResponse.url();
127-
}
128-
129123
@Override
130124
public int getContentLength() {
131125
long l = getContentLengthLong();

src/main/java/org/kohsuke/github/GitHubResponse.java

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,12 @@
44
import com.fasterxml.jackson.databind.InjectableValues;
55
import com.fasterxml.jackson.databind.JsonMappingException;
66
import org.apache.commons.io.IOUtils;
7-
import org.kohsuke.github.connector.GitHubConnectorRequest;
87
import org.kohsuke.github.connector.GitHubConnectorResponse;
98

109
import java.io.IOException;
1110
import java.io.InputStreamReader;
1211
import java.lang.reflect.Array;
1312
import java.net.HttpURLConnection;
14-
import java.net.URL;
1513
import java.nio.charset.StandardCharsets;
1614
import java.util.*;
1715
import java.util.logging.Level;
@@ -35,9 +33,6 @@ class GitHubResponse<T> {
3533

3634
private final int statusCode;
3735

38-
@Nonnull
39-
private final GitHubConnectorRequest request;
40-
4136
@Nonnull
4237
private final Map<String, List<String>> headers;
4338

@@ -46,14 +41,12 @@ class GitHubResponse<T> {
4641

4742
GitHubResponse(GitHubResponse<T> response, @CheckForNull T body) {
4843
this.statusCode = response.statusCode();
49-
this.request = response.request();
5044
this.headers = response.headers;
5145
this.body = body;
5246
}
5347

5448
GitHubResponse(GitHubConnectorResponse connectorResponse, @CheckForNull T body) {
5549
this.statusCode = connectorResponse.statusCode();
56-
this.request = connectorResponse.request();
5750
this.headers = connectorResponse.allHeaders();
5851
this.body = body;
5952
}
@@ -138,26 +131,6 @@ static String getBodyAsString(GitHubConnectorResponse connectorResponse) throws
138131
return IOUtils.toString(r);
139132
}
140133

141-
/**
142-
* The {@link URL} for this response.
143-
*
144-
* @return the {@link URL} for this response.
145-
*/
146-
@Nonnull
147-
public URL url() {
148-
return request.url();
149-
}
150-
151-
/**
152-
* The {@link GitHubConnectorRequest} for this response.
153-
*
154-
* @return the {@link GitHubConnectorRequest} for this response.
155-
*/
156-
@Nonnull
157-
public GitHubConnectorRequest request() {
158-
return request;
159-
}
160-
161134
/**
162135
* The status code for this response.
163136
*

src/main/java/org/kohsuke/github/RateLimitHandler.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import java.io.InterruptedIOException;
77
import java.net.HttpURLConnection;
88

9+
import javax.annotation.Nonnull;
10+
911
/**
1012
* Pluggable strategy to determine what to do when the API rate limit is reached.
1113
*
@@ -30,12 +32,12 @@ public abstract class RateLimitHandler {
3032
* the io exception
3133
* @see <a href="https://developer.github.com/v3/#rate-limiting">API documentation from GitHub</a>
3234
*/
33-
void onError(GitHubConnectorResponse connectorResponse) throws IOException {
35+
public void onError(@Nonnull GitHubConnectorResponse connectorResponse) throws IOException {
3436
GHIOException e = new HttpException("Rate limit violation",
3537
connectorResponse.statusCode(),
3638
connectorResponse.header("Status"),
37-
connectorResponse.url().toString()).withResponseHeaderFields(connectorResponse.allHeaders());
38-
onError(e, new GitHubResponseInfoHttpURLConnectionAdapter(connectorResponse));
39+
connectorResponse.request().url().toString()).withResponseHeaderFields(connectorResponse.allHeaders());
40+
onError(e, new GitHubConnectorResponseHttpUrlConnectionAdapter(connectorResponse));
3941
}
4042

4143
/**
@@ -55,7 +57,9 @@ void onError(GitHubConnectorResponse connectorResponse) throws IOException {
5557
* the io exception
5658
* @see <a href="https://developer.github.com/v3/#rate-limiting">API documentation from GitHub</a>
5759
*/
58-
public abstract void onError(IOException e, HttpURLConnection uc) throws IOException;
60+
@Deprecated
61+
public void onError(IOException e, HttpURLConnection uc) throws IOException {
62+
}
5963

6064
/**
6165
* Block until the API rate limit is reset. Useful for long-running batch processing.

src/main/java/org/kohsuke/github/authorization/OrgAppInstallationAuthorizationProvider.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class OrgAppInstallationAuthorizationProvider extends GitHub.DependentAut
1919

2020
private final String organizationName;
2121

22-
private String latestToken;
22+
private String authorization;
2323

2424
@Nonnull
2525
private Instant validUntil = Instant.MIN;
@@ -44,19 +44,20 @@ public OrgAppInstallationAuthorizationProvider(String organizationName,
4444
@Override
4545
public String getEncodedAuthorization() throws IOException {
4646
synchronized (this) {
47-
if (latestToken == null || Instant.now().isAfter(this.validUntil)) {
48-
refreshToken();
47+
if (authorization == null || Instant.now().isAfter(this.validUntil)) {
48+
String token = refreshToken();
49+
authorization = String.format("token %s", token);
4950
}
50-
return String.format("token %s", latestToken);
51+
return authorization;
5152
}
5253
}
5354

54-
private void refreshToken() throws IOException {
55+
private String refreshToken() throws IOException {
5556
GitHub gitHub = this.gitHub();
5657
GHAppInstallation installationByOrganization = gitHub.getApp()
5758
.getInstallationByOrganization(this.organizationName);
5859
GHAppInstallationToken ghAppInstallationToken = installationByOrganization.createToken().create();
5960
this.validUntil = ghAppInstallationToken.getExpiresAt().toInstant().minus(Duration.ofMinutes(5));
60-
this.latestToken = Objects.requireNonNull(ghAppInstallationToken.getToken());
61+
return Objects.requireNonNull(ghAppInstallationToken.getToken());
6162
}
6263
}

0 commit comments

Comments
 (0)