diff --git a/.github/workflows/maven-build.yml b/.github/workflows/maven-build.yml index 5ce3de342a..9054fef941 100644 --- a/.github/workflows/maven-build.yml +++ b/.github/workflows/maven-build.yml @@ -112,25 +112,6 @@ jobs: fail_ci_if_error: true verbose: true - test-java-8: - name: test Java 8 (no-build) - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/download-artifact@v4 - with: - name: maven-target-directory - path: target - - name: Set up JDK - uses: actions/setup-java@v4 - with: - java-version: 8 - distribution: 'temurin' - cache: 'maven' - - name: Maven Test (no build) Java 8 - run: mvn -B surefire:test -DfailIfNoTests -Dsurefire.excludesFile=src/test/resources/slow-or-flaky-tests.txt - test-java-11: name: test Java 11 (no-build) needs: build @@ -144,7 +125,7 @@ jobs: - name: Set up JDK uses: actions/setup-java@v4 with: - java-version: 8 + java-version: 11 distribution: 'temurin' cache: 'maven' - name: Maven Test (no build) Java 11 diff --git a/pom.xml b/pom.xml index b0622b27e5..3f5381294d 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 org.kohsuke github-api - 1.326-SNAPSHOT + 2.0.0-alpha-1-SNAPSHOT GitHub API for Java https://github-api.kohsuke.org/ GitHub API for Java @@ -63,14 +63,6 @@ maven-scm-manager-plexus 2.1.0 - - @@ -117,11 +109,7 @@ - /org/kohsuke/github/extras/HttpClient* /org/kohsuke/github/example/* - /org/kohsuke/github/extras/OkHttpConnector* - /org/kohsuke/github/extras/OkHttp3Connector* - /org/kohsuke/github/extras/okhttp3/ObsoleteUrlFactory* @@ -172,23 +160,14 @@ - - org.kohsuke.github.extras.HttpClientGitHubConnector.** - org.kohsuke.github.extras.HttpClientGitHubConnector - - - org.kohsuke.github.extras.okhttp3.ObsoleteUrlFactory.** - org.kohsuke.github.extras.okhttp3.ObsoleteUrlFactory + + org.kohsuke.github.GHRepositorySearchBuilder.Fork org.kohsuke.github.example.* - - org.kohsuke.github.extras.OkHttpConnector - org.kohsuke.github.extras.OkHttp3Connector - org.kohsuke.github.EnforcementLevel - org.kohsuke.github.GHPerson.1 - org.kohsuke.github.GHCompare.User + + org.kohsuke.github.GHCommit.GHAuthor org.kohsuke.github.GHIssue.PullRequest @@ -225,7 +204,7 @@ maven-javadoc-plugin 3.8.0 - 8 + 11 true all @@ -298,34 +277,16 @@ maven-compiler-plugin 3.13.0 - 1.8 - 1.8 + 11 + 11 org.jenkins-ci annotation-indexer - 1.12 + 1.17 - - - compile-java-11 - compile - - compile - - - 11 - 11 - 11 - - ${project.basedir}/src/main/java11 - - true - - - maven-surefire-plugin @@ -349,27 +310,10 @@ org.kohsuke.github.api - true - - org.codehaus.mojo - animal-sniffer-maven-plugin - - - com.infradna.tool - bridge-method-injector - 1.29 - - - - process - - - - com.diffplug.spotless spotless-maven-plugin @@ -388,7 +332,6 @@ src/main/java/**/*.java - src/main/java11/**/*.java src/test/java/**/*.java @@ -436,17 +379,16 @@ com.github.siom79.japicmp japicmp-maven-plugin - 0.17.2 + 0.21.2 - true + + true true org.kohsuke.github.internal - - org.kohsuke.github.extras.HttpClientGitHubConnector#HttpClientGitHubConnector(java.net.http.HttpClient) @@ -555,37 +497,10 @@ 1.29 true - - commons-fileupload - commons-fileupload - 1.5 - test - - - - commons-discovery - commons-discovery - 0.5 - test - - - - org.kohsuke.stapler - stapler - 1.263 - test - - - org.kohsuke.stapler - stapler-jetty - 1.1 - test - - - org.eclipse.jgit - org.eclipse.jgit - 6.7.0.202309050840-r + com.google.guava + guava + 33.1.0-jre test @@ -618,20 +533,6 @@ ${okhttp3.version} true - - - - com.squareup.okhttp3 - okhttp-urlconnection - 3.12.3 - true - - - com.squareup.okhttp - okhttp-urlconnection - 2.7.5 - true - org.kohsuke wordnet-random-name @@ -684,7 +585,7 @@ - test-jwt-slow-multireleasejar-flaky + test-jwt-slow-flaky !test @@ -708,7 +609,7 @@ - java11-test + httpclient-test integration-test test @@ -724,23 +625,6 @@ - - java11-urlconnection-test - integration-test - - test - - - ${project.basedir}/target/${project.artifactId}-${project.version}.jar - false - src/test/resources/slow-or-flaky-tests.txt - @{jacoco.surefire.argLine} ${surefire.argLine} -Dtest.github.connector=urlconnection - - - src/test/resources/test-trace-logging.properties - - - slow-or-flaky-test integration-test diff --git a/src/main/java/org/kohsuke/github/AbuseLimitHandler.java b/src/main/java/org/kohsuke/github/AbuseLimitHandler.java deleted file mode 100644 index 09084080a7..0000000000 --- a/src/main/java/org/kohsuke/github/AbuseLimitHandler.java +++ /dev/null @@ -1,125 +0,0 @@ -package org.kohsuke.github; - -import org.kohsuke.github.connector.GitHubConnectorResponse; - -import java.io.IOException; -import java.io.InterruptedIOException; -import java.net.HttpURLConnection; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; -import java.time.temporal.ChronoUnit; - -import javax.annotation.Nonnull; - -// TODO: Auto-generated Javadoc -/** - * Pluggable strategy to determine what to do when the API abuse limit is hit. - * - * @author Kohsuke Kawaguchi - * @see GitHubBuilder#withAbuseLimitHandler(GitHubAbuseLimitHandler) - * GitHubBuilder#withAbuseLimitHandler(GitHubAbuseLimitHandler) - * @see documentation - * @see RateLimitHandler - * @deprecated Switch to {@link GitHubAbuseLimitHandler}. - */ -@Deprecated -public abstract class AbuseLimitHandler extends GitHubAbuseLimitHandler { - - /** - * Called when the library encounters HTTP error indicating that the API abuse limit is reached. - * - *

- * Any exception thrown from this method will cause the request to fail, and the caller of github-api will receive - * an exception. If this method returns normally, another request will be attempted. For that to make sense, the - * implementation needs to wait for some time. - * - * @param connectorResponse - * Response information for this request. - * @throws IOException - * on failure - * @see API documentation from GitHub - * @see Dealing - * with abuse rate limits - * - */ - public void onError(@Nonnull GitHubConnectorResponse connectorResponse) throws IOException { - GHIOException e = new HttpException("Abuse limit reached", - connectorResponse.statusCode(), - connectorResponse.header("Status"), - connectorResponse.request().url().toString()).withResponseHeaderFields(connectorResponse.allHeaders()); - onError(e, connectorResponse.toHttpURLConnection()); - } - - /** - * Called when the library encounters HTTP error indicating that the API abuse limit is reached. - * - *

- * Any exception thrown from this method will cause the request to fail, and the caller of github-api will receive - * an exception. If this method returns normally, another request will be attempted. For that to make sense, the - * implementation needs to wait for some time. - * - * @param e - * Exception from Java I/O layer. If you decide to fail the processing, you can throw this exception (or - * wrap this exception into another exception and throw it). - * @param uc - * Connection that resulted in an error. Useful for accessing other response headers. - * @throws IOException - * on failure - * @see API documentation from GitHub - * @see Dealing - * with abuse rate limits - * - */ - @Deprecated - public abstract void onError(IOException e, HttpURLConnection uc) throws IOException; - - /** - * Wait until the API abuse "wait time" is passed. - */ - @Deprecated - public static final AbuseLimitHandler WAIT = new AbuseLimitHandler() { - @Override - public void onError(IOException e, HttpURLConnection uc) throws IOException { - try { - Thread.sleep(parseWaitTime(uc)); - } catch (InterruptedException ex) { - throw (InterruptedIOException) new InterruptedIOException().initCause(e); - } - } - - }; - - /** - * Fail immediately. - */ - @Deprecated - public static final AbuseLimitHandler FAIL = new AbuseLimitHandler() { - @Override - public void onError(IOException e, HttpURLConnection uc) throws IOException { - throw e; - } - }; - - /* - * Exposed for testability. Given an http response, find the retry-after header field and parse it as either a - * number or a date (the spec allows both). If no header is found, wait for a reasonably amount of time. - */ - long parseWaitTime(HttpURLConnection uc) { - String v = uc.getHeaderField("Retry-After"); - if (v == null) { - // can't tell, wait for unambiguously over one minute per GitHub guidance - return 61 * 1000; - } - - try { - return Math.max(1000, Long.parseLong(v) * 1000); - } catch (NumberFormatException nfe) { - // The retry-after header could be a number in seconds, or an http-date - ZonedDateTime zdt = ZonedDateTime.parse(v, DateTimeFormatter.RFC_1123_DATE_TIME); - return ChronoUnit.MILLIS.between(ZonedDateTime.now(), zdt); - } - } - -} diff --git a/src/main/java/org/kohsuke/github/BetaApi.java b/src/main/java/org/kohsuke/github/BetaApi.java index 1c33b7daa3..22ae2d76a6 100644 --- a/src/main/java/org/kohsuke/github/BetaApi.java +++ b/src/main/java/org/kohsuke/github/BetaApi.java @@ -5,12 +5,9 @@ import java.lang.annotation.RetentionPolicy; /** - * Indicates that the method/class/etc marked is a beta implementation of an sdk feature. + * Indicates that the method/class/etc marked is a beta implementation of an SDK feature. *

- * These APIs are subject to change and not a part of the backward compatibility commitment. Always used in conjunction - * with 'deprecated' to raise awareness to clients. - *

- * + * These APIs are subject to change and not a part of the backward compatibility commitment. */ @Retention(RetentionPolicy.RUNTIME) @Documented diff --git a/src/main/java/org/kohsuke/github/EnforcementLevel.java b/src/main/java/org/kohsuke/github/EnforcementLevel.java deleted file mode 100644 index 0cc69500a9..0000000000 --- a/src/main/java/org/kohsuke/github/EnforcementLevel.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.kohsuke.github; - -import java.util.Locale; - -// TODO: Auto-generated Javadoc -/** - * This was added during preview API period but it has changed since then. - * - * @author Kohsuke Kawaguchi - */ -@Deprecated -public enum EnforcementLevel { - - /** The off. */ - OFF, - /** The non admins. */ - NON_ADMINS, - /** The everyone. */ - EVERYONE; - - /** - * To string. - * - * @return the string - */ - public String toString() { - return name().toLowerCase(Locale.ENGLISH); - } -} diff --git a/src/main/java/org/kohsuke/github/GHApp.java b/src/main/java/org/kohsuke/github/GHApp.java index 904b7c3696..fd8dba0120 100644 --- a/src/main/java/org/kohsuke/github/GHApp.java +++ b/src/main/java/org/kohsuke/github/GHApp.java @@ -40,18 +40,6 @@ public GHUser getOwner() { return owner; } - /** - * Sets owner. - * - * @param owner - * the owner - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setOwner(GHUser owner) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets name. * @@ -70,18 +58,6 @@ public String getSlug() { return slug; } - /** - * Sets name. - * - * @param name - * the name - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setName(String name) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets description. * @@ -91,18 +67,6 @@ public String getDescription() { return description; } - /** - * Sets description. - * - * @param description - * the description - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setDescription(String description) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets external url. * @@ -112,18 +76,6 @@ public String getExternalUrl() { return externalUrl; } - /** - * Sets external url. - * - * @param externalUrl - * the external url - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setExternalUrl(String externalUrl) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets events. * @@ -135,18 +87,6 @@ public List getEvents() { .collect(Collectors.toList()); } - /** - * Sets events. - * - * @param events - * the events - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setEvents(List events) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets installations count. * @@ -156,18 +96,6 @@ public long getInstallationsCount() { return installationsCount; } - /** - * Sets installations count. - * - * @param installationsCount - * the installations count - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setInstallationsCount(long installationsCount) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets the html url. * @@ -186,18 +114,6 @@ public Map getPermissions() { return Collections.unmodifiableMap(permissions); } - /** - * Sets permissions. - * - * @param permissions - * the permissions - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setPermissions(Map permissions) { - throw new RuntimeException("Do not use this method."); - } - /** * Obtains all the installations associated with this app. *

diff --git a/src/main/java/org/kohsuke/github/GHAppCreateTokenBuilder.java b/src/main/java/org/kohsuke/github/GHAppCreateTokenBuilder.java index 348282ecf6..edab276e90 100644 --- a/src/main/java/org/kohsuke/github/GHAppCreateTokenBuilder.java +++ b/src/main/java/org/kohsuke/github/GHAppCreateTokenBuilder.java @@ -10,7 +10,6 @@ * Creates a access token for a GitHub App Installation. * * @author Paulo Miguel Almeida - * @see GHAppInstallation#createToken(Map) GHAppInstallation#createToken(Map) * @see GHAppInstallation#createToken() GHAppInstallation#createToken() */ public class GHAppCreateTokenBuilder extends GitHubInteractiveObject { @@ -34,22 +33,6 @@ public class GHAppCreateTokenBuilder extends GitHubInteractiveObject { this.builder = root.createRequest(); } - /** - * Instantiates a new GH app create token builder. - * - * @param root - * the root - * @param apiUrlTail - * the api url tail - * @param permissions - * the permissions - */ - @BetaApi - GHAppCreateTokenBuilder(GitHub root, String apiUrlTail, Map permissions) { - this(root, apiUrlTail); - permissions(permissions); - } - /** * By default the installation token has access to all repositories that the installation can access. To restrict * the access to specific repositories, you can provide the repository_ids when creating the token. When you omit diff --git a/src/main/java/org/kohsuke/github/GHAppInstallation.java b/src/main/java/org/kohsuke/github/GHAppInstallation.java index 0e18ec6800..72731cdd03 100644 --- a/src/main/java/org/kohsuke/github/GHAppInstallation.java +++ b/src/main/java/org/kohsuke/github/GHAppInstallation.java @@ -55,18 +55,6 @@ public URL getHtmlUrl() { return GitHubClient.parseURL(htmlUrl); } - /** - * Sets root. - * - * @param root - * the root - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setRoot(GitHub root) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets account. * @@ -77,18 +65,6 @@ public GHUser getAccount() { return account; } - /** - * Sets account. - * - * @param account - * the account - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setAccount(GHUser account) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets access token url. * @@ -98,18 +74,6 @@ public String getAccessTokenUrl() { return accessTokenUrl; } - /** - * Sets access token url. - * - * @param accessTokenUrl - * the access token url - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setAccessTokenUrl(String accessTokenUrl) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets repositories url. * @@ -125,10 +89,9 @@ public String getRepositoriesUrl() { * @return the paged iterable * @deprecated This method cannot work on a {@link GHAppInstallation} retrieved from * {@link GHApp#listInstallations()} (for example), except when resorting to unsupported hacks involving - * {@link GHAppInstallation#setRoot(GitHub)} to switch from an application client to an installation - * client. This method will be removed. You should instead use an installation client (with an - * installation token, not a JWT), retrieve a {@link GHAuthenticatedAppInstallation} from - * {@link GitHub#getInstallation()}, then call + * setRoot(GitHub) to switch from an application client to an installation client. This method will be + * removed. You should instead use an installation client (with an installation token, not a JWT), + * retrieve a {@link GHAuthenticatedAppInstallation} from {@link GitHub#getInstallation()}, then call * {@link GHAuthenticatedAppInstallation#listRepositories()}. */ @Deprecated @@ -149,18 +112,6 @@ GHRepository[] getItems(GitHub root) { } } - /** - * Sets repositories url. - * - * @param repositoriesUrl - * the repositories url - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setRepositoriesUrl(String repositoriesUrl) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets app id. * @@ -170,18 +121,6 @@ public long getAppId() { return appId; } - /** - * Sets app id. - * - * @param appId - * the app id - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setAppId(long appId) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets target id. * @@ -191,18 +130,6 @@ public long getTargetId() { return targetId; } - /** - * Sets target id. - * - * @param targetId - * the target id - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setTargetId(long targetId) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets target type. * @@ -212,18 +139,6 @@ public GHTargetType getTargetType() { return targetType; } - /** - * Sets target type. - * - * @param targetType - * the target type - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setTargetType(GHTargetType targetType) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets permissions. * @@ -233,18 +148,6 @@ public Map getPermissions() { return Collections.unmodifiableMap(permissions); } - /** - * Sets permissions. - * - * @param permissions - * the permissions - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setPermissions(Map permissions) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets events. * @@ -256,18 +159,6 @@ public List getEvents() { .collect(Collectors.toList()); } - /** - * Sets events. - * - * @param events - * the events - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setEvents(List events) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets single file name. * @@ -277,18 +168,6 @@ public String getSingleFileName() { return singleFileName; } - /** - * Sets single file name. - * - * @param singleFileName - * the single file name - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setSingleFileName(String singleFileName) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets repository selection. * @@ -298,18 +177,6 @@ public GHRepositorySelection getRepositorySelection() { return repositorySelection; } - /** - * Sets repository selection. - * - * @param repositorySelection - * the repository selection - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setRepositorySelection(GHRepositorySelection repositorySelection) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets suspended at. * @@ -354,11 +221,9 @@ public void deleteInstallation() throws IOException { * @return a GHAppCreateTokenBuilder instance * @deprecated Use {@link GHAppInstallation#createToken()} instead. */ - @BetaApi + @Deprecated public GHAppCreateTokenBuilder createToken(Map permissions) { - return new GHAppCreateTokenBuilder(root(), - String.format("/app/installations/%d/access_tokens", getId()), - permissions); + return createToken().permissions(permissions); } /** @@ -370,7 +235,6 @@ public GHAppCreateTokenBuilder createToken(Map permiss * * @return a GHAppCreateTokenBuilder instance */ - @BetaApi public GHAppCreateTokenBuilder createToken() { return new GHAppCreateTokenBuilder(root(), String.format("/app/installations/%d/access_tokens", getId())); } diff --git a/src/main/java/org/kohsuke/github/GHAppInstallationToken.java b/src/main/java/org/kohsuke/github/GHAppInstallationToken.java index 415cc996bc..e9bccdb139 100644 --- a/src/main/java/org/kohsuke/github/GHAppInstallationToken.java +++ b/src/main/java/org/kohsuke/github/GHAppInstallationToken.java @@ -1,8 +1,5 @@ package org.kohsuke.github; -import com.infradna.tool.bridge_method_injector.WithBridgeMethods; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; - import java.io.IOException; import java.util.*; @@ -11,7 +8,7 @@ * A Github App Installation Token. * * @author Paulo Miguel Almeida - * @see GHAppInstallation#createToken(Map) GHAppInstallation#createToken(Map) + * @see GHAppInstallation#createToken() GHAppInstallation#createToken() */ public class GHAppInstallationToken extends GitHubInteractiveObject { private String token; @@ -22,18 +19,6 @@ public class GHAppInstallationToken extends GitHubInteractiveObject { private List repositories; private GHRepositorySelection repositorySelection; - /** - * Sets root. - * - * @param root - * the root - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setRoot(GitHub root) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets permissions. * @@ -43,18 +28,6 @@ public Map getPermissions() { return Collections.unmodifiableMap(permissions); } - /** - * Sets permissions. - * - * @param permissions - * the permissions - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setPermissions(Map permissions) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets token. * @@ -64,18 +37,6 @@ public String getToken() { return token; } - /** - * Sets token. - * - * @param token - * the token - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setToken(String token) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets repositories. * @@ -85,18 +46,6 @@ public List getRepositories() { return GitHubClient.unmodifiableListOrNull(repositories); } - /** - * Sets repositories. - * - * @param repositories - * the repositories - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setRepositories(List repositories) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets repository selection. * @@ -106,18 +55,6 @@ public GHRepositorySelection getRepositorySelection() { return repositorySelection; } - /** - * Sets repository selection. - * - * @param repositorySelection - * the repository selection - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setRepositorySelection(GHRepositorySelection repositorySelection) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets expires at. * @@ -125,13 +62,7 @@ public void setRepositorySelection(GHRepositorySelection repositorySelection) { * @throws IOException * on error */ - @WithBridgeMethods(value = String.class, adapterMethod = "expiresAtStr") public Date getExpiresAt() throws IOException { return GitHubClient.parseDate(expires_at); } - - @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Bridge method of getExpiresAt") - private Object expiresAtStr(Date id, Class type) { - return expires_at; - } } diff --git a/src/main/java/org/kohsuke/github/GHArtifact.java b/src/main/java/org/kohsuke/github/GHArtifact.java index a50454d0d0..0cd6fbb0cc 100644 --- a/src/main/java/org/kohsuke/github/GHArtifact.java +++ b/src/main/java/org/kohsuke/github/GHArtifact.java @@ -85,19 +85,6 @@ public GHRepository getRepository() { return owner; } - /** - * Gets the html url. - * - * @return the html url - * @throws IOException - * Signals that an I/O exception has occurred. - * @deprecated This object has no HTML URL. - */ - @Override - public URL getHtmlUrl() throws IOException { - return null; - } - /** * Deletes the artifact. * diff --git a/src/main/java/org/kohsuke/github/GHAsset.java b/src/main/java/org/kohsuke/github/GHAsset.java index d64116f5eb..15210408aa 100644 --- a/src/main/java/org/kohsuke/github/GHAsset.java +++ b/src/main/java/org/kohsuke/github/GHAsset.java @@ -3,7 +3,6 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.io.IOException; -import java.net.URL; // TODO: Auto-generated Javadoc /** @@ -113,17 +112,6 @@ public String getState() { return state; } - /** - * Gets the html url. - * - * @return the html url - * @deprecated This object has no HTML URL. - */ - @Override - public URL getHtmlUrl() { - return null; - } - /** * Gets browser download url. * diff --git a/src/main/java/org/kohsuke/github/GHAuthorization.java b/src/main/java/org/kohsuke/github/GHAuthorization.java index 5286750ed7..82fa354ab7 100644 --- a/src/main/java/org/kohsuke/github/GHAuthorization.java +++ b/src/main/java/org/kohsuke/github/GHAuthorization.java @@ -136,29 +136,6 @@ public String getAppName() { return app.name; } - /** - * Gets api url. - * - * @return the api url - * @deprecated use {@link #getUrl()} - */ - @Deprecated - @SuppressFBWarnings(value = "NM_CONFUSING", justification = "It's a part of the library API, cannot be changed") - public URL getApiURL() { - return getUrl(); - } - - /** - * Gets the html url. - * - * @return the html url - * @deprecated This object has no HTML URL. - */ - @Override - public URL getHtmlUrl() { - return null; - } - /** * Gets note. * diff --git a/src/main/java/org/kohsuke/github/GHBranch.java b/src/main/java/org/kohsuke/github/GHBranch.java index 21dc55717d..8a37b645c4 100644 --- a/src/main/java/org/kohsuke/github/GHBranch.java +++ b/src/main/java/org/kohsuke/github/GHBranch.java @@ -6,7 +6,6 @@ import java.io.IOException; import java.net.URL; -import java.util.Collection; import java.util.Objects; import javax.annotation.CheckForNull; @@ -134,32 +133,6 @@ public GHBranchProtectionBuilder enableProtection() { return new GHBranchProtectionBuilder(this); } - /** - * Enable protection. - * - * @param level - * the level - * @param contexts - * the contexts - * @throws IOException - * the io exception - */ - // backward compatibility with previous signature - @Deprecated - public void enableProtection(EnforcementLevel level, Collection contexts) throws IOException { - switch (level) { - case OFF : - disableProtection(); - break; - case NON_ADMINS : - case EVERYONE : - enableProtection().addRequiredChecks(contexts) - .includeAdmins(level == EnforcementLevel.EVERYONE) - .enable(); - break; - } - } - /** * Merge a branch into this branch. * diff --git a/src/main/java/org/kohsuke/github/GHBranchProtectionBuilder.java b/src/main/java/org/kohsuke/github/GHBranchProtectionBuilder.java index 640818af17..c56e7f2197 100644 --- a/src/main/java/org/kohsuke/github/GHBranchProtectionBuilder.java +++ b/src/main/java/org/kohsuke/github/GHBranchProtectionBuilder.java @@ -11,7 +11,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.stream.Collectors; // TODO: Auto-generated Javadoc /** @@ -54,34 +53,6 @@ public GHBranchProtectionBuilder addRequiredStatusChecks(Collection checks) { - getStatusChecks().checks.addAll(checks.stream() - .map(context -> new GHBranchProtection.Check(context, null)) - .collect(Collectors.toList())); - return this; - } - - /** - * Add required checks gh branch protection builder. - * - * @param checks - * the checks - * @return the gh branch protection builder - */ - @Deprecated - public GHBranchProtectionBuilder addRequiredChecks(String... checks) { - addRequiredChecks(Arrays.asList(checks)); - return this; - } - /** * Add required checks gh branch protection builder. * diff --git a/src/main/java/org/kohsuke/github/GHCheckRun.java b/src/main/java/org/kohsuke/github/GHCheckRun.java index 0593656cfe..e06bdc35a2 100644 --- a/src/main/java/org/kohsuke/github/GHCheckRun.java +++ b/src/main/java/org/kohsuke/github/GHCheckRun.java @@ -1,7 +1,6 @@ package org.kohsuke.github; import com.fasterxml.jackson.annotation.JsonProperty; -import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import org.kohsuke.github.internal.EnumUtils; @@ -86,16 +85,10 @@ GHCheckRun wrap(GitHub root) { * @return Status of the check run * @see Status */ - @WithBridgeMethods(value = String.class, adapterMethod = "statusAsStr") public Status getStatus() { return Status.from(status); } - @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Bridge method of getStatus") - private Object statusAsStr(Status status, Class type) { - return status; - } - /** * The Enum Status. */ @@ -138,16 +131,10 @@ public String toString() { * @return Status of the check run * @see Conclusion */ - @WithBridgeMethods(value = String.class, adapterMethod = "conclusionAsStr") public Conclusion getConclusion() { return Conclusion.from(conclusion); } - @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Bridge method of getConclusion") - private Object conclusionAsStr(Conclusion conclusion, Class type) { - return conclusion; - } - /** * Final conclusion of the check. * @@ -239,7 +226,6 @@ public List getPullRequests() throws IOException { * * @return HTML URL */ - @Override public URL getHtmlUrl() { return GitHubClient.parseURL(htmlUrl); } diff --git a/src/main/java/org/kohsuke/github/GHCheckSuite.java b/src/main/java/org/kohsuke/github/GHCheckSuite.java index ee70b4c74f..2048bdaaf6 100644 --- a/src/main/java/org/kohsuke/github/GHCheckSuite.java +++ b/src/main/java/org/kohsuke/github/GHCheckSuite.java @@ -201,16 +201,6 @@ public List getPullRequests() throws IOException { return Collections.emptyList(); } - /** - * Check suite doesn't have a HTML URL. - * - * @return null - */ - @Override - public URL getHtmlUrl() { - return null; - } - /** * The Class HeadCommit. */ diff --git a/src/main/java/org/kohsuke/github/GHCommit.java b/src/main/java/org/kohsuke/github/GHCommit.java index acdf943991..4686f7fdf9 100644 --- a/src/main/java/org/kohsuke/github/GHCommit.java +++ b/src/main/java/org/kohsuke/github/GHCommit.java @@ -85,32 +85,6 @@ public List getParentSHA1s() { } - /** - * The type GHAuthor. - * - * @deprecated Use {@link GitUser} instead. - */ - @Deprecated - public static class GHAuthor extends GitUser { - - /** - * Instantiates a new GH author. - */ - public GHAuthor() { - super(); - } - - /** - * Instantiates a new GH author. - * - * @param user - * the user - */ - public GHAuthor(GitUser user) { - super(user); - } - } - /** * The type Stats. */ @@ -407,19 +381,6 @@ public URL getUrl() { return GitHubClient.parseURL(url); } - /** - * List of files changed/added/removed in this commit. - * - * @return Can be empty but never null. - * @throws IOException - * on error - * @deprecated Use {@link #listFiles()} instead. - */ - @Deprecated - public List getFiles() throws IOException { - return listFiles().toList(); - } - /** * List of files changed/added/removed in this commit. Uses a paginated list if the files returned by GitHub exceed * 300 in quantity. diff --git a/src/main/java/org/kohsuke/github/GHCommitStatus.java b/src/main/java/org/kohsuke/github/GHCommitStatus.java index 45a5d94360..808b6f9df0 100644 --- a/src/main/java/org/kohsuke/github/GHCommitStatus.java +++ b/src/main/java/org/kohsuke/github/GHCommitStatus.java @@ -1,7 +1,6 @@ package org.kohsuke.github; import java.io.IOException; -import java.net.URL; // TODO: Auto-generated Javadoc /** @@ -80,14 +79,4 @@ public String getContext() { return context; } - /** - * Gets the html url. - * - * @return the html url - * @deprecated This object has no HTML URL. - */ - @Override - public URL getHtmlUrl() { - return null; - } } diff --git a/src/main/java/org/kohsuke/github/GHCompare.java b/src/main/java/org/kohsuke/github/GHCompare.java index 08c6f051b1..4951917087 100644 --- a/src/main/java/org/kohsuke/github/GHCompare.java +++ b/src/main/java/org/kohsuke/github/GHCompare.java @@ -1,7 +1,6 @@ package org.kohsuke.github; import com.fasterxml.jackson.annotation.JacksonInject; -import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.io.IOException; @@ -198,18 +197,6 @@ public GHCommit.File[] getFiles() { return newValue; } - /** - * Wrap gh compare. - * - * @param owner - * the owner - * @return the gh compare - */ - @Deprecated - public GHCompare wrap(GHRepository owner) { - throw new RuntimeException("Do not use this method."); - } - /** * Wrap gh compare. * @@ -252,7 +239,7 @@ public InnerCommit getCommit() { */ public static class InnerCommit { private String url, sha, message; - private User author, committer; + private GitUser author, committer; private Tree tree; /** @@ -287,7 +274,6 @@ public String getMessage() { * * @return the author */ - @WithBridgeMethods(value = User.class, castRequired = true) public GitUser getAuthor() { return author; } @@ -297,7 +283,6 @@ public GitUser getAuthor() { * * @return the committer */ - @WithBridgeMethods(value = User.class, castRequired = true) public GitUser getCommitter() { return committer; } @@ -337,14 +322,6 @@ public String getSha() { } } - /** - * The type User. - * - * @deprecated use {@link GitUser} instead. - */ - public static class User extends GitUser { - } - /** * The enum Status. */ diff --git a/src/main/java/org/kohsuke/github/GHContent.java b/src/main/java/org/kohsuke/github/GHContent.java index c476a89d8c..d3d86ecb39 100644 --- a/src/main/java/org/kohsuke/github/GHContent.java +++ b/src/main/java/org/kohsuke/github/GHContent.java @@ -121,9 +121,10 @@ public String getTarget() { * the io exception * @deprecated Use {@link #read()} */ + @Deprecated @SuppressFBWarnings("DM_DEFAULT_ENCODING") public String getContent() throws IOException { - return new String(Base64.getMimeDecoder().decode(getEncodedContent())); + return new String(readDecodedContent()); } /** @@ -138,6 +139,7 @@ public String getContent() throws IOException { * the io exception * @deprecated Use {@link #read()} */ + @Deprecated public String getEncodedContent() throws IOException { refresh(content); return content; @@ -171,25 +173,29 @@ public String getHtmlUrl() { } /** - * Retrieves the actual content stored here. + * Retrieves the actual bytes of the blob. * * @return the input stream * @throws IOException - * Signals that an I/O exception has occurred. + * the io exception */ + public InputStream read() throws IOException { + return new ByteArrayInputStream(readDecodedContent()); + } + /** - * Retrieves the actual bytes of the blob. + * Retrieves the decoded bytes of the blob. * * @return the input stream * @throws IOException * the io exception */ - public InputStream read() throws IOException { - refresh(content); + private byte[] readDecodedContent() throws IOException { + String encodedContent = getEncodedContent(); if (encoding.equals("base64")) { try { Base64.Decoder decoder = Base64.getMimeDecoder(); - return new ByteArrayInputStream(decoder.decode(content.getBytes(StandardCharsets.US_ASCII))); + return decoder.decode(encodedContent.getBytes(StandardCharsets.US_ASCII)); } catch (IllegalArgumentException e) { throw new AssertionError(e); // US-ASCII is mandatory } diff --git a/src/main/java/org/kohsuke/github/GHContentSearchBuilder.java b/src/main/java/org/kohsuke/github/GHContentSearchBuilder.java index 305c61b36a..e29449e6bb 100644 --- a/src/main/java/org/kohsuke/github/GHContentSearchBuilder.java +++ b/src/main/java/org/kohsuke/github/GHContentSearchBuilder.java @@ -59,19 +59,6 @@ public GHContentSearchBuilder language(String v) { return q("language:" + v); } - /** - * Fork gh content search builder. - * - * @param v - * the v - * @return the gh content search builder - * @deprecated use {@link #fork(GHFork)}. - */ - @Deprecated - public GHContentSearchBuilder fork(String v) { - return q("fork", v); - } - /** * Fork gh content search builder. * diff --git a/src/main/java/org/kohsuke/github/GHContentUpdateResponse.java b/src/main/java/org/kohsuke/github/GHContentUpdateResponse.java index 5da5ecf7cd..0b90c9a5e9 100644 --- a/src/main/java/org/kohsuke/github/GHContentUpdateResponse.java +++ b/src/main/java/org/kohsuke/github/GHContentUpdateResponse.java @@ -1,6 +1,5 @@ package org.kohsuke.github; -import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; // TODO: Auto-generated Javadoc @@ -27,14 +26,8 @@ public GHContent getContent() { * @return the commit */ @SuppressFBWarnings(value = { "EI_EXPOSE_REP" }, justification = "Expected behavior") - @WithBridgeMethods(value = GHCommit.class, adapterMethod = "gitCommitToGHCommit") public GitCommit getCommit() { return commit; } - @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "bridge method of getCommit") - private Object gitCommitToGHCommit(GitCommit commit, Class targetType) { - return new GHCommit(new GHCommit.ShortInfo(commit)); - } - } diff --git a/src/main/java/org/kohsuke/github/GHCreateRepositoryBuilder.java b/src/main/java/org/kohsuke/github/GHCreateRepositoryBuilder.java index e50ff7aa88..15bceb2ebd 100644 --- a/src/main/java/org/kohsuke/github/GHCreateRepositoryBuilder.java +++ b/src/main/java/org/kohsuke/github/GHCreateRepositoryBuilder.java @@ -86,21 +86,6 @@ public GHCreateRepositoryBuilder team(GHTeam team) throws IOException { return this; } - /** - * Specifies whether the repository is a template. - * - * @param enabled - * true if enabled - * @return a builder to continue with building - * @throws IOException - * In case of any networking error or error from the server. - * @deprecated Use {@link #isTemplate(boolean)} method instead - */ - @Deprecated - public GHCreateRepositoryBuilder templateRepository(boolean enabled) throws IOException { - return isTemplate(enabled); - } - /** * Specifies the ownership of the repository. * @@ -122,7 +107,6 @@ public GHCreateRepositoryBuilder owner(String owner) throws IOException { * @param templateRepo * template repository * @return a builder to continue with building - * @see GitHub API Previews */ public GHCreateRepositoryBuilder fromTemplateRepository(String templateOwner, String templateRepo) { requester.withUrlPath("/repos/" + templateOwner + "/" + templateRepo + "/generate"); @@ -135,7 +119,6 @@ public GHCreateRepositoryBuilder fromTemplateRepository(String templateOwner, St * @param templateRepository * the template repository as a GHRepository * @return a builder to continue with building - * @see GitHub API Previews */ public GHCreateRepositoryBuilder fromTemplateRepository(GHRepository templateRepository) { Objects.requireNonNull(templateRepository, "templateRepository cannot be null"); diff --git a/src/main/java/org/kohsuke/github/GHDeployKey.java b/src/main/java/org/kohsuke/github/GHDeployKey.java index 2af3b9d7ee..ac743ba9cf 100644 --- a/src/main/java/org/kohsuke/github/GHDeployKey.java +++ b/src/main/java/org/kohsuke/github/GHDeployKey.java @@ -114,18 +114,6 @@ public boolean isRead_only() { return read_only; } - /** - * Wrap gh deploy key. - * - * @param repo - * the repo - * @return the gh deploy key - */ - @Deprecated - public GHDeployKey wrap(GHRepository repo) { - throw new RuntimeException("Do not use this method."); - } - /** * Wrap gh deploy key. * diff --git a/src/main/java/org/kohsuke/github/GHDeployment.java b/src/main/java/org/kohsuke/github/GHDeployment.java index 62152485fc..0fe369ed46 100644 --- a/src/main/java/org/kohsuke/github/GHDeployment.java +++ b/src/main/java/org/kohsuke/github/GHDeployment.java @@ -125,7 +125,6 @@ public Object getPayloadObject() { * The environment defined when the deployment was first created. * * @return the original deployment environment - * @deprecated until preview feature has graduated to stable */ public String getOriginalEnvironment() { return original_environment; @@ -145,7 +144,6 @@ public String getEnvironment() { * future. * * @return the environment is transient - * @deprecated until preview feature has graduated to stable */ public boolean isTransientEnvironment() { return transient_environment; @@ -155,7 +153,6 @@ public boolean isTransientEnvironment() { * Specifies if the given environment is one that end-users directly interact with. * * @return the environment is used by end-users directly - * @deprecated until preview feature has graduated to stable */ public boolean isProductionEnvironment() { return production_environment; @@ -190,17 +187,6 @@ public String getSha() { return sha; } - /** - * Gets the html url. - * - * @return the html url - * @deprecated This object has no HTML URL. - */ - @Override - public URL getHtmlUrl() { - return null; - } - /** * Create status gh deployment status builder. * diff --git a/src/main/java/org/kohsuke/github/GHDeploymentBuilder.java b/src/main/java/org/kohsuke/github/GHDeploymentBuilder.java index 2f7b0ae7d5..0463b425bc 100644 --- a/src/main/java/org/kohsuke/github/GHDeploymentBuilder.java +++ b/src/main/java/org/kohsuke/github/GHDeploymentBuilder.java @@ -124,7 +124,6 @@ public GHDeploymentBuilder environment(String environment) { * @param transientEnvironment * the environment is transient * @return the gh deployment builder - * @deprecated until preview feature has graduated to stable */ public GHDeploymentBuilder transientEnvironment(boolean transientEnvironment) { builder.with("transient_environment", transientEnvironment); @@ -137,7 +136,6 @@ public GHDeploymentBuilder transientEnvironment(boolean transientEnvironment) { * @param productionEnvironment * the environment is used by end-users directly * @return the gh deployment builder - * @deprecated until preview feature has graduated to stable */ public GHDeploymentBuilder productionEnvironment(boolean productionEnvironment) { builder.with("production_environment", productionEnvironment); diff --git a/src/main/java/org/kohsuke/github/GHDeploymentStatus.java b/src/main/java/org/kohsuke/github/GHDeploymentStatus.java index 80a2221731..c666355ff9 100644 --- a/src/main/java/org/kohsuke/github/GHDeploymentStatus.java +++ b/src/main/java/org/kohsuke/github/GHDeploymentStatus.java @@ -34,19 +34,6 @@ public class GHDeploymentStatus extends GHObject { /** The environment url. */ protected String environment_url; - /** - * Wrap gh deployment status. - * - * @param owner - * the owner - * - * @return the gh deployment status - */ - @Deprecated - public GHDeploymentStatus wrap(GHRepository owner) { - throw new RuntimeException("Do not use this method."); - } - /** * Wrap gh deployment status. * @@ -64,20 +51,6 @@ GHDeploymentStatus lateBind(GHRepository owner) { * Gets target url. * * @return the target url - * @deprecated Target url is deprecated in favor of {@link #getLogUrl() getLogUrl} - */ - @Deprecated - public URL getTargetUrl() { - return GitHubClient.parseURL(target_url); - } - - /** - * Gets target url. - *

- * This method replaces {@link #getTargetUrl() getTargetUrl}}. - * - * @return the target url - * @deprecated until preview feature has graduated to stable */ public URL getLogUrl() { return GitHubClient.parseURL(log_url); @@ -96,7 +69,6 @@ public URL getDeploymentUrl() { * Gets deployment environment url. * * @return the deployment environment url - * @deprecated until preview feature has graduated to stable */ public URL getEnvironmentUrl() { return GitHubClient.parseURL(environment_url); @@ -120,17 +92,6 @@ public GHDeploymentState getState() { return GHDeploymentState.valueOf(state.toUpperCase(Locale.ENGLISH)); } - /** - * Gets the html url. - * - * @return the html url - * @deprecated This object has no HTML URL. - */ - @Override - public URL getHtmlUrl() { - return null; - } - /** * Gets the owner. * diff --git a/src/main/java/org/kohsuke/github/GHDeploymentStatusBuilder.java b/src/main/java/org/kohsuke/github/GHDeploymentStatusBuilder.java index 2cac135cc7..e003758fb8 100644 --- a/src/main/java/org/kohsuke/github/GHDeploymentStatusBuilder.java +++ b/src/main/java/org/kohsuke/github/GHDeploymentStatusBuilder.java @@ -13,23 +13,6 @@ public class GHDeploymentStatusBuilder { private GHRepository repo; private long deploymentId; - /** - * Instantiates a new Gh deployment status builder. - * - * @param repo - * the repo - * @param deploymentId - * the deployment id - * @param state - * the state - * - * @deprecated Use {@link GHDeployment#createStatus(GHDeploymentState)} - */ - @Deprecated - public GHDeploymentStatusBuilder(GHRepository repo, int deploymentId, GHDeploymentState state) { - this(repo, (long) deploymentId, state); - } - /** * Instantiates a new GH deployment status builder. * @@ -55,7 +38,6 @@ public GHDeploymentStatusBuilder(GHRepository repo, int deploymentId, GHDeployme * @param autoInactive * Add inactive status flag * @return the gh deployment status builder - * @deprecated until preview feature has graduated to stable */ public GHDeploymentStatusBuilder autoInactive(boolean autoInactive) { this.builder.with("auto_inactive", autoInactive); @@ -81,7 +63,6 @@ public GHDeploymentStatusBuilder description(String description) { * @param environment * the environment name * @return the gh deployment status builder - * @deprecated until preview feature has graduated to stable */ public GHDeploymentStatusBuilder environment(String environment) { this.builder.with("environment", environment); @@ -94,7 +75,6 @@ public GHDeploymentStatusBuilder environment(String environment) { * @param environmentUrl * the environment url * @return the gh deployment status builder - * @deprecated until preview feature has graduated to stable */ public GHDeploymentStatusBuilder environmentUrl(String environmentUrl) { this.builder.with("environment_url", environmentUrl); @@ -103,33 +83,16 @@ public GHDeploymentStatusBuilder environmentUrl(String environmentUrl) { /** * The full URL of the deployment's output. - *

- * This method replaces {@link #targetUrl(String) targetUrl}. * * @param logUrl * the deployment output url * @return the gh deployment status builder - * @deprecated until preview feature has graduated to stable */ public GHDeploymentStatusBuilder logUrl(String logUrl) { this.builder.with("log_url", logUrl); return this; } - /** - * Target url gh deployment status builder. - * - * @param targetUrl - * the target url - * @return the gh deployment status builder - * @deprecated Target url is deprecated in favor of {@link #logUrl(String) logUrl} - */ - @Deprecated - public GHDeploymentStatusBuilder targetUrl(String targetUrl) { - this.builder.with("target_url", targetUrl); - return this; - } - /** * Create gh deployment status. * diff --git a/src/main/java/org/kohsuke/github/GHDiscussion.java b/src/main/java/org/kohsuke/github/GHDiscussion.java index 88f851b282..246912f9ea 100644 --- a/src/main/java/org/kohsuke/github/GHDiscussion.java +++ b/src/main/java/org/kohsuke/github/GHDiscussion.java @@ -33,7 +33,6 @@ public class GHDiscussion extends GHObject { * @throws IOException * Signals that an I/O exception has occurred. */ - @Override public URL getHtmlUrl() throws IOException { return GitHubClient.parseURL(htmlUrl); } diff --git a/src/main/java/org/kohsuke/github/GHEventPayload.java b/src/main/java/org/kohsuke/github/GHEventPayload.java index 2e34daa299..30c959be5c 100644 --- a/src/main/java/org/kohsuke/github/GHEventPayload.java +++ b/src/main/java/org/kohsuke/github/GHEventPayload.java @@ -57,18 +57,6 @@ public GHUser getSender() { return sender; } - /** - * Sets sender. - * - * @param sender - * the sender - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setSender(GHUser sender) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets repository. * @@ -79,18 +67,6 @@ public GHRepository getRepository() { return repository; } - /** - * Sets repository. - * - * @param repository - * the repository - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setRepository(GHRepository repository) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets organization. * @@ -101,18 +77,6 @@ public GHOrganization getOrganization() { return organization; } - /** - * Sets organization. - * - * @param organization - * the organization - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setOrganization(GHOrganization organization) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets installation. * @@ -158,18 +122,6 @@ public int getNumber() { return number; } - /** - * Sets Check Run object. - * - * @param currentCheckRun - * the check run object - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setCheckRun(GHCheckRun currentCheckRun) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets Check Run object. * @@ -180,18 +132,6 @@ public GHCheckRun getCheckRun() { return checkRun; } - /** - * Sets the Requested Action object. - * - * @param currentRequestedAction - * the current action - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setRequestedAction(GHRequestedAction currentRequestedAction) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets the Requested Action object. * @@ -692,18 +632,6 @@ public GHIssue getIssue() { return issue; } - /** - * Sets issue. - * - * @param issue - * the issue - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setIssue(GHIssue issue) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets the added or removed label for labeled/unlabeled events. * @@ -769,18 +697,6 @@ public CommentChanges getChanges() { return changes; } - /** - * Sets comment. - * - * @param comment - * the comment - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setComment(GHIssueComment comment) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets issue. * @@ -791,18 +707,6 @@ public GHIssue getIssue() { return issue; } - /** - * Sets issue. - * - * @param issue - * the issue - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setIssue(GHIssue issue) { - throw new RuntimeException("Do not use this method."); - } - /** * Late bind. */ @@ -838,18 +742,6 @@ public GHCommitComment getComment() { return comment; } - /** - * Sets comment. - * - * @param comment - * the comment - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setComment(GHCommitComment comment) { - throw new RuntimeException("Do not use this method."); - } - /** * Late bind. */ @@ -965,18 +857,6 @@ public GHDeployment getDeployment() { return deployment; } - /** - * Sets deployment. - * - * @param deployment - * the deployment - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setDeployment(GHDeployment deployment) { - throw new RuntimeException("Do not use this method."); - } - /** * Late bind. */ @@ -1012,18 +892,6 @@ public GHDeploymentStatus getDeploymentStatus() { return deploymentStatus; } - /** - * Sets deployment status. - * - * @param deploymentStatus - * the deployment status - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setDeploymentStatus(GHDeploymentStatus deploymentStatus) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets deployment. * @@ -1034,18 +902,6 @@ public GHDeployment getDeployment() { return deployment; } - /** - * Sets deployment. - * - * @param deployment - * the deployment - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setDeployment(GHDeployment deployment) { - throw new RuntimeException("Do not use this method."); - } - /** * Late bind. */ @@ -1079,18 +935,6 @@ public static class Fork extends GHEventPayload { public GHRepository getForkee() { return forkee; } - - /** - * Sets forkee. - * - * @param forkee - * the forkee - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setForkee(GHRepository forkee) { - throw new RuntimeException("Do not use this method."); - } } /** @@ -1225,18 +1069,6 @@ public Pusher getPusher() { return pusher; } - /** - * Sets pusher. - * - * @param pusher - * the pusher - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setPusher(Pusher pusher) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets compare. * @@ -1261,18 +1093,6 @@ public String getName() { return name; } - /** - * Sets name. - * - * @param name - * the name - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setName(String name) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets email. * @@ -1281,18 +1101,6 @@ public void setName(String name) { public String getEmail() { return email; } - - /** - * Sets email. - * - * @param email - * the email - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setEmail(String email) { - throw new RuntimeException("Do not use this method."); - } } /** @@ -1423,18 +1231,6 @@ public static class Release extends GHEventPayload { public GHRelease getRelease() { return release; } - - /** - * Sets release. - * - * @param release - * the release - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setRelease(GHRelease release) { - throw new RuntimeException("Do not use this method."); - } } /** @@ -1508,18 +1304,6 @@ public GHCommitState getState() { return state; } - /** - * Sets the status stage. - * - * @param state - * status state - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setState(GHCommitState state) { - throw new RuntimeException("Do not use this method."); - } - /** * Gets the commit associated with the status event. * @@ -1530,18 +1314,6 @@ public GHCommit getCommit() { return commit; } - /** - * Sets the commit associated with the status event. - * - * @param commit - * commit - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setCommit(GHCommit commit) { - throw new RuntimeException("Do not use this method."); - } - /** * Late bind. */ diff --git a/src/main/java/org/kohsuke/github/GHHook.java b/src/main/java/org/kohsuke/github/GHHook.java index 08f2b9e798..f52b972834 100644 --- a/src/main/java/org/kohsuke/github/GHHook.java +++ b/src/main/java/org/kohsuke/github/GHHook.java @@ -4,7 +4,6 @@ import org.kohsuke.github.internal.EnumUtils; import java.io.IOException; -import java.net.URL; import java.util.Collections; import java.util.EnumSet; import java.util.List; @@ -93,17 +92,6 @@ public void delete() throws IOException { root().createRequest().method("DELETE").withUrlPath(getApiRoute()).send(); } - /** - * Gets the html url. - * - * @return the html url - * @deprecated This object has no HTML URL. - */ - @Override - public URL getHtmlUrl() { - return null; - } - /** * Root. * diff --git a/src/main/java/org/kohsuke/github/GHInvitation.java b/src/main/java/org/kohsuke/github/GHInvitation.java index 4985bb9c1e..1f9332af7f 100644 --- a/src/main/java/org/kohsuke/github/GHInvitation.java +++ b/src/main/java/org/kohsuke/github/GHInvitation.java @@ -49,7 +49,6 @@ public void decline() throws IOException { * * @return the html url */ - @Override public URL getHtmlUrl() { return GitHubClient.parseURL(html_url); } diff --git a/src/main/java/org/kohsuke/github/GHIssue.java b/src/main/java/org/kohsuke/github/GHIssue.java index 2adeb20b11..f460e89bc0 100644 --- a/src/main/java/org/kohsuke/github/GHIssue.java +++ b/src/main/java/org/kohsuke/github/GHIssue.java @@ -24,7 +24,6 @@ package org.kohsuke.github; -import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import org.apache.commons.lang3.StringUtils; import org.kohsuke.github.internal.EnumUtils; @@ -232,17 +231,6 @@ public Date getClosedAt() { return GitHubClient.parseDate(closed_at); } - /** - * Gets api url. - * - * @return API URL of this object. - * @deprecated use {@link #getUrl()} - */ - @Deprecated - public URL getApiURL() { - return getUrl(); - } - /** * Lock. * @@ -272,7 +260,6 @@ public void unlock() throws IOException { * @throws IOException * the io exception */ - @WithBridgeMethods(void.class) public GHIssueComment comment(String message) throws IOException { GHIssueComment r = root().createRequest() .method("POST") @@ -411,7 +398,6 @@ public void setLabels(String... labels) throws IOException { * @throws IOException * the io exception */ - @WithBridgeMethods(void.class) public List addLabels(String... names) throws IOException { return _addLabels(Arrays.asList(names)); } @@ -427,7 +413,6 @@ public List addLabels(String... names) throws IOException { * @throws IOException * the io exception */ - @WithBridgeMethods(void.class) public List addLabels(GHLabel... labels) throws IOException { return addLabels(Arrays.asList(labels)); } @@ -443,7 +428,6 @@ public List addLabels(GHLabel... labels) throws IOException { * @throws IOException * the io exception */ - @WithBridgeMethods(void.class) public List addLabels(Collection labels) throws IOException { return _addLabels(GHLabel.toNames(labels)); } @@ -467,7 +451,6 @@ private List _addLabels(Collection names) throws IOException { * @throws IOException * the io exception, throws {@link GHFileNotFoundException} if label was not present. */ - @WithBridgeMethods(void.class) public List removeLabel(String name) throws IOException { return Arrays.asList(root().createRequest() .method("DELETE") @@ -486,7 +469,6 @@ public List removeLabel(String name) throws IOException { * @throws IOException * the io exception */ - @WithBridgeMethods(void.class) public List removeLabels(String... names) throws IOException { return _removeLabels(Arrays.asList(names)); } @@ -503,7 +485,6 @@ public List removeLabels(String... names) throws IOException { * the io exception * @see #removeLabels(String...) #removeLabels(String...) */ - @WithBridgeMethods(void.class) public List removeLabels(GHLabel... labels) throws IOException { return removeLabels(Arrays.asList(labels)); } @@ -519,7 +500,6 @@ public List removeLabels(GHLabel... labels) throws IOException { * @throws IOException * the io exception */ - @WithBridgeMethods(void.class) public List removeLabels(Collection labels) throws IOException { return _removeLabels(GHLabel.toNames(labels)); } diff --git a/src/main/java/org/kohsuke/github/GHIssueComment.java b/src/main/java/org/kohsuke/github/GHIssueComment.java index 013cd5f85a..c1b657ca48 100644 --- a/src/main/java/org/kohsuke/github/GHIssueComment.java +++ b/src/main/java/org/kohsuke/github/GHIssueComment.java @@ -75,16 +75,6 @@ public String getBody() { return body; } - /** - * Gets the ID of the user who posted this comment. - * - * @return the user name - */ - @Deprecated - public String getUserName() { - return user.getLogin(); - } - /** * Gets the user who posted this comment. * @@ -101,7 +91,6 @@ public GHUser getUser() throws IOException { * * @return the html url */ - @Override public URL getHtmlUrl() { return GitHubClient.parseURL(html_url); } diff --git a/src/main/java/org/kohsuke/github/GHLabel.java b/src/main/java/org/kohsuke/github/GHLabel.java index 46c5af2069..fcc478693d 100644 --- a/src/main/java/org/kohsuke/github/GHLabel.java +++ b/src/main/java/org/kohsuke/github/GHLabel.java @@ -120,34 +120,6 @@ public boolean isDefault() { return default_; } - /** - * Sets color. - * - * @param newColor - * 6-letter hex color code, like "f29513" - * @throws IOException - * the io exception - * @deprecated use {@link #set()} or {@link #update()} instead - */ - @Deprecated - public void setColor(String newColor) throws IOException { - set().color(newColor); - } - - /** - * Sets description. - * - * @param newDescription - * Description of label - * @throws IOException - * the io exception - * @deprecated use {@link #set()} or {@link #update()} instead - */ - @Deprecated - public void setDescription(String newDescription) throws IOException { - set().description(newDescription); - } - /** * To names. * diff --git a/src/main/java/org/kohsuke/github/GHMemberChanges.java b/src/main/java/org/kohsuke/github/GHMemberChanges.java index 6de93c5dc4..aef48bb247 100644 --- a/src/main/java/org/kohsuke/github/GHMemberChanges.java +++ b/src/main/java/org/kohsuke/github/GHMemberChanges.java @@ -1,8 +1,6 @@ package org.kohsuke.github; -import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import org.kohsuke.github.internal.EnumUtils; /** * Changes made to a team. @@ -47,9 +45,10 @@ public static class FromToPermission { /** * Gets the from. * + * Cannot use {@link GHOrganization.Permission#ADMIN} due to messy underlying design. + * * @return the from */ - @WithBridgeMethods(value = GHOrganization.Permission.class, adapterMethod = "stringToOrgPermission") public String getFrom() { return from; } @@ -57,28 +56,13 @@ public String getFrom() { /** * Gets the to. * + * Cannot use {@link GHOrganization.Permission#ADMIN} due to messy underlying design. + * * @return the to */ - @WithBridgeMethods(value = GHOrganization.Permission.class, adapterMethod = "stringToOrgPermission") public String getTo() { return to; } - - @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Bridge method of getFrom and getTo") - private Object stringToOrgPermission(String permissionType, Class type) { - switch (permissionType) { - case "admin" : - return GHOrganization.Permission.ADMIN; - case "none" : - return GHOrganization.Permission.UNKNOWN; - case "read" : - return GHOrganization.Permission.PULL; - case "write" : - return GHOrganization.Permission.PUSH; - default : - return EnumUtils.getNullableEnumOrDefault(GHPermissionType.class, to, GHPermissionType.UNKNOWN); - } - } } /** diff --git a/src/main/java/org/kohsuke/github/GHMilestone.java b/src/main/java/org/kohsuke/github/GHMilestone.java index 0bb7481a1a..44a290374b 100644 --- a/src/main/java/org/kohsuke/github/GHMilestone.java +++ b/src/main/java/org/kohsuke/github/GHMilestone.java @@ -211,18 +211,6 @@ protected String getApiRoute() { return "/repos/" + owner.getOwnerName() + "/" + owner.getName() + "/milestones/" + number; } - /** - * Wrap gh milestone. - * - * @param repo - * the repo - * @return the gh milestone - */ - @Deprecated - public GHMilestone wrap(GHRepository repo) { - throw new RuntimeException("Do not use this method."); - } - /** * Wrap gh milestone. * diff --git a/src/main/java/org/kohsuke/github/GHMyself.java b/src/main/java/org/kohsuke/github/GHMyself.java index 43914f2bd2..4f145402ec 100644 --- a/src/main/java/org/kohsuke/github/GHMyself.java +++ b/src/main/java/org/kohsuke/github/GHMyself.java @@ -1,7 +1,6 @@ package org.kohsuke.github; import java.io.IOException; -import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -46,13 +45,9 @@ public enum RepositoryListFilter { * the io exception * @deprecated Use {@link #getEmails2()} */ + @Deprecated public List getEmails() throws IOException { - List src = getEmails2(); - List r = new ArrayList(src.size()); - for (GHEmail e : src) { - r.add(e.getEmail()); - } - return r; + return listEmails().toList().stream().map(email -> email.getEmail()).toList(); } /** @@ -64,9 +59,23 @@ public List getEmails() throws IOException { * @return Always non-null. * @throws IOException * the io exception + * @deprecated Use {@link #listEmails()} */ + @Deprecated public List getEmails2() throws IOException { - return root().createRequest().withUrlPath("/user/emails").toIterable(GHEmail[].class, null).toList(); + return listEmails().toList(); + } + + /** + * Returns the read-only list of e-mail addresses configured for you. + *

+ * This corresponds to the stuff you configure in https://github.com/settings/emails, and not to be confused with + * {@link #getEmail()} that shows your public e-mail address set in https://github.com/settings/profile + * + * @return Always non-null. + */ + public PagedIterable listEmails() { + return root().createRequest().withUrlPath("/user/emails").toIterable(GHEmail[].class, null); } /** @@ -151,7 +160,7 @@ public GHPersonSet getAllOrganizations() throws IOException { */ public synchronized Map getAllRepositories() throws IOException { Map repositories = new TreeMap(); - for (GHRepository r : listAllRepositories()) { + for (GHRepository r : listRepositories()) { repositories.put(r.getName(), r); } return Collections.unmodifiableMap(repositories); @@ -206,17 +215,6 @@ public PagedIterable listRepositories(final int pageSize, final Re .withPageSize(pageSize); } - /** - * List all repositories paged iterable. - * - * @return the paged iterable - * @deprecated Use {@link #listRepositories()} - */ - @Deprecated - public PagedIterable listAllRepositories() { - return listRepositories(); - } - /** * List your organization memberships. * diff --git a/src/main/java/org/kohsuke/github/GHObject.java b/src/main/java/org/kohsuke/github/GHObject.java index e58c2144a1..9d9b2f4fe0 100644 --- a/src/main/java/org/kohsuke/github/GHObject.java +++ b/src/main/java/org/kohsuke/github/GHObject.java @@ -1,7 +1,6 @@ package org.kohsuke.github; import com.fasterxml.jackson.annotation.JacksonInject; -import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import org.apache.commons.lang3.builder.ReflectionToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; @@ -79,36 +78,19 @@ public Map> getResponseHeaderFields() { * @throws IOException * on error */ - @WithBridgeMethods(value = String.class, adapterMethod = "createdAtStr") public Date getCreatedAt() throws IOException { return GitHubClient.parseDate(createdAt); } - @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Bridge method of getCreatedAt") - private Object createdAtStr(Date id, Class type) { - return createdAt; - } - /** * Gets url. * * @return API URL of this object. */ - @WithBridgeMethods(value = String.class, adapterMethod = "urlToString") public URL getUrl() { return GitHubClient.parseURL(url); } - /** - * Gets html url. - * - * @return URL of this object for humans, which renders some HTML. - * @throws IOException - * on error - */ - @WithBridgeMethods(value = String.class, adapterMethod = "urlToString") - public abstract URL getHtmlUrl() throws IOException; - /** * When was this resource last updated?. * @@ -135,25 +117,10 @@ public String getNodeId() { * * @return Unique ID number of this resource. */ - @WithBridgeMethods(value = { String.class, int.class }, adapterMethod = "longToStringOrInt") public long getId() { return id; } - @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Bridge method of getId") - private Object longToStringOrInt(long id, Class type) { - if (type == String.class) - return String.valueOf(id); - if (type == int.class) - return (int) id; - throw new AssertionError("Unexpected type: " + type); - } - - @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Bridge method of getHtmlUrl") - private Object urlToString(URL url, Class type) { - return url == null ? null : url.toString(); - } - /** * String representation to assist debugging and inspection. The output format of this string is not a committed * part of the API and is subject to change. diff --git a/src/main/java/org/kohsuke/github/GHOrganization.java b/src/main/java/org/kohsuke/github/GHOrganization.java index ee5f843348..3f3d3b97d9 100644 --- a/src/main/java/org/kohsuke/github/GHOrganization.java +++ b/src/main/java/org/kohsuke/github/GHOrganization.java @@ -2,7 +2,12 @@ import java.io.IOException; import java.net.URL; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; // TODO: Auto-generated Javadoc @@ -15,69 +20,6 @@ public class GHOrganization extends GHPerson { private boolean has_organization_projects; - /** - * Creates a new repository. - * - * @param name - * the name - * @param description - * the description - * @param homepage - * the homepage - * @param team - * the team - * @param isPublic - * the is public - * @return Newly created repository. - * @throws IOException - * the io exception - * @deprecated Use {@link #createRepository(String)} that uses a builder pattern to let you control every aspect. - */ - @Deprecated - public GHRepository createRepository(String name, - String description, - String homepage, - String team, - boolean isPublic) throws IOException { - GHTeam t = getTeams().get(team); - if (t == null) - throw new IllegalArgumentException("No such team: " + team); - return createRepository(name, description, homepage, t, isPublic); - } - - /** - * Create repository gh repository. - * - * @param name - * the name - * @param description - * the description - * @param homepage - * the homepage - * @param team - * the team - * @param isPublic - * the is public - * @return the gh repository - * @throws IOException - * the io exception - * @deprecated Use {@link #createRepository(String)} that uses a builder pattern to let you control every aspect. - */ - @Deprecated - public GHRepository createRepository(String name, - String description, - String homepage, - GHTeam team, - boolean isPublic) throws IOException { - if (team == null) - throw new IllegalArgumentException("Invalid team"); - return createRepository(name).description(description) - .homepage(homepage) - .private_(!isPublic) - .team(team) - .create(); - } - /** * Starts a builder that creates a new repository. *

@@ -120,21 +62,6 @@ public PagedIterable listTeams() throws IOException { .toIterable(GHTeam[].class, item -> item.wrapUp(this)); } - /** - * Gets a single team by ID. - * - * @param teamId - * id of the team that we want to query for - * @return the team - * @throws IOException - * the io exception - * @deprecated Use {@link GHOrganization#getTeam(long)} - */ - @Deprecated - public GHTeam getTeam(int teamId) throws IOException { - return getTeam((long) teamId); - } - /** * Gets a single team by ID. * @@ -351,18 +278,6 @@ public void publicize(GHUser u) throws IOException { root().createRequest().method("PUT").withUrlPath("/orgs/" + login + "/public_members/" + u.getLogin()).send(); } - /** - * Gets members. - * - * @return the members - * @throws IOException - * the io exception - * @deprecated use {@link #listMembers()} - */ - public List getMembers() throws IOException { - return listMembers().toList(); - } - /** * All the members of this organization. * @@ -616,92 +531,6 @@ public String toString() { } } - /** - * Creates a new team and assigns the repositories. - * - * @param name - * the name - * @param p - * the p - * @param repositories - * the repositories - * @return the gh team - * @throws IOException - * the io exception - * @deprecated https://developer.github.com/v3/teams/#create-team deprecates permission field use - * {@link #createTeam(String)} - */ - @Deprecated - public GHTeam createTeam(String name, Permission p, Collection repositories) throws IOException { - Requester post = root().createRequest().method("POST").with("name", name).with("permission", p); - List repo_names = new ArrayList(); - for (GHRepository r : repositories) { - repo_names.add(login + "/" + r.getName()); - } - post.with("repo_names", repo_names); - return post.withUrlPath("/orgs/" + login + "/teams").fetch(GHTeam.class).wrapUp(this); - } - - /** - * Create team gh team. - * - * @param name - * the name - * @param p - * the p - * @param repositories - * the repositories - * @return the gh team - * @throws IOException - * the io exception - * @deprecated https://developer.github.com/v3/teams/#create-team deprecates permission field use - * {@link #createTeam(String)} - */ - @Deprecated - public GHTeam createTeam(String name, Permission p, GHRepository... repositories) throws IOException { - return createTeam(name, p, Arrays.asList(repositories)); - } - - /** - * Creates a new team and assigns the repositories. - * - * @param name - * the name - * @param repositories - * the repositories - * @return the gh team - * @throws IOException - * the io exception - * @deprecated Use {@link #createTeam(String)} that uses a builder pattern to let you control every aspect. - */ - @Deprecated - public GHTeam createTeam(String name, Collection repositories) throws IOException { - Requester post = root().createRequest().method("POST").with("name", name); - List repo_names = new ArrayList(); - for (GHRepository r : repositories) { - repo_names.add(login + "/" + r.getName()); - } - post.with("repo_names", repo_names); - return post.withUrlPath("/orgs/" + login + "/teams").fetch(GHTeam.class).wrapUp(this); - } - - /** - * Create team gh team. - * - * @param name - * the name - * @param repositories - * the repositories - * @return the gh team - * @throws IOException - * the io exception - * @deprecated Use {@link #createTeam(String)} that uses a builder pattern to let you control every aspect. - */ - @Deprecated - public GHTeam createTeam(String name, GHRepository... repositories) throws IOException { - return createTeam(name, Arrays.asList(repositories)); - } - /** * Starts a builder that creates a new team. *

@@ -717,7 +546,7 @@ public GHTeamBuilder createTeam(String name) { } /** - * List up repositories that has some open pull requests. + * List repositories that has some open pull requests. *

* This used to be an efficient method that didn't involve traversing every repository, but now it doesn't do any * optimization. @@ -728,8 +557,8 @@ public GHTeamBuilder createTeam(String name) { */ public List getRepositoriesWithOpenPullRequests() throws IOException { List r = new ArrayList(); - for (GHRepository repository : listRepositories(100)) { - List pullRequests = repository.getPullRequests(GHIssueState.OPEN); + for (GHRepository repository : listRepositories().withPageSize(100)) { + List pullRequests = repository.queryPullRequests().state(GHIssueState.OPEN).list().toList(); if (pullRequests.size() > 0) { r.add(repository); } @@ -747,7 +576,7 @@ public List getRepositoriesWithOpenPullRequests() throws IOExcepti public List getPullRequests() throws IOException { List all = new ArrayList(); for (GHRepository r : getRepositoriesWithOpenPullRequests()) { - all.addAll(r.getPullRequests(GHIssueState.OPEN)); + all.addAll(r.queryPullRequests().state(GHIssueState.OPEN).list().toList()); } return all; } @@ -766,19 +595,16 @@ public PagedIterable listEvents() throws IOException { } /** - * Lists up all the repositories using the specified page size. + * List all the repositories using a default of 30 items page size. * - * @param pageSize - * size for each page of items returned by GitHub. Maximum page size is 100. Unlike - * {@link #getRepositories()}, this does not wait until all the repositories are returned. * @return the paged iterable */ @Override - public PagedIterable listRepositories(final int pageSize) { + public PagedIterable listRepositories() { return root().createRequest() .withUrlPath("/orgs/" + login + "/repos") .toIterable(GHRepository[].class, null) - .withPageSize(pageSize); + .withPageSize(30); } /** diff --git a/src/main/java/org/kohsuke/github/GHPerson.java b/src/main/java/org/kohsuke/github/GHPerson.java index addcebfead..a3a5d2b1fc 100644 --- a/src/main/java/org/kohsuke/github/GHPerson.java +++ b/src/main/java/org/kohsuke/github/GHPerson.java @@ -5,8 +5,6 @@ import java.net.URL; import java.util.Collections; import java.util.Date; -import java.util.Iterator; -import java.util.List; import java.util.Map; import java.util.Optional; import java.util.TreeMap; @@ -73,21 +71,24 @@ protected synchronized void populate() throws IOException { */ public synchronized Map getRepositories() throws IOException { Map repositories = new TreeMap(); - for (GHRepository r : listRepositories(100)) { + for (GHRepository r : listRepositories().withPageSize(100)) { repositories.put(r.getName(), r); } return Collections.unmodifiableMap(repositories); } /** - * Lists up all the repositories using a 30 items page size. + * List all the repositories using a default of 30 items page size. *

* Unlike {@link #getRepositories()}, this does not wait until all the repositories are returned. * * @return the paged iterable */ public PagedIterable listRepositories() { - return listRepositories(30); + return root().createRequest() + .withUrlPath("/users/" + login + "/repos") + .toIterable(GHRepository[].class, null) + .withPageSize(30); } /** @@ -97,49 +98,11 @@ public PagedIterable listRepositories() { * size for each page of items returned by GitHub. Maximum page size is 100. Unlike * {@link #getRepositories()}, this does not wait until all the repositories are returned. * @return the paged iterable - */ - public PagedIterable listRepositories(final int pageSize) { - return root().createRequest() - .withUrlPath("/users/" + login + "/repos") - .toIterable(GHRepository[].class, null) - .withPageSize(pageSize); - } - - /** - * Loads repository list in a paginated fashion. - * - *

- * For a person with a lot of repositories, GitHub returns the list of repositories in a paginated fashion. Unlike - * {@link #getRepositories()}, this method allows the caller to start processing data as it arrives. - *

- * Every {@link Iterator#next()} call results in I/O. Exceptions that occur during the processing is wrapped into - * {@link Error}. - * - * @param pageSize - * the page size - * @return the iterable - * @deprecated Use {@link #listRepositories()} + * @deprecated Use #listRepositories().withPageSize() instead. */ @Deprecated - public synchronized Iterable> iterateRepositories(final int pageSize) { - return () -> { - final PagedIterator pager; - GitHubPageIterator iterator = GitHubPageIterator.create(root().getClient(), - GHRepository[].class, - root().createRequest().withUrlPath("users", login, "repos").build(), - pageSize); - pager = new PagedIterator<>(iterator, null); - - return new Iterator>() { - public boolean hasNext() { - return pager.hasNext(); - } - - public List next() { - return pager.nextPage(); - } - }; - }; + public PagedIterable listRepositories(final int pageSize) { + return listRepositories().withPageSize(pageSize); } /** @@ -168,17 +131,6 @@ public GHRepository getRepository(String name) throws IOException { */ public abstract PagedIterable listEvents() throws IOException; - /** - * Gravatar ID of this user, like 0cb9832a01c22c083390f3c5dcb64105. - * - * @return the gravatar id - * @deprecated No longer available in the v3 API. - */ - @Deprecated - public String getGravatarId() { - return ""; - } - /** * Returns a string of the avatar image URL. * @@ -286,7 +238,6 @@ public String getBlog() throws IOException { * * @return the html url */ - @Override public URL getHtmlUrl() { return GitHubClient.parseURL(html_url); } diff --git a/src/main/java/org/kohsuke/github/GHProject.java b/src/main/java/org/kohsuke/github/GHProject.java index e86115add1..3c44c828de 100644 --- a/src/main/java/org/kohsuke/github/GHProject.java +++ b/src/main/java/org/kohsuke/github/GHProject.java @@ -57,7 +57,6 @@ public class GHProject extends GHObject { * @throws IOException * Signals that an I/O exception has occurred. */ - @Override public URL getHtmlUrl() throws IOException { return GitHubClient.parseURL(html_url); } @@ -97,17 +96,6 @@ public URL getOwnerUrl() { return GitHubClient.parseURL(owner_url); } - /** - * Gets node id. - * - * @return the node id - * @deprecated Use {@link GHObject#getNodeId()} - */ - @Deprecated - public String getNode_id() { - return getNodeId(); - } - /** * Gets name. * @@ -154,30 +142,6 @@ public GHUser getCreator() { return creator; } - /** - * Wrap gh project. - * - * @param root - * the root - * @return the gh project - */ - @Deprecated - public GHProject wrap(GitHub root) { - throw new RuntimeException("Do not use this method."); - } - - /** - * Wrap gh project. - * - * @param repo - * the repo - * @return the gh project - */ - @Deprecated - public GHProject wrap(GHRepository repo) { - throw new RuntimeException("Do not use this method."); - } - /** * Wrap gh project. * diff --git a/src/main/java/org/kohsuke/github/GHProjectCard.java b/src/main/java/org/kohsuke/github/GHProjectCard.java index 45da83d709..6804f135bb 100644 --- a/src/main/java/org/kohsuke/github/GHProjectCard.java +++ b/src/main/java/org/kohsuke/github/GHProjectCard.java @@ -33,18 +33,6 @@ public URL getHtmlUrl() throws IOException { return null; } - /** - * Wrap gh project card. - * - * @param root - * the root - * @return the gh project card - */ - @Deprecated - public GHProjectCard wrap(GitHub root) { - throw new RuntimeException("Do not use this method."); - } - /** * Wrap gh project card. * @@ -56,18 +44,6 @@ GHProjectCard lateBind(GitHub root) { return this; } - /** - * Wrap gh project card. - * - * @param column - * the column - * @return the gh project card - */ - @Deprecated - public GHProjectCard wrap(GHProjectColumn column) { - throw new RuntimeException("Do not use this method."); - } - /** * Wrap gh project card. * diff --git a/src/main/java/org/kohsuke/github/GHProjectColumn.java b/src/main/java/org/kohsuke/github/GHProjectColumn.java index f05cc4f75d..6fce67bc3c 100644 --- a/src/main/java/org/kohsuke/github/GHProjectColumn.java +++ b/src/main/java/org/kohsuke/github/GHProjectColumn.java @@ -20,30 +20,6 @@ public class GHProjectColumn extends GHObject { private String name; private String project_url; - /** - * Gets the html url. - * - * @return the html url - * @throws IOException - * Signals that an I/O exception has occurred. - */ - @Override - public URL getHtmlUrl() throws IOException { - return null; - } - - /** - * Wrap gh project column. - * - * @param root - * the root - * @return the gh project column - */ - @Deprecated - public GHProjectColumn wrap(GitHub root) { - throw new RuntimeException("Do not use this method."); - } - /** * Wrap gh project column. * @@ -55,18 +31,6 @@ GHProjectColumn lateBind(GitHub root) { return this; } - /** - * Wrap gh project column. - * - * @param project - * the project - * @return the gh project column - */ - @Deprecated - public GHProjectColumn wrap(GHProject project) { - throw new RuntimeException("Do not use this method."); - } - /** * Wrap gh project column. * diff --git a/src/main/java/org/kohsuke/github/GHPullRequest.java b/src/main/java/org/kohsuke/github/GHPullRequest.java index 4d6e30fc08..98a9abfc98 100644 --- a/src/main/java/org/kohsuke/github/GHPullRequest.java +++ b/src/main/java/org/kohsuke/github/GHPullRequest.java @@ -35,8 +35,6 @@ import java.util.List; import java.util.Objects; -import javax.annotation.CheckForNull; - // TODO: Auto-generated Javadoc /** * A pull request. @@ -152,18 +150,6 @@ public GHCommitPointer getHead() { return head; } - /** - * Gets issue updated at. - * - * @return the issue updated at - * @throws IOException - * the io exception - */ - @Deprecated - public Date getIssueUpdatedAt() throws IOException { - return super.getUpdatedAt(); - } - /** * The diff file, like https://github.com/jenkinsci/jenkins/pull/100.diff * @@ -309,11 +295,8 @@ public Boolean getMergeable() throws IOException { * for test purposes only. * * @return the mergeable no refresh - * @throws IOException - * Signals that an I/O exception has occurred. */ - @Deprecated - Boolean getMergeableNoRefresh() throws IOException { + Boolean getMergeableNoRefresh() { return mergeable; } @@ -467,52 +450,6 @@ public PagedIterable listCommits() { .toIterable(GHPullRequestCommitDetail[].class, item -> item.wrapUp(this)); } - /** - * Create review gh pull request review. - * - * @param body - * the body - * @param event - * the event - * @param comments - * the comments - * @return the gh pull request review - * @throws IOException - * the io exception - * @deprecated Use {@link #createReview()} - */ - @Deprecated - public GHPullRequestReview createReview(String body, - @CheckForNull GHPullRequestReviewState event, - GHPullRequestReviewComment... comments) throws IOException { - return createReview(body, event, Arrays.asList(comments)); - } - - /** - * Create review gh pull request review. - * - * @param body - * the body - * @param event - * the event - * @param comments - * the comments - * @return the gh pull request review - * @throws IOException - * the io exception - * @deprecated Use {@link #createReview()} - */ - @Deprecated - public GHPullRequestReview createReview(String body, - @CheckForNull GHPullRequestReviewState event, - List comments) throws IOException { - GHPullRequestReviewBuilder b = createReview().body(body); - for (GHPullRequestReviewComment c : comments) { - b.comment(c.getBody(), c.getPath(), c.getPosition()); - } - return b.create(); - } - /** * Create review gh pull request review builder. * diff --git a/src/main/java/org/kohsuke/github/GHPullRequestCommitDetail.java b/src/main/java/org/kohsuke/github/GHPullRequestCommitDetail.java index c3faccbfad..59bc7c9798 100644 --- a/src/main/java/org/kohsuke/github/GHPullRequestCommitDetail.java +++ b/src/main/java/org/kohsuke/github/GHPullRequestCommitDetail.java @@ -23,7 +23,6 @@ */ package org.kohsuke.github; -import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.net.URL; @@ -52,14 +51,6 @@ void wrapUp(GHPullRequest owner) { this.owner = owner; } - /** - * The type Authorship. - * - * @deprecated Use {@link GitUser} - */ - public static class Authorship extends GitUser { - } - /** * The type Tree. */ @@ -96,10 +87,10 @@ public URL getUrl() { public static class Commit { /** The author. */ - Authorship author; + GitUser author; /** The committer. */ - Authorship committer; + GitUser committer; /** The message. */ String message; @@ -118,7 +109,6 @@ public static class Commit { * * @return the author */ - @WithBridgeMethods(value = Authorship.class, castRequired = true) public GitUser getAuthor() { return author; } @@ -128,7 +118,6 @@ public GitUser getAuthor() { * * @return the committer */ - @WithBridgeMethods(value = Authorship.class, castRequired = true) public GitUser getCommitter() { return committer; } diff --git a/src/main/java/org/kohsuke/github/GHPullRequestReview.java b/src/main/java/org/kohsuke/github/GHPullRequestReview.java index a72f462f1e..90e529ea7a 100644 --- a/src/main/java/org/kohsuke/github/GHPullRequestReview.java +++ b/src/main/java/org/kohsuke/github/GHPullRequestReview.java @@ -120,7 +120,6 @@ public GHPullRequestReviewState getState() { * * @return the html url */ - @Override public URL getHtmlUrl() { return GitHubClient.parseURL(html_url); } @@ -157,23 +156,6 @@ public Date getCreatedAt() throws IOException { return getSubmittedAt(); } - /** - * Submit. - * - * @param body - * the body - * @param state - * the state - * @throws IOException - * the io exception - * @deprecated Former preview method that changed when it got public. Left here for backward compatibility. Use - * {@link #submit(String, GHPullRequestReviewEvent)} - */ - @Deprecated - public void submit(String body, GHPullRequestReviewState state) throws IOException { - submit(body, state.toEvent()); - } - /** * Updates the comment. * diff --git a/src/main/java/org/kohsuke/github/GHPullRequestReviewComment.java b/src/main/java/org/kohsuke/github/GHPullRequestReviewComment.java index c59d7acf81..6ca55ea4c9 100644 --- a/src/main/java/org/kohsuke/github/GHPullRequestReviewComment.java +++ b/src/main/java/org/kohsuke/github/GHPullRequestReviewComment.java @@ -68,27 +68,6 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable { private GHPullRequestReviewCommentReactions reactions; private GHCommentAuthorAssociation author_association; - /** - * Draft gh pull request review comment. - * - * @param body - * the body - * @param path - * the path - * @param position - * the position - * @return the gh pull request review comment - * @deprecated You should be using {@link GHPullRequestReviewBuilder#comment(String, String, int)} - */ - @Deprecated - public static GHPullRequestReviewComment draft(String body, String path, int position) { - GHPullRequestReviewComment result = new GHPullRequestReviewComment(); - result.body = body; - result.path = path; - result.position = position; - return result; - } - /** * Wrap up. * @@ -210,7 +189,6 @@ public long getInReplyToId() { * * @return the html url */ - @Override public URL getHtmlUrl() { return GitHubClient.parseURL(html_url); } diff --git a/src/main/java/org/kohsuke/github/GHPullRequestReviewState.java b/src/main/java/org/kohsuke/github/GHPullRequestReviewState.java index 27026f4783..3d755f9555 100644 --- a/src/main/java/org/kohsuke/github/GHPullRequestReviewState.java +++ b/src/main/java/org/kohsuke/github/GHPullRequestReviewState.java @@ -15,14 +15,6 @@ public enum GHPullRequestReviewState { /** The changes requested. */ CHANGES_REQUESTED, - /** - * The request changes. - * - * @deprecated This was the thing when this API was in preview, but it changed when it became public. Use - * {@link #CHANGES_REQUESTED}. Left here for compatibility. - */ - REQUEST_CHANGES, - /** The commented. */ COMMENTED, @@ -33,9 +25,8 @@ public enum GHPullRequestReviewState { * Action string. * * @return the string - * @deprecated This was an internal method accidentally exposed. Left here for compatibility. */ - public String action() { + String action() { GHPullRequestReviewEvent e = toEvent(); return e == null ? null : e.action(); } @@ -53,8 +44,6 @@ GHPullRequestReviewEvent toEvent() { return GHPullRequestReviewEvent.APPROVE; case CHANGES_REQUESTED : return GHPullRequestReviewEvent.REQUEST_CHANGES; - case REQUEST_CHANGES : - return GHPullRequestReviewEvent.REQUEST_CHANGES; case COMMENTED : return GHPullRequestReviewEvent.COMMENT; } diff --git a/src/main/java/org/kohsuke/github/GHRateLimit.java b/src/main/java/org/kohsuke/github/GHRateLimit.java index 84c9345e77..06af2831bf 100644 --- a/src/main/java/org/kohsuke/github/GHRateLimit.java +++ b/src/main/java/org/kohsuke/github/GHRateLimit.java @@ -30,33 +30,6 @@ @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD", justification = "JSON API") public class GHRateLimit { - /** - * Remaining calls that can be made. - * - * @deprecated This field should never have been made public. Use {@link #getRemaining()} - */ - @Deprecated - public int remaining; - - /** - * Allotted API call per hour. - * - * @deprecated This field should never have been made public. Use {@link #getLimit()} - */ - @Deprecated - public int limit; - - /** - * The time at which the current rate limit window resets in UTC epoch seconds. WARNING: this field was implemented - * using {@link Date#Date(long)} which expects UTC epoch milliseconds, so this Date instance is meaningless as a - * date. To use this field in any meaningful way, it must be converted to a long using {@link Date#getTime()} - * multiplied by 1000. - * - * @deprecated This field should never have been made public. Use {@link #getResetDate()} - */ - @Deprecated - public Date reset; - @Nonnull private final Record core; @@ -150,12 +123,6 @@ static GHRateLimit fromRecord(@Nonnull Record record, @Nonnull RateLimitTarget r this.search = search; this.graphql = graphql; this.integrationManifest = integrationManifest; - - // Deprecated fields - this.remaining = core.getRemaining(); - this.limit = core.getLimit(); - // This is wrong but is how this was implemented. Kept for backward compat. - this.reset = new Date(core.getResetEpochSeconds()); } /** diff --git a/src/main/java/org/kohsuke/github/GHReaction.java b/src/main/java/org/kohsuke/github/GHReaction.java index 6a0cadcbcb..5f35c7a3da 100644 --- a/src/main/java/org/kohsuke/github/GHReaction.java +++ b/src/main/java/org/kohsuke/github/GHReaction.java @@ -2,9 +2,6 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import java.io.IOException; -import java.net.URL; - // TODO: Auto-generated Javadoc /** * Reaction to issue, comment, PR, and so on. @@ -35,29 +32,4 @@ public ReactionContent getContent() { public GHUser getUser() { return user; } - - /** - * Reaction has no HTML URL. Don't call this method. - * - * @return the html url - */ - @Deprecated - public URL getHtmlUrl() { - return null; - } - - /** - * Removes this reaction. - * - * @throws IOException - * the io exception - * @see Legacy Delete - * reactions REST API removed - * @deprecated this API is no longer supported by GitHub, keeping it as is for old versions of GitHub Enterprise - */ - @Deprecated - public void delete() throws IOException { - throw new UnsupportedOperationException( - "This method is not supported anymore. Please use Reactable#deleteReaction(GHReaction)."); - } } diff --git a/src/main/java/org/kohsuke/github/GHRelease.java b/src/main/java/org/kohsuke/github/GHRelease.java index 712255c019..4c31b52f4f 100644 --- a/src/main/java/org/kohsuke/github/GHRelease.java +++ b/src/main/java/org/kohsuke/github/GHRelease.java @@ -18,7 +18,6 @@ /** * Release in a github repository. * - * @see GHRepository#getReleases() GHRepository#getReleases() * @see GHRepository#listReleases() () GHRepository#listReleases() * @see GHRepository#createRelease(String) GHRepository#createRelease(String) */ @@ -78,21 +77,6 @@ public boolean isDraft() { return draft; } - /** - * Sets draft. - * - * @param draft - * the draft - * @return the draft - * @throws IOException - * the io exception - * @deprecated Use {@link #update()} - */ - @Deprecated - public GHRelease setDraft(boolean draft) throws IOException { - return update().draft(draft).update(); - } - /** * Gets the html url. * @@ -131,18 +115,6 @@ public GHRepository getOwner() { return owner; } - /** - * Sets owner. - * - * @param owner - * the owner - * @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding. - */ - @Deprecated - public void setOwner(GHRepository owner) { - throw new RuntimeException("Do not use this method."); - } - /** * Is prerelease boolean. * @@ -286,39 +258,17 @@ public GHAsset uploadAsset(String filename, InputStream stream, String contentTy * Get the cached assets. * * @return the assets - * - * @deprecated This should be the default behavior of {@link #getAssets()} in a future release. This method is - * introduced in addition to enable a transition to using cached asset information while keeping the - * existing logic in place for backwards compatibility. */ - @Deprecated - public List assets() { + public List getAssets() { return Collections.unmodifiableList(assets); } /** * Re-fetch the assets of this release. * - * @return the assets - * @throws IOException - * the io exception - * @deprecated The behavior of this method will change in a future release. It will then provide cached assets as - * provided by {@link #assets()}. Use {@link #listAssets()} instead to fetch up-to-date information of - * assets. - */ - @Deprecated - public List getAssets() throws IOException { - return listAssets().toList(); - } - - /** - * Re-fetch the assets of this release. - * - * @return the assets - * @throws IOException - * the io exception + * @return the assets iterable */ - public PagedIterable listAssets() throws IOException { + public PagedIterable listAssets() { Requester builder = owner.root().createRequest(); return builder.withUrlPath(getApiTailUrl("assets")).toIterable(GHAsset[].class, item -> item.wrap(this)); } diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index d13a3c7cdc..80e6abc5de 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -24,7 +24,6 @@ package org.kohsuke.github; import com.fasterxml.jackson.annotation.JsonProperty; -import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -39,15 +38,12 @@ import java.io.InterruptedIOException; import java.io.Reader; import java.net.URL; -import java.util.AbstractSet; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; @@ -153,21 +149,6 @@ public GHDeploymentBuilder createDeployment(String ref) { return new GHDeploymentBuilder(this, ref); } - /** - * Gets deployment statuses. - * - * @param id - * the id - * @return the deployment statuses - * @throws IOException - * the io exception - * @deprecated Use {@code getDeployment(id).listStatuses()} - */ - @Deprecated - public PagedIterable getDeploymentStatuses(final int id) throws IOException { - return getDeployment(id).listStatuses(); - } - /** * List deployments paged iterable. * @@ -207,24 +188,6 @@ public GHDeployment getDeployment(long id) throws IOException { .wrap(this); } - /** - * Gets deploy status. - * - * @param deploymentId - * the deployment id - * @param ghDeploymentState - * the gh deployment state - * @return the deploy status - * @throws IOException - * the io exception - * @deprecated Use {@code getDeployment(deploymentId).createStatus(ghDeploymentState)} - */ - @Deprecated - public GHDeploymentStatusBuilder createDeployStatus(int deploymentId, GHDeploymentState ghDeploymentState) - throws IOException { - return getDeployment(deploymentId).createStatus(ghDeploymentState); - } - static class GHRepoPermission { boolean pull, push, admin; } @@ -274,17 +237,6 @@ public String getHttpTransportUrl() { return clone_url; } - /** - * Git http transport url string. - * - * @return the string - * @deprecated Typo of {@link #getHttpTransportUrl()} - */ - @Deprecated - public String gitHttpTransportUrl() { - return clone_url; - } - /** * Gets the Subversion URL to access this repository: https://github.com/rails/rails * @@ -444,19 +396,6 @@ public List getIssues(GHIssueState state, GHMilestone milestone) throws .toList(); } - /** - * Lists up all the issues in this repository. - * - * @param state - * the state - * @return the paged iterable - * @deprecated Use {@link #queryIssues()} - */ - @Deprecated - public PagedIterable listIssues(final GHIssueState state) { - return queryIssues().state(state).list(); - } - /** * Retrieves issues. * @@ -498,18 +437,6 @@ public GHRef createRef(String name, String sha) throws IOException { .fetch(GHRef.class); } - /** - * Gets releases. - * - * @return the releases - * @throws IOException - * the io exception - * @deprecated use {@link #listReleases()} - */ - public List getReleases() throws IOException { - return listReleases().toList(); - } - /** * Gets release. * @@ -726,18 +653,6 @@ public boolean isDeleteBranchOnMerge() { return delete_branch_on_merge; } - /** - * Returns the number of all forks of this repository. This not only counts direct forks, but also forks of forks, - * and so on. - * - * @return the forks - * @deprecated use {@link #getForksCount()} instead - */ - @Deprecated - public int getForks() { - return getForksCount(); - } - /** * Returns the number of all forks of this repository. This not only counts direct forks, but also forks of forks, * and so on. @@ -836,7 +751,6 @@ public Visibility getVisibility() { * @return the boolean */ public boolean isTemplate() { - // isTemplate is still in preview, we do not want to retrieve it unless needed. if (isTemplate == null) { try { populate(); @@ -868,17 +782,6 @@ public boolean hasPages() { return has_pages; } - /** - * Gets watchers. - * - * @return the watchers - * @deprecated use {@link #getWatchersCount()} instead - */ - @Deprecated - public int getWatchers() { - return getWatchersCount(); - } - /** * Gets the count of watchers. * @@ -924,19 +827,6 @@ public String getDefaultBranch() { return default_branch; } - /** - * Gets default branch. - * - * Name is an artifact of when "master" was the most common default. - * - * @return the default branch - * @deprecated Renamed to {@link #getDefaultBranch()} - */ - @Deprecated - public String getMasterBranch() { - return default_branch; - } - /** * Get Repository template was the repository created from. * @@ -976,7 +866,6 @@ public enum CollaboratorAffiliation { * @throws IOException * the io exception */ - @WithBridgeMethods(Set.class) public GHPersonSet getCollaborators() throws IOException { return new GHPersonSet(listCollaborators().toList()); } @@ -1164,22 +1053,6 @@ public Set getTeams() throws IOException { .toSet(); } - /** - * Add collaborators. - * - * @param permission - * the permission level - * @param users - * the users - * @throws IOException - * the io exception - * @deprecated #addCollaborators(GHOrganization.RolePermission, GHUser) - */ - @Deprecated - public void addCollaborators(GHOrganization.Permission permission, GHUser... users) throws IOException { - addCollaborators(asList(users), permission); - } - /** * Add collaborators. * @@ -1219,22 +1092,6 @@ public void addCollaborators(Collection users) throws IOException { modifyCollaborators(users, "PUT", null); } - /** - * Add collaborators. - * - * @param users - * the users - * @param permission - * the permission level - * @throws IOException - * the io exception - * @deprecated #addCollaborators(Collection, GHOrganization.RolePermission) - */ - @Deprecated - public void addCollaborators(Collection users, GHOrganization.Permission permission) throws IOException { - modifyCollaborators(users, "PUT", GHOrganization.RepositoryRole.from(permission)); - } - /** * Add collaborators. * @@ -1676,33 +1533,6 @@ public GHPullRequest getPullRequest(int i) throws IOException { return root().createRequest().withUrlPath(getApiTailUrl("pulls/" + i)).fetch(GHPullRequest.class).wrapUp(this); } - /** - * Retrieves all the pull requests of a particular state. - * - * @param state - * the state - * @return the pull requests - * @throws IOException - * the io exception - * @see #listPullRequests(GHIssueState) #listPullRequests(GHIssueState) - */ - public List getPullRequests(GHIssueState state) throws IOException { - return queryPullRequests().state(state).list().toList(); - } - - /** - * Retrieves all the pull requests of a particular state. - * - * @param state - * the state - * @return the paged iterable - * @deprecated Use {@link #queryPullRequests()} - */ - @Deprecated - public PagedIterable listPullRequests(GHIssueState state) { - return queryPullRequests().state(state).list(); - } - /** * Retrieves pull requests. * @@ -2443,22 +2273,24 @@ public PagedIterable listSubscribers() { } /** - * Lists all the users who have starred this repo based on the old version of the API. For additional information, - * like date when the repository was starred, see {@link #listStargazers2()} + * Lists all the users who have starred this repo based on new version of the API, having extended information like + * the time when the repository was starred. * * @return the paged iterable + * @deprecated Use {@link #listStargazers()} */ - public PagedIterable listStargazers() { - return listUsers("stargazers"); + @Deprecated + public PagedIterable listStargazers2() { + return listStargazers(); } /** * Lists all the users who have starred this repo based on new version of the API, having extended information like - * the time when the repository was starred. For compatibility with the old API see {@link #listStargazers()} + * the time when the repository was starred. * * @return the paged iterable */ - public PagedIterable listStargazers2() { + public PagedIterable listStargazers() { return root().createRequest() .withAccept("application/vnd.github.star+json") .withUrlPath(getApiTailUrl("stargazers")) @@ -2522,89 +2354,6 @@ public GHHook createWebHook(URL url) throws IOException { return createWebHook(url, null); } - /** - * Returns a set that represents the post-commit hook URLs. The returned set is live, and changes made to them are - * reflected to GitHub. - * - * @return the post commit hooks - * @deprecated Use {@link #getHooks()} and {@link #createHook(String, Map, Collection, boolean)} - */ - @SuppressFBWarnings(value = { "DMI_COLLECTION_OF_URLS", "EI_EXPOSE_REP" }, - justification = "It causes a performance degradation, but we have already exposed it to the API") - @Deprecated - public Set getPostCommitHooks() { - synchronized (this) { - if (postCommitHooks == null) { - postCommitHooks = setupPostCommitHooks(); - } - return postCommitHooks; - } - } - - /** - * Live set view of the post-commit hook. - */ - @SuppressFBWarnings(value = "DMI_COLLECTION_OF_URLS", - justification = "It causes a performance degradation, but we have already exposed it to the API") - @SkipFromToString - private /* final */ transient Set postCommitHooks; - - @SuppressFBWarnings(value = "DMI_COLLECTION_OF_URLS", - justification = "It causes a performance degradation, but we have already exposed it to the API") - private Set setupPostCommitHooks() { - return new AbstractSet() { - private List getPostCommitHooks() { - try { - List r = new ArrayList<>(); - for (GHHook h : getHooks()) { - if (h.getName().equals("web")) { - r.add(new URL(h.getConfig().get("url"))); - } - } - return r; - } catch (IOException e) { - throw new GHException("Failed to retrieve post-commit hooks", e); - } - } - - @Override - public Iterator iterator() { - return getPostCommitHooks().iterator(); - } - - @Override - public int size() { - return getPostCommitHooks().size(); - } - - @Override - public boolean add(URL url) { - try { - createWebHook(url); - return true; - } catch (IOException e) { - throw new GHException("Failed to update post-commit hooks", e); - } - } - - @Override - public boolean remove(Object url) { - try { - String _url = ((URL) url).toExternalForm(); - for (GHHook h : getHooks()) { - if (h.getName().equals("web") && h.getConfig().get("url").equals(_url)) { - h.delete(); - return true; - } - } - return false; - } catch (IOException e) { - throw new GHException("Failed to update post-commit hooks", e); - } - } - }; - } - /** * Gets branches by {@linkplain GHBranch#getName() their names}. * @@ -2636,22 +2385,6 @@ public GHBranch getBranch(String name) throws IOException { return root().createRequest().withUrlPath(getApiTailUrl("branches/" + name)).fetch(GHBranch.class).wrap(this); } - /** - * Gets milestones. - * - * @return the milestones - * @throws IOException - * the io exception - * @deprecated Use {@link #listMilestones(GHIssueState)} - */ - public Map getMilestones() throws IOException { - Map milestones = new TreeMap(); - for (GHMilestone m : listMilestones(GHIssueState.OPEN)) { - milestones.put(m.getNumber(), m); - } - return milestones; - } - /** * Lists up all the milestones in this repository. * @@ -2779,20 +2512,6 @@ public void createVariable(String name, String value) throws IOException { GHRepositoryVariable.create(this).name(name).value(value).done(); } - /** - * Gets a variable by name - * - * @param name - * the variable name (e.g. test-variable) - * @return the variable - * @throws IOException - * the io exception - */ - @Deprecated - public GHRepositoryVariable getRepoVariable(String name) throws IOException { - return getVariable(name); - } - /** * Gets a repository variable. * @@ -2815,85 +2534,6 @@ public GHContentBuilder createContent() { return new GHContentBuilder(this); } - /** - * Use {@link #createContent()}. - * - * @param content - * the content - * @param commitMessage - * the commit message - * @param path - * the path - * @return the gh content update response - * @throws IOException - * the io exception - */ - @Deprecated - public GHContentUpdateResponse createContent(String content, String commitMessage, String path) throws IOException { - return createContent().content(content).message(commitMessage).path(path).commit(); - } - - /** - * Use {@link #createContent()}. - * - * @param content - * the content - * @param commitMessage - * the commit message - * @param path - * the path - * @param branch - * the branch - * @return the gh content update response - * @throws IOException - * the io exception - */ - @Deprecated - public GHContentUpdateResponse createContent(String content, String commitMessage, String path, String branch) - throws IOException { - return createContent().content(content).message(commitMessage).path(path).branch(branch).commit(); - } - - /** - * Use {@link #createContent()}. - * - * @param contentBytes - * the content bytes - * @param commitMessage - * the commit message - * @param path - * the path - * @return the gh content update response - * @throws IOException - * the io exception - */ - @Deprecated - public GHContentUpdateResponse createContent(byte[] contentBytes, String commitMessage, String path) - throws IOException { - return createContent().content(contentBytes).message(commitMessage).path(path).commit(); - } - - /** - * Use {@link #createContent()}. - * - * @param contentBytes - * the content bytes - * @param commitMessage - * the commit message - * @param path - * the path - * @param branch - * the branch - * @return the gh content update response - * @throws IOException - * the io exception - */ - @Deprecated - public GHContentUpdateResponse createContent(byte[] contentBytes, String commitMessage, String path, String branch) - throws IOException { - return createContent().content(contentBytes).message(commitMessage).path(path).branch(branch).commit(); - } - /** * Create milestone gh milestone. * @@ -3590,7 +3230,6 @@ void populate() throws IOException { // "https://github.com/{fullName}". // All other occurrences of "url" take the form "https://api.github.com/...". // 2. For Installation event payloads, the URL is not provided at all. - root().createRequest().withUrlPath(getApiTailUrl("")).fetchInto(this); } diff --git a/src/main/java/org/kohsuke/github/GHRepositoryPublicKey.java b/src/main/java/org/kohsuke/github/GHRepositoryPublicKey.java index 9d7ab86c71..c3a8d5fc98 100644 --- a/src/main/java/org/kohsuke/github/GHRepositoryPublicKey.java +++ b/src/main/java/org/kohsuke/github/GHRepositoryPublicKey.java @@ -2,9 +2,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; -import java.io.IOException; -import java.net.URL; - // TODO: Auto-generated Javadoc /** * A public key for the given repository. @@ -19,18 +16,6 @@ public class GHRepositoryPublicKey extends GHObject { private String keyId; private String key; - /** - * Gets the html url. - * - * @return the html url - * @throws IOException - * Signals that an I/O exception has occurred. - */ - @Override - public URL getHtmlUrl() throws IOException { - return null; - } - /** * Gets the key id. * diff --git a/src/main/java/org/kohsuke/github/GHRepositorySearchBuilder.java b/src/main/java/org/kohsuke/github/GHRepositorySearchBuilder.java index ed770fd995..c0e3220911 100644 --- a/src/main/java/org/kohsuke/github/GHRepositorySearchBuilder.java +++ b/src/main/java/org/kohsuke/github/GHRepositorySearchBuilder.java @@ -61,56 +61,14 @@ public GHRepositorySearchBuilder size(String v) { return q("size:" + v); } - /** - * Forks gh repository search builder. - * - * @param v - * the v - * @return the gh repository search builder - * @deprecated use {@link #fork(GHFork)} instead. - */ - @Deprecated - public GHRepositorySearchBuilder forks(String v) { - return q("fork", v); - } - /** * Searching in forks * - * The default search mode is {@link Fork#PARENT_ONLY}. In that mode, forks are not included in search results. + * The default search mode is {@link GHFork#PARENT_ONLY}. In that mode, forks are not included in search results. * *

- * Passing {@link Fork#PARENT_AND_FORKS} or {@link Fork#FORKS_ONLY} will show results from forks, but only if they - * have more stars than the parent repository. - * - *

- * IMPORTANT: Regardless of this setting, no search results will ever be returned for forks with equal or fewer - * stars than the parent repository. Forks with less stars than the parent repository are not included in the index - * for code searching. - * - * @param fork - * search mode for forks - * - * @return the gh repository search builder - * - * @see Searching - * in forks - * @deprecated use {@link #fork(GHFork)} instead. - */ - @Deprecated - public GHRepositorySearchBuilder fork(Fork fork) { - return q("fork", fork.toString()); - } - - /** - * Searching in forks - * - * The default search mode is {@link Fork#PARENT_ONLY}. In that mode, forks are not included in search results. - * - *

- * Passing {@link Fork#PARENT_AND_FORKS} or {@link Fork#FORKS_ONLY} will show results from forks, but only if they - * have more stars than the parent repository. + * Passing {@link GHFork#PARENT_AND_FORKS} or {@link GHFork#FORKS_ONLY} will show results from forks, but only if + * they have more stars than the parent repository. * *

* IMPORTANT: Regardless of this setting, no search results will ever be returned for forks with equal or fewer @@ -278,58 +236,6 @@ public enum Sort { UPDATED } - /** - * The enum for Fork search mode. - * - * @deprecated Kept for backward compatibility. Use {@link GHFork} instead. - */ - @Deprecated - public enum Fork { - - /** - * Search in the parent repository and in forks with more stars than the parent repository. - * - * Forks with the same or fewer stars than the parent repository are still ignored. - */ - PARENT_AND_FORKS("true"), - - /** - * Search only in forks with more stars than the parent repository. - * - * The parent repository is ignored. If no forks have more stars than the parent, no results will be returned. - */ - FORKS_ONLY("only"), - - /** - * (Default) Search only the parent repository. - * - * Forks are ignored. - */ - PARENT_ONLY(""); - - private String filterMode; - - /** - * Instantiates a new fork. - * - * @param mode - * the mode - */ - Fork(final String mode) { - this.filterMode = mode; - } - - /** - * To string. - * - * @return the string - */ - @Override - public String toString() { - return filterMode; - } - } - @SuppressFBWarnings( value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" }, justification = "JSON API") diff --git a/src/main/java/org/kohsuke/github/GHRepositoryStatistics.java b/src/main/java/org/kohsuke/github/GHRepositoryStatistics.java index 35c8bfea55..c7cdc310b6 100644 --- a/src/main/java/org/kohsuke/github/GHRepositoryStatistics.java +++ b/src/main/java/org/kohsuke/github/GHRepositoryStatistics.java @@ -5,7 +5,6 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.io.IOException; -import java.net.URL; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -103,18 +102,6 @@ public static class ContributorStats extends GHObject { private int total; private List weeks; - /** - * Gets the html url. - * - * @return the html url - * @throws IOException - * Signals that an I/O exception has occurred. - */ - @Override - public URL getHtmlUrl() throws IOException { - throw new UnsupportedOperationException("Not supported yet."); - } - /** * Gets author. * @@ -288,18 +275,6 @@ public int getTotal() { public long getWeek() { return week; } - - /** - * Gets the html url. - * - * @return the html url - * @throws IOException - * Signals that an I/O exception has occurred. - */ - @Override - public URL getHtmlUrl() throws IOException { - throw new UnsupportedOperationException("Not supported yet."); - } } /** @@ -401,18 +376,6 @@ public static class Participation extends GHObject { private List all; private List owner; - /** - * Gets the html url. - * - * @return the html url - * @throws IOException - * Signals that an I/O exception has occurred. - */ - @Override - public URL getHtmlUrl() throws IOException { - throw new UnsupportedOperationException("Not supported yet."); - } - /** * Gets all commits. * diff --git a/src/main/java/org/kohsuke/github/GHRequestedAction.java b/src/main/java/org/kohsuke/github/GHRequestedAction.java index db87a833ba..305337d022 100644 --- a/src/main/java/org/kohsuke/github/GHRequestedAction.java +++ b/src/main/java/org/kohsuke/github/GHRequestedAction.java @@ -2,8 +2,6 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import java.net.URL; - // TODO: Auto-generated Javadoc /** * The Class GHRequestedAction. @@ -55,15 +53,4 @@ String getDescription() { return description; } - /** - * Gets the html url. - * - * @return the html url - * @deprecated This object has no HTML URL. - */ - @Override - public URL getHtmlUrl() { - return null; - } - } diff --git a/src/main/java/org/kohsuke/github/GHTeam.java b/src/main/java/org/kohsuke/github/GHTeam.java index 4d94735aec..7ac5e7a53d 100644 --- a/src/main/java/org/kohsuke/github/GHTeam.java +++ b/src/main/java/org/kohsuke/github/GHTeam.java @@ -341,22 +341,6 @@ public void add(GHRepository r) throws IOException { add(r, (GHOrganization.RepositoryRole) null); } - /** - * * Add. - * - * @param r - * the r - * @param permission - * the permission - * @throws IOException - * the io exception - * @deprecated use {@link GHTeam#add(GHRepository, org.kohsuke.github.GHOrganization.RepositoryRole)} - */ - @Deprecated - public void add(GHRepository r, GHOrganization.Permission permission) throws IOException { - add(r, GHOrganization.RepositoryRole.from(permission)); - } - /** * Add. * @@ -535,7 +519,6 @@ public void refresh() throws IOException { * * @return the html url */ - @Override public URL getHtmlUrl() { return GitHubClient.parseURL(html_url); } diff --git a/src/main/java/org/kohsuke/github/GHTeamBuilder.java b/src/main/java/org/kohsuke/github/GHTeamBuilder.java index f1583fb8db..6db44008af 100644 --- a/src/main/java/org/kohsuke/github/GHTeamBuilder.java +++ b/src/main/java/org/kohsuke/github/GHTeamBuilder.java @@ -70,6 +70,21 @@ public GHTeamBuilder repositories(String... repoNames) { return this; } + /** + * The permission that new repositories will be added to the team with when none is specified. + * + * @param permission + * permssion to be applied + * @return a builder to continue with building + * @deprecated see + * https://docs.github.com/en/free-pro-team@latest/rest/teams/teams?apiVersion=2022-11-28#create-a-team + */ + @Deprecated + public GHTeamBuilder permission(GHOrganization.Permission permission) { + this.builder.with("permission", permission); + return this; + } + /** * Description for this team. * diff --git a/src/main/java/org/kohsuke/github/GHThread.java b/src/main/java/org/kohsuke/github/GHThread.java index 383f2b2fef..2bafc28307 100644 --- a/src/main/java/org/kohsuke/github/GHThread.java +++ b/src/main/java/org/kohsuke/github/GHThread.java @@ -4,7 +4,6 @@ import java.io.FileNotFoundException; import java.io.IOException; -import java.net.URL; import java.util.Date; // TODO: Auto-generated Javadoc @@ -55,17 +54,6 @@ public Date getLastReadAt() { return GitHubClient.parseDate(last_read_at); } - /** - * Gets the html url. - * - * @return the html url - * @deprecated This object has no HTML URL. - */ - @Override - public URL getHtmlUrl() { - return null; - } - /** * Gets reason. * diff --git a/src/main/java/org/kohsuke/github/GHTreeBuilder.java b/src/main/java/org/kohsuke/github/GHTreeBuilder.java index 892afb7686..c7e1902124 100644 --- a/src/main/java/org/kohsuke/github/GHTreeBuilder.java +++ b/src/main/java/org/kohsuke/github/GHTreeBuilder.java @@ -77,33 +77,7 @@ public GHTreeBuilder baseTree(String baseTree) { } /** - * Adds a new entry to the tree. Exactly one of the parameters {@code sha} and {@code content} must be non-null. - * - * @param path - * the path - * @param mode - * the mode - * @param type - * the type - * @param sha - * the sha - * @param content - * the content - * @return the gh tree builder - * @deprecated use {@link #add(String, String, boolean)} or {@link #add(String, byte[], boolean)} instead. - */ - @Deprecated - public GHTreeBuilder entry(String path, String mode, String type, String sha, String content) { - TreeEntry entry = new TreeEntry(path, mode, type); - entry.sha = sha; - entry.content = content; - treeEntries.add(entry); - return this; - } - - /** - * Specialized version of {@link #entry(String, String, String, String, String)} for adding an existing blob - * referred by its SHA. + * Specialized version of entry() for adding an existing blob referred by its SHA. * * @param path * the path @@ -123,8 +97,7 @@ public GHTreeBuilder shaEntry(String path, String sha, boolean executable) { } /** - * Specialized version of {@link #entry(String, String, String, String, String)} for adding a text file with the - * specified {@code content}. + * Specialized version of entry() for adding an existing blob specified {@code content}. * * @param path * the path diff --git a/src/main/java/org/kohsuke/github/GHUser.java b/src/main/java/org/kohsuke/github/GHUser.java index dc25a3fd51..afbed86554 100644 --- a/src/main/java/org/kohsuke/github/GHUser.java +++ b/src/main/java/org/kohsuke/github/GHUser.java @@ -23,8 +23,6 @@ */ package org.kohsuke.github; -import com.infradna.tool.bridge_method_injector.WithBridgeMethods; - import java.io.IOException; import java.util.*; @@ -80,7 +78,6 @@ public void unfollow() throws IOException { * @throws IOException * the io exception */ - @WithBridgeMethods(Set.class) public GHPersonSet getFollows() throws IOException { return new GHPersonSet(listFollows().toList()); } @@ -101,7 +98,6 @@ public PagedIterable listFollows() { * @throws IOException * the io exception */ - @WithBridgeMethods(Set.class) public GHPersonSet getFollowers() throws IOException { return new GHPersonSet(listFollowers().toList()); } @@ -212,7 +208,6 @@ public String getBio() { * @throws IOException * the io exception */ - @WithBridgeMethods(Set.class) public GHPersonSet getOrganizations() throws IOException { GHPersonSet orgs = new GHPersonSet(); Set names = new HashSet(); diff --git a/src/main/java/org/kohsuke/github/GHWorkflow.java b/src/main/java/org/kohsuke/github/GHWorkflow.java index b016e5d6bc..1a2b28dfe5 100644 --- a/src/main/java/org/kohsuke/github/GHWorkflow.java +++ b/src/main/java/org/kohsuke/github/GHWorkflow.java @@ -64,7 +64,6 @@ public String getState() { * @throws IOException * Signals that an I/O exception has occurred. */ - @Override public URL getHtmlUrl() throws IOException { return GitHubClient.parseURL(htmlUrl); } diff --git a/src/main/java/org/kohsuke/github/GHWorkflowJob.java b/src/main/java/org/kohsuke/github/GHWorkflowJob.java index 82a487d72f..326b903aa4 100644 --- a/src/main/java/org/kohsuke/github/GHWorkflowJob.java +++ b/src/main/java/org/kohsuke/github/GHWorkflowJob.java @@ -135,7 +135,6 @@ public int getRunAttempt() { * * @return the html url */ - @Override public URL getHtmlUrl() { return GitHubClient.parseURL(htmlUrl); } diff --git a/src/main/java/org/kohsuke/github/GHWorkflowRun.java b/src/main/java/org/kohsuke/github/GHWorkflowRun.java index b12e8f005e..efb8bfa68c 100644 --- a/src/main/java/org/kohsuke/github/GHWorkflowRun.java +++ b/src/main/java/org/kohsuke/github/GHWorkflowRun.java @@ -120,7 +120,6 @@ public Date getRunStartedAt() throws IOException { * @throws IOException * Signals that an I/O exception has occurred. */ - @Override public URL getHtmlUrl() throws IOException { return GitHubClient.parseURL(htmlUrl); } diff --git a/src/main/java/org/kohsuke/github/GitCommit.java b/src/main/java/org/kohsuke/github/GitCommit.java index 0c522b57db..4478edf7cc 100644 --- a/src/main/java/org/kohsuke/github/GitCommit.java +++ b/src/main/java/org/kohsuke/github/GitCommit.java @@ -1,6 +1,5 @@ package org.kohsuke.github; -import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.AbstractList; @@ -77,7 +76,7 @@ public GitCommit() { */ GitCommit(GitCommit commit) { // copy constructor used to cast to GitCommit.ShortInfo and from there - // to GHCommit, for GHContentUpdateResponse bridge method to GHCommit + // to GHCommit, for testing purposes this.owner = commit.getOwner(); this.sha = commit.getSha(); this.node_id = commit.getNodeId(); @@ -151,17 +150,10 @@ public String getHtmlUrl() { * * @return the author */ - @WithBridgeMethods(value = GHCommit.GHAuthor.class, adapterMethod = "gitUserToGHAuthor") public GitUser getAuthor() { return author; } - @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", - justification = "bridge method of getAuthor & getCommitter") - private Object gitUserToGHAuthor(GitUser author, Class targetType) { - return new GHCommit.GHAuthor(author); - } - /** * Gets authored date. * @@ -176,7 +168,6 @@ public Date getAuthoredDate() { * * @return the committer */ - @WithBridgeMethods(value = GHCommit.GHAuthor.class, adapterMethod = "gitUserToGHAuthor") public GitUser getCommitter() { return committer; } @@ -278,4 +269,13 @@ GitCommit wrapUp(GHRepository owner) { return this; } + /** + * For test purposes only. + * + * @return Equivalent GHCommit + */ + GHCommit toGHCommit() { + return new GHCommit(new GHCommit.ShortInfo(this)); + } + } diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index de7d95fb7e..aa5b6239e3 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -25,13 +25,11 @@ import com.fasterxml.jackson.databind.ObjectReader; import com.fasterxml.jackson.databind.ObjectWriter; -import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import org.kohsuke.github.authorization.AuthorizationProvider; import org.kohsuke.github.authorization.ImmutableAuthorizationProvider; import org.kohsuke.github.authorization.UserAuthorizationProvider; import org.kohsuke.github.connector.GitHubConnector; -import org.kohsuke.github.internal.GitHubConnectorHttpConnectorAdapter; import java.io.*; import java.util.*; @@ -99,7 +97,7 @@ public class GitHub { * The URL of GitHub (or GitHub enterprise) API endpoint, such as "https://api.github.com" or * "http://ghe.acme.com/api/v3". Note that GitHub Enterprise has /api/v3 in the URL. For * historical reasons, this parameter still accepts the bare domain name, but that's considered - * deprecated. Password is also considered deprecated as it is no longer required for api usage. + * deprecated. * @param connector * a connector * @param rateLimitHandler @@ -274,26 +272,6 @@ public static GitHub connect() throws IOException { return GitHubBuilder.fromCredentials().build(); } - /** - * Version that connects to GitHub Enterprise. - * - * @param apiUrl - * The URL of GitHub (or GitHub Enterprise) API endpoint, such as "https://api.github.com" or - * "http://ghe.acme.com/api/v3". Note that GitHub Enterprise has /api/v3 in the URL. For - * historical reasons, this parameter still accepts the bare domain name, but that's considered - * deprecated. - * @param oauthAccessToken - * the oauth access token - * @return the git hub - * @throws IOException - * the io exception - * @deprecated Use {@link #connectToEnterpriseWithOAuth(String, String, String)} - */ - @Deprecated - public static GitHub connectToEnterprise(String apiUrl, String oauthAccessToken) throws IOException { - return connectToEnterpriseWithOAuth(apiUrl, null, oauthAccessToken); - } - /** * Version that connects to GitHub Enterprise. * @@ -315,25 +293,6 @@ public static GitHub connectToEnterpriseWithOAuth(String apiUrl, String login, S return new GitHubBuilder().withEndpoint(apiUrl).withOAuthToken(oauthAccessToken, login).build(); } - /** - * Version that connects to GitHub Enterprise. - * - * @param apiUrl - * the api url - * @param login - * the login - * @param password - * the password - * @return the git hub - * @throws IOException - * the io exception - * @deprecated Use with caution. Login with password is not a preferred method. - */ - @Deprecated - public static GitHub connectToEnterprise(String apiUrl, String login, String password) throws IOException { - return new GitHubBuilder().withEndpoint(apiUrl).withPassword(login, password).build(); - } - /** * Connect git hub. * @@ -349,45 +308,6 @@ public static GitHub connect(String login, String oauthAccessToken) throws IOExc return new GitHubBuilder().withOAuthToken(oauthAccessToken, login).build(); } - /** - * Connect git hub. - * - * @param login - * the login - * @param oauthAccessToken - * the oauth access token - * @param password - * the password - * @return the git hub - * @throws IOException - * the io exception - * @deprecated Use {@link #connectUsingOAuth(String)}. - */ - @Deprecated - public static GitHub connect(String login, String oauthAccessToken, String password) throws IOException { - return new GitHubBuilder().withOAuthToken(oauthAccessToken, login).withPassword(login, password).build(); - } - - /** - * Connect using password git hub. - * - * @param login - * the login - * @param password - * the password - * @return the git hub - * @throws IOException - * the io exception - * @see Deprecating - * password authentication and OAuth authorizations API - * @deprecated Use {@link #connectUsingOAuth(String)} instead. - */ - @Deprecated - public static GitHub connectUsingPassword(String login, String password) throws IOException { - return new GitHubBuilder().withPassword(login, password).build(); - } - /** * Connect using o auth git hub. * @@ -479,30 +399,6 @@ public boolean isOffline() { return client.isOffline(); } - /** - * Gets connector. - * - * @return the connector - * @deprecated HttpConnector has been replaced by GitHubConnector which is generally not useful outside of this - * library. If you are using this method, file an issue describing your use case. - */ - @Deprecated - public HttpConnector getConnector() { - return client.getConnector(); - } - - /** - * Sets the custom connector used to make requests to GitHub. - * - * @param connector - * the connector - * @deprecated HttpConnector should not be changed. If you find yourself needing to do this, file an issue. - */ - @Deprecated - public void setConnector(@Nonnull HttpConnector connector) { - client.setConnector(GitHubConnectorHttpConnectorAdapter.adapt(connector)); - } - /** * Gets api url. * @@ -568,7 +464,6 @@ public GHRateLimit rateLimit() throws IOException { * the io exception */ @SuppressFBWarnings(value = { "EI_EXPOSE_REP" }, justification = "Expected") - @WithBridgeMethods(value = GHUser.class) public GHMyself getMyself() throws IOException { client.requireCredential(); return setMyself(); @@ -684,22 +579,6 @@ public GHRepository getRepository(String name) throws IOException { return GHRepository.read(this, tokens[0], tokens[1]); } - /** - * Gets the repository object from its ID. - * - * @param id - * the id - * @return the repository by id - * @throws IOException - * the io exception - * @deprecated Do not use this method. It was added due to misunderstanding of the type of parameter. Use - * {@link #getRepositoryById(long)} instead - */ - @Deprecated - public GHRepository getRepositoryById(String id) throws IOException { - return createRequest().withUrlPath("/repositories/" + id).fetch(GHRepository.class); - } - /** * Gets the repository object from its ID. * @@ -883,27 +762,6 @@ public Map> getMyTeams() throws IOException { return allMyTeams; } - /** - * Gets a single team by ID. - *

- * This method is no longer supported and throws an UnsupportedOperationException. - * - * @param id - * the id - * @return the team - * @throws IOException - * the io exception - * @see deprecation notice - * @see sunset - * notice - * @deprecated Use {@link GHOrganization#getTeam(long)} - */ - @Deprecated - public GHTeam getTeam(int id) throws IOException { - throw new UnsupportedOperationException( - "This method is not supported anymore. Please use GHOrganization#getTeam(long)."); - } - /** * Public events visible to you. Equivalent of what's displayed on https://github.com/ * @@ -976,28 +834,6 @@ public T parseEventPayload(Reader r, Class type) t return t; } - /** - * Creates a new repository. - * - * @param name - * the name - * @param description - * the description - * @param homepage - * the homepage - * @param isPublic - * the is public - * @return Newly created repository. - * @throws IOException - * the io exception - * @deprecated Use {@link #createRepository(String)} that uses a builder pattern to let you control every aspect. - */ - @Deprecated - public GHRepository createRepository(String name, String description, String homepage, boolean isPublic) - throws IOException { - return createRepository(name).description(description).homepage(homepage).private_(!isPublic).create(); - } - /** * Starts a builder that creates a new repository. * @@ -1005,10 +841,6 @@ public GHRepository createRepository(String name, String description, String hom * You use the returned builder to set various properties, then call {@link GHCreateRepositoryBuilder#create()} to * finally create a repository. * - *

- * To create a repository in an organization, see - * {@link GHOrganization#createRepository(String, String, String, GHTeam, boolean)} - * * @param name * the name * @return the gh create repository builder diff --git a/src/main/java/org/kohsuke/github/GitHubAbuseLimitHandler.java b/src/main/java/org/kohsuke/github/GitHubAbuseLimitHandler.java index e769604525..33887cad04 100644 --- a/src/main/java/org/kohsuke/github/GitHubAbuseLimitHandler.java +++ b/src/main/java/org/kohsuke/github/GitHubAbuseLimitHandler.java @@ -3,10 +3,15 @@ import org.kohsuke.github.connector.GitHubConnectorResponse; import java.io.IOException; -import java.net.HttpURLConnection; +import java.io.InterruptedIOException; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; import javax.annotation.Nonnull; +import static java.net.HttpURLConnection.HTTP_FORBIDDEN; + // TODO: Auto-generated Javadoc /** * Pluggable strategy to determine what to do when the API rate limit is reached. @@ -52,7 +57,7 @@ private boolean isTooManyRequests(GitHubConnectorResponse connectorResponse) { * @return true if the status code is HTTP_FORBIDDEN */ private boolean isForbidden(GitHubConnectorResponse connectorResponse) { - return connectorResponse.statusCode() == HttpURLConnection.HTTP_FORBIDDEN; + return connectorResponse.statusCode() == HTTP_FORBIDDEN; } /** @@ -102,4 +107,55 @@ private boolean hasHeader(GitHubConnectorResponse connectorResponse, String head * */ public abstract void onError(@Nonnull GitHubConnectorResponse connectorResponse) throws IOException; + + /** + * Wait until the API abuse "wait time" is passed. + */ + public static final GitHubAbuseLimitHandler WAIT = new GitHubAbuseLimitHandler() { + @Override + public void onError(GitHubConnectorResponse connectorResponse) throws IOException { + try { + Thread.sleep(parseWaitTime(connectorResponse)); + } catch (InterruptedException ex) { + throw (InterruptedIOException) new InterruptedIOException().initCause(ex); + } + } + }; + + /** + * Fail immediately. + */ + public static final GitHubAbuseLimitHandler FAIL = new GitHubAbuseLimitHandler() { + @Override + public void onError(GitHubConnectorResponse connectorResponse) throws IOException { + throw new HttpException("Abuse limit reached", + connectorResponse.statusCode(), + connectorResponse.header("Status"), + connectorResponse.request().url().toString()) + .withResponseHeaderFields(connectorResponse.allHeaders()); + } + }; + + // If "Retry-After" missing, wait for unambiguously over one minute per GitHub guidance + static long DEFAULT_WAIT_MILLIS = 61 * 1000; + + /* + * Exposed for testability. Given an http response, find the retry-after header field and parse it as either a + * number or a date (the spec allows both). If no header is found, wait for a reasonably amount of time. + */ + static long parseWaitTime(GitHubConnectorResponse connectorResponse) { + String v = connectorResponse.header("Retry-After"); + if (v == null) { + return DEFAULT_WAIT_MILLIS; + } + + try { + return Math.max(1000, Long.parseLong(v) * 1000); + } catch (NumberFormatException nfe) { + // The retry-after header could be a number in seconds, or an http-date + ZonedDateTime zdt = ZonedDateTime.parse(v, DateTimeFormatter.RFC_1123_DATE_TIME); + return ChronoUnit.MILLIS.between(ZonedDateTime.now(), zdt); + } + } + } diff --git a/src/main/java/org/kohsuke/github/GitHubBuilder.java b/src/main/java/org/kohsuke/github/GitHubBuilder.java index b61be61f27..19f4c4a957 100644 --- a/src/main/java/org/kohsuke/github/GitHubBuilder.java +++ b/src/main/java/org/kohsuke/github/GitHubBuilder.java @@ -5,15 +5,11 @@ import org.kohsuke.github.authorization.ImmutableAuthorizationProvider; import org.kohsuke.github.connector.GitHubConnector; import org.kohsuke.github.connector.GitHubConnectorResponse; -import org.kohsuke.github.extras.ImpatientHttpConnector; -import org.kohsuke.github.internal.GitHubConnectorHttpConnectorAdapter; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.Proxy; import java.util.Locale; import java.util.Map.Entry; import java.util.Properties; @@ -38,8 +34,8 @@ public class GitHubBuilder implements Cloneable { private GitHubConnector connector; - private GitHubRateLimitHandler rateLimitHandler = RateLimitHandler.WAIT; - private GitHubAbuseLimitHandler abuseLimitHandler = AbuseLimitHandler.WAIT; + private GitHubRateLimitHandler rateLimitHandler = GitHubRateLimitHandler.WAIT; + private GitHubAbuseLimitHandler abuseLimitHandler = GitHubAbuseLimitHandler.WAIT; private GitHubRateLimitChecker rateLimitChecker = new GitHubRateLimitChecker(); /** The authorization provider. */ @@ -87,64 +83,12 @@ static GitHubBuilder fromCredentials() throws IOException { .initCause(cause); } - /** - * From environment git hub builder. - * - * @param loginVariableName - * the login variable name - * @param passwordVariableName - * the password variable name - * @param oauthVariableName - * the oauth variable name - * @return the git hub builder - * @throws IOException - * the io exception - * @deprecated Use {@link #fromEnvironment()} to pick up standard set of environment variables, so that different - * clients of this library will all recognize one consistent set of coordinates. - */ - @Deprecated - public static GitHubBuilder fromEnvironment(String loginVariableName, - String passwordVariableName, - String oauthVariableName) throws IOException { - return fromEnvironment(loginVariableName, passwordVariableName, oauthVariableName, ""); - } - private static void loadIfSet(String envName, Properties p, String propName) { String v = System.getenv(envName); if (v != null) p.put(propName, v); } - /** - * From environment git hub builder. - * - * @param loginVariableName - * the login variable name - * @param passwordVariableName - * the password variable name - * @param oauthVariableName - * the oauth variable name - * @param endpointVariableName - * the endpoint variable name - * @return the git hub builder - * @throws IOException - * the io exception - * @deprecated Use {@link #fromEnvironment()} to pick up standard set of environment variables, so that different - * clients of this library will all recognize one consistent set of coordinates. - */ - @Deprecated - public static GitHubBuilder fromEnvironment(String loginVariableName, - String passwordVariableName, - String oauthVariableName, - String endpointVariableName) throws IOException { - Properties env = new Properties(); - loadIfSet(loginVariableName, env, "login"); - loadIfSet(passwordVariableName, env, "password"); - loadIfSet(oauthVariableName, env, "oauth"); - loadIfSet(endpointVariableName, env, "endpoint"); - return fromProperties(env); - } - /** * Creates {@link GitHubBuilder} by picking up coordinates from environment variables. * @@ -153,7 +97,6 @@ public static GitHubBuilder fromEnvironment(String loginVariableName, * *

    *
  • GITHUB_LOGIN: username like 'kohsuke' - *
  • GITHUB_PASSWORD: raw password *
  • GITHUB_OAUTH: OAuth token to login *
  • GITHUB_ENDPOINT: URL of the API endpoint *
  • GITHUB_JWT: JWT token to login @@ -162,11 +105,7 @@ public static GitHubBuilder fromEnvironment(String loginVariableName, *

    * See class javadoc for the relationship between these coordinates. * - *

    - * For backward compatibility, the following environment variables are recognized but discouraged: login, password, - * oauth - * - * @return the git hub builder + * @return the GitHubBuilder * @throws IOException * the io exception */ @@ -182,9 +121,9 @@ public static GitHubBuilder fromEnvironment() throws IOException { } /** - * From property file git hub builder. + * From property file GitHubBuilder. * - * @return the git hub builder + * @return the GitHubBuilder * @throws IOException * the io exception */ @@ -195,11 +134,11 @@ public static GitHubBuilder fromPropertyFile() throws IOException { } /** - * From property file git hub builder. + * From property file GitHubBuilder. * * @param propertyFileName * the property file name - * @return the git hub builder + * @return the GitHubBuilder * @throws IOException * the io exception */ @@ -217,18 +156,17 @@ public static GitHubBuilder fromPropertyFile(String propertyFileName) throws IOE } /** - * From properties git hub builder. + * From properties GitHubBuilder. * * @param props * the props - * @return the git hub builder + * @return the GitHubBuilder */ public static GitHubBuilder fromProperties(Properties props) { GitHubBuilder self = new GitHubBuilder(); String oauth = props.getProperty("oauth"); String jwt = props.getProperty("jwt"); String login = props.getProperty("login"); - String password = props.getProperty("password"); if (oauth != null) { self.withOAuthToken(oauth, login); @@ -236,22 +174,19 @@ public static GitHubBuilder fromProperties(Properties props) { if (jwt != null) { self.withJwtToken(jwt); } - if (password != null) { - self.withPassword(login, password); - } self.withEndpoint(props.getProperty("endpoint", GitHubClient.GITHUB_URL)); return self; } /** - * With endpoint git hub builder. + * With endpoint GitHubBuilder. * * @param endpoint * The URL of GitHub (or GitHub enterprise) API endpoint, such as "https://api.github.com" or * "https://ghe.acme.com/api/v3". Note that GitHub Enterprise has /api/v3 in the URL. For * historical reasons, this parameter still accepts the bare domain name, but that's considered * deprecated. - * @return the git hub builder + * @return the GitHubBuilder */ public GitHubBuilder withEndpoint(String endpoint) { this.endpoint = endpoint; @@ -259,37 +194,24 @@ public GitHubBuilder withEndpoint(String endpoint) { } /** - * With password git hub builder. - * - * @param user - * the user - * @param password - * the password - * @return the git hub builder - */ - public GitHubBuilder withPassword(String user, String password) { - return withAuthorizationProvider(ImmutableAuthorizationProvider.fromLoginAndPassword(user, password)); - } - - /** - * With o auth token git hub builder. + * With o auth token GitHubBuilder. * * @param oauthToken * the oauth token - * @return the git hub builder + * @return the GitHubBuilder */ public GitHubBuilder withOAuthToken(String oauthToken) { return withAuthorizationProvider(ImmutableAuthorizationProvider.fromOauthToken(oauthToken)); } /** - * With o auth token git hub builder. + * With o auth token GitHubBuilder. * * @param oauthToken * the oauth token * @param user * the user - * @return the git hub builder + * @return the GitHubBuilder */ public GitHubBuilder withOAuthToken(String oauthToken, String user) { return withAuthorizationProvider(ImmutableAuthorizationProvider.fromOauthToken(oauthToken, user)); @@ -302,7 +224,7 @@ public GitHubBuilder withOAuthToken(String oauthToken, String user) { * * @param authorizationProvider * the authorization provider - * @return the git hub builder + * @return the GitHubBuilder * */ public GitHubBuilder withAuthorizationProvider(final AuthorizationProvider authorizationProvider) { @@ -316,73 +238,35 @@ public GitHubBuilder withAuthorizationProvider(final AuthorizationProvider autho * @param appInstallationToken * A string containing the GitHub App installation token * @return the configured Builder from given GitHub App installation token. - * @see GHAppInstallation#createToken(java.util.Map) GHAppInstallation#createToken(java.util.Map) + * @see GHAppInstallation#createToken() GHAppInstallation#createToken() */ public GitHubBuilder withAppInstallationToken(String appInstallationToken) { return withAuthorizationProvider(ImmutableAuthorizationProvider.fromAppInstallationToken(appInstallationToken)); } /** - * With jwt token git hub builder. + * With jwt token GitHubBuilder. * * @param jwtToken * the jwt token - * @return the git hub builder + * @return the GitHubBuilder */ public GitHubBuilder withJwtToken(String jwtToken) { return withAuthorizationProvider(ImmutableAuthorizationProvider.fromJwtToken(jwtToken)); } /** - * With connector git hub builder. + * With connector GitHubBuilder. * * @param connector * the connector - * @return the git hub builder - */ - @Deprecated - public GitHubBuilder withConnector(@Nonnull HttpConnector connector) { - return withConnector(GitHubConnectorHttpConnectorAdapter.adapt(connector)); - } - - /** - * With connector git hub builder. - * - * @param connector - * the connector - * @return the git hub builder + * @return the GitHubBuilder */ public GitHubBuilder withConnector(GitHubConnector connector) { this.connector = connector; return this; } - /** - * Adds a {@link RateLimitHandler} to this {@link GitHubBuilder}. - *

    - * GitHub allots a certain number of requests to each user or application per period of time (usually per hour). The - * number of requests remaining is returned in the response header and can also be requested using - * {@link GitHub#getRateLimit()}. This requests per interval is referred to as the "rate limit". - *

    - *

    - * When the remaining number of requests reaches zero, the next request will return an error. If this happens, - * {@link RateLimitHandler#onError(IOException, HttpURLConnection)} will be called. - *

    - *

    - * NOTE: GitHub treats clients that exceed their rate limit very harshly. If possible, clients should avoid - * exceeding their rate limit. Consider adding a {@link RateLimitChecker} to automatically check the rate limit for - * each request and wait if needed. - *

    - * - * @param handler - * the handler - * @return the git hub builder - * @see #withRateLimitChecker(RateLimitChecker) - */ - public GitHubBuilder withRateLimitHandler(RateLimitHandler handler) { - return withRateLimitHandler((GitHubRateLimitHandler) handler); - } - /** * Adds a {@link GitHubRateLimitHandler} to this {@link GitHubBuilder}. *

    @@ -402,7 +286,7 @@ public GitHubBuilder withRateLimitHandler(RateLimitHandler handler) { * * @param handler * the handler - * @return the git hub builder + * @return the GitHubBuilder * @see #withRateLimitChecker(RateLimitChecker) */ public GitHubBuilder withRateLimitHandler(GitHubRateLimitHandler handler) { @@ -410,23 +294,6 @@ public GitHubBuilder withRateLimitHandler(GitHubRateLimitHandler handler) { return this; } - /** - * Adds a {@link AbuseLimitHandler} to this {@link GitHubBuilder}. - *

    - * When a client sends too many requests in a short time span, GitHub may return an error and set a header telling - * the client to not make any more request for some period of time. If this happens, - * {@link AbuseLimitHandler#onError(IOException, HttpURLConnection)} will be called. - *

    - * - * @param handler - * the handler - * @return the git hub builder - */ - @Deprecated - public GitHubBuilder withAbuseLimitHandler(AbuseLimitHandler handler) { - return withAbuseLimitHandler((GitHubAbuseLimitHandler) handler); - } - /** * Adds a {@link GitHubAbuseLimitHandler} to this {@link GitHubBuilder}. *

    @@ -437,7 +304,7 @@ public GitHubBuilder withAbuseLimitHandler(AbuseLimitHandler handler) { * * @param handler * the handler - * @return the git hub builder + * @return the GitHubBuilder */ public GitHubBuilder withAbuseLimitHandler(GitHubAbuseLimitHandler handler) { this.abuseLimitHandler = handler; @@ -449,7 +316,7 @@ public GitHubBuilder withAbuseLimitHandler(GitHubAbuseLimitHandler handler) { * * @param coreRateLimitChecker * the {@link RateLimitChecker} for core GitHub API requests - * @return the git hub builder + * @return the GitHubBuilder * @see #withRateLimitChecker(RateLimitChecker, RateLimitTarget) */ public GitHubBuilder withRateLimitChecker(@Nonnull RateLimitChecker coreRateLimitChecker) { @@ -478,7 +345,7 @@ public GitHubBuilder withRateLimitChecker(@Nonnull RateLimitChecker coreRateLimi * the {@link RateLimitChecker} for requests * @param rateLimitTarget * the {@link RateLimitTarget} specifying which rate limit record to check - * @return the git hub builder + * @return the GitHubBuilder */ public GitHubBuilder withRateLimitChecker(@Nonnull RateLimitChecker rateLimitChecker, @Nonnull RateLimitTarget rateLimitTarget) { @@ -486,22 +353,10 @@ public GitHubBuilder withRateLimitChecker(@Nonnull RateLimitChecker rateLimitChe return this; } - /** - * Configures {@linkplain #withConnector(HttpConnector) connector} that uses HTTP library in JRE but use a specific - * proxy, instead of the system default one. - * - * @param p - * the p - * @return the git hub builder - */ - public GitHubBuilder withProxy(final Proxy p) { - return withConnector(new ImpatientHttpConnector(url -> (HttpURLConnection) url.openConnection(p))); - } - /** * Builds a {@link GitHub} instance. * - * @return the git hub + * @return the github * @throws IOException * the io exception */ @@ -517,7 +372,7 @@ public GitHub build() throws IOException { /** * Clone. * - * @return the git hub builder + * @return the GitHubBuilder */ @Override public GitHubBuilder clone() { diff --git a/src/main/java/org/kohsuke/github/GitHubClient.java b/src/main/java/org/kohsuke/github/GitHubClient.java index d40fcf3c1f..38552b573c 100644 --- a/src/main/java/org/kohsuke/github/GitHubClient.java +++ b/src/main/java/org/kohsuke/github/GitHubClient.java @@ -22,11 +22,15 @@ import javax.annotation.CheckForNull; import javax.annotation.Nonnull; -import javax.net.ssl.SSLHandshakeException; import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY; import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE; -import static java.net.HttpURLConnection.*; +import static java.net.HttpURLConnection.HTTP_ACCEPTED; +import static java.net.HttpURLConnection.HTTP_BAD_REQUEST; +import static java.net.HttpURLConnection.HTTP_MOVED_PERM; +import static java.net.HttpURLConnection.HTTP_MOVED_TEMP; +import static java.net.HttpURLConnection.HTTP_NOT_MODIFIED; +import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED; import static java.util.logging.Level.*; import static org.apache.commons.lang3.StringUtils.defaultString; @@ -192,35 +196,6 @@ public boolean isOffline() { return connector == GitHubConnector.OFFLINE; } - /** - * Gets connector. - * - * @return the connector - */ - @Deprecated - public HttpConnector getConnector() { - if (!(connector instanceof HttpConnector)) { - throw new UnsupportedOperationException("This GitHubConnector does not support HttpConnector.connect()."); - } - - LOGGER.warning( - "HttpConnector and getConnector() are deprecated. Please file an issue describing your use case."); - return (HttpConnector) connector; - } - - /** - * Sets the custom connector used to make requests to GitHub. - * - * @param connector - * the connector - * @deprecated HttpConnector should not be changed. - */ - @Deprecated - public void setConnector(GitHubConnector connector) { - LOGGER.warning("Connector should not be changed. Please file an issue describing your use case."); - this.connector = connector; - } - /** * Is this an anonymous connection. * @@ -469,13 +444,6 @@ public GitHubResponse sendRequest(GitHubRequest request, @CheckForNull Bo if (retries > 0 && e.connectorRequest != null) { connectorRequest = e.connectorRequest; } - } catch (SocketException | SocketTimeoutException | SSLHandshakeException e) { - // These transient errors thrown by HttpURLConnection - if (retries > 0) { - logRetryConnectionError(e, connectorRequest.url(), retries); - continue; - } - throw interpretApiError(e, connectorRequest, connectorResponse); } catch (IOException e) { throw interpretApiError(e, connectorRequest, connectorResponse); } finally { @@ -685,10 +653,10 @@ private static GitHubResponse createResponse(@Nonnull GitHubConnectorResp } private static boolean shouldIgnoreBody(@Nonnull GitHubConnectorResponse connectorResponse) { - if (connectorResponse.statusCode() == HttpURLConnection.HTTP_NOT_MODIFIED) { + if (connectorResponse.statusCode() == HTTP_NOT_MODIFIED) { // special case handling for 304 unmodified, as the content will be "" return true; - } else if (connectorResponse.statusCode() == HttpURLConnection.HTTP_ACCEPTED) { + } else if (connectorResponse.statusCode() == HTTP_ACCEPTED) { // Response code 202 means data is being generated or an action that can require some time is triggered. // This happens in specific cases: diff --git a/src/main/java/org/kohsuke/github/GitHubInteractiveObject.java b/src/main/java/org/kohsuke/github/GitHubInteractiveObject.java index 036b53f7c1..274640bef4 100644 --- a/src/main/java/org/kohsuke/github/GitHubInteractiveObject.java +++ b/src/main/java/org/kohsuke/github/GitHubInteractiveObject.java @@ -3,7 +3,6 @@ import com.fasterxml.jackson.annotation.JacksonInject; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.Objects; @@ -39,19 +38,6 @@ abstract class GitHubInteractiveObject { this.root = root; } - /** - * Get the root {@link GitHub} instance for this object. - * - * @return the root {@link GitHub} instance - * - * @deprecated For access to the {@link GitHub} instance, use a local copy instead of pulling it out of objects. - */ - @Deprecated - @SuppressFBWarnings(value = { "EI_EXPOSE_REP" }, justification = "Expected behavior") - public GitHub getRoot() { - return root(); - } - /** * Get the root {@link GitHub} instance for this object. * diff --git a/src/main/java/org/kohsuke/github/GitHubRateLimitHandler.java b/src/main/java/org/kohsuke/github/GitHubRateLimitHandler.java index da4f6ad104..24ea47f5f4 100644 --- a/src/main/java/org/kohsuke/github/GitHubRateLimitHandler.java +++ b/src/main/java/org/kohsuke/github/GitHubRateLimitHandler.java @@ -4,10 +4,12 @@ import org.kohsuke.github.connector.GitHubConnectorResponse; import java.io.IOException; -import java.net.HttpURLConnection; +import java.io.InterruptedIOException; import javax.annotation.Nonnull; +import static java.net.HttpURLConnection.HTTP_FORBIDDEN; + // TODO: Auto-generated Javadoc /** * Pluggable strategy to determine what to do when the API rate limit is reached. @@ -30,7 +32,7 @@ public abstract class GitHubRateLimitHandler extends GitHubConnectorResponseErro */ @Override boolean isError(@NotNull GitHubConnectorResponse connectorResponse) throws IOException { - return connectorResponse.statusCode() == HttpURLConnection.HTTP_FORBIDDEN + return connectorResponse.statusCode() == HTTP_FORBIDDEN && "0".equals(connectorResponse.header("X-RateLimit-Remaining")); } @@ -50,4 +52,42 @@ boolean isError(@NotNull GitHubConnectorResponse connectorResponse) throws IOExc * @see API documentation from GitHub */ public abstract void onError(@Nonnull GitHubConnectorResponse connectorResponse) throws IOException; + + /** + * Wait until the API abuse "wait time" is passed. + */ + public static final GitHubRateLimitHandler WAIT = new GitHubRateLimitHandler() { + @Override + public void onError(GitHubConnectorResponse connectorResponse) throws IOException { + try { + Thread.sleep(parseWaitTime(connectorResponse)); + } catch (InterruptedException ex) { + throw (InterruptedIOException) new InterruptedIOException().initCause(ex); + } + } + + private long parseWaitTime(GitHubConnectorResponse connectorResponse) { + String v = connectorResponse.header("X-RateLimit-Reset"); + if (v == null) + return 60 * 1000; // can't tell, return 1 min + + return Math.max(1000, Long.parseLong(v) * 1000 - System.currentTimeMillis()); + } + }; + + /** + * Fail immediately. + */ + public static final GitHubRateLimitHandler FAIL = new GitHubRateLimitHandler() { + @Override + public void onError(GitHubConnectorResponse connectorResponse) throws IOException { + throw new HttpException("API rate limit reached", + connectorResponse.statusCode(), + connectorResponse.header("Status"), + connectorResponse.request().url().toString()) + .withResponseHeaderFields(connectorResponse.allHeaders()); + + } + }; + } diff --git a/src/main/java/org/kohsuke/github/GitHubRequest.java b/src/main/java/org/kohsuke/github/GitHubRequest.java index 75b2286504..2bb4a459a8 100644 --- a/src/main/java/org/kohsuke/github/GitHubRequest.java +++ b/src/main/java/org/kohsuke/github/GitHubRequest.java @@ -5,7 +5,6 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.kohsuke.github.connector.GitHubConnectorRequest; -import org.kohsuke.github.internal.Previews; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -111,7 +110,7 @@ static URL getApiURL(String apiUrl, String tailApiUrl) { // backward compatibility apiUrl = GitHubClient.GITHUB_URL; } - return new URL(apiUrl + tailApiUrl); + return new URI(apiUrl + tailApiUrl).toURL(); } catch (Exception e) { // The data going into constructing this URL should be controlled by the GitHub API framework, // so a malformed URL here is a framework runtime error. @@ -507,32 +506,8 @@ public B injectMappingValue(@NonNull String name, Object value) { * the name * @return the b */ - @Deprecated - public B withPreview(String name) { - return withHeader("Accept", name); - } - - /** - * With preview. - * - * @param preview - * the preview - * @return the b - */ - @Deprecated - public B withPreview(Previews preview) { - return withPreview(preview.mediaType()); - } - - /** - * With accept header. - * - * @param name - * the name - * @return the b - */ public B withAccept(String name) { - return withPreview(name); + return withHeader("Accept", name); } /** diff --git a/src/main/java/org/kohsuke/github/GitHubResponse.java b/src/main/java/org/kohsuke/github/GitHubResponse.java index 3ec2e2b9fa..fc8cb02f28 100644 --- a/src/main/java/org/kohsuke/github/GitHubResponse.java +++ b/src/main/java/org/kohsuke/github/GitHubResponse.java @@ -10,7 +10,6 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.Array; -import java.net.HttpURLConnection; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.logging.Level; @@ -19,6 +18,8 @@ import javax.annotation.CheckForNull; import javax.annotation.Nonnull; +import static java.net.HttpURLConnection.HTTP_NO_CONTENT; + // TODO: Auto-generated Javadoc /** * A GitHubResponse @@ -86,7 +87,7 @@ class GitHubResponse { @CheckForNull static T parseBody(GitHubConnectorResponse connectorResponse, Class type) throws IOException { - if (connectorResponse.statusCode() == HttpURLConnection.HTTP_NO_CONTENT) { + if (connectorResponse.statusCode() == HTTP_NO_CONTENT) { if (type != null && type.isArray()) { // no content for array should be empty array return type.cast(Array.newInstance(type.getComponentType(), 0)); diff --git a/src/main/java/org/kohsuke/github/GitUser.java b/src/main/java/org/kohsuke/github/GitUser.java index 434cc92877..d906bc519a 100644 --- a/src/main/java/org/kohsuke/github/GitUser.java +++ b/src/main/java/org/kohsuke/github/GitUser.java @@ -63,18 +63,4 @@ public Date getDate() { public GitUser() { // Empty constructor for Jackson binding } - - /** - * Instantiates a new git user. - * - * @param user - * the user - */ - public GitUser(GitUser user) { - // Copy constructor to convert to GHCommit.GHAuthor - name = user.getName(); - email = user.getEmail(); - date = user.getDate().toString(); - username = user.getUsername(); - } } diff --git a/src/main/java/org/kohsuke/github/HttpConnector.java b/src/main/java/org/kohsuke/github/HttpConnector.java deleted file mode 100644 index af4fc81536..0000000000 --- a/src/main/java/org/kohsuke/github/HttpConnector.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.kohsuke.github; - -import org.kohsuke.github.extras.ImpatientHttpConnector; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URL; - -// TODO: Auto-generated Javadoc -/** - * Pluggability for customizing HTTP request behaviors or using altogether different library. - * - *

    - * For example, you can implement this to st custom timeouts. - * - * @author Kohsuke Kawaguchi - * @deprecated Use {@link org.kohsuke.github.connector.GitHubConnector} instead. - */ -@FunctionalInterface -@Deprecated -public interface HttpConnector { - /** - * Opens a connection to the given URL. - * - * @param url - * the url - * @return the http url connection - * @throws IOException - * the io exception - */ - HttpURLConnection connect(URL url) throws IOException; - - /** - * Default implementation that uses {@link URL#openConnection()}. - */ - HttpConnector DEFAULT = new ImpatientHttpConnector(url -> (HttpURLConnection) url.openConnection()); - - /** - * Stub implementation that is always off-line. - */ - HttpConnector OFFLINE = url -> { - throw new IOException("Offline"); - }; -} diff --git a/src/main/java/org/kohsuke/github/PagedIterable.java b/src/main/java/org/kohsuke/github/PagedIterable.java index fc3528492e..a92d0ef693 100644 --- a/src/main/java/org/kohsuke/github/PagedIterable.java +++ b/src/main/java/org/kohsuke/github/PagedIterable.java @@ -131,38 +131,6 @@ public Set toSet() throws IOException { return Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(this.toArray()))); } - /** - * Eagerly walk {@link Iterable} and return the result in a list. - * - * @return the list - * @deprecated Use {@link #toList()} instead. - */ - @Nonnull - @Deprecated - public List asList() { - try { - return this.toList(); - } catch (IOException e) { - throw new GHException("Failed to retrieve list: " + e.getMessage(), e); - } - } - - /** - * Eagerly walk {@link Iterable} and return the result in a set. - * - * @return the set - * @deprecated Use {@link #toSet()} instead. - */ - @Nonnull - @Deprecated - public Set asSet() { - try { - return this.toSet(); - } catch (IOException e) { - throw new GHException("Failed to retrieve list: " + e.getMessage(), e); - } - } - /** * Concatenates a list of arrays into a single array. * diff --git a/src/main/java/org/kohsuke/github/Preview.java b/src/main/java/org/kohsuke/github/Preview.java deleted file mode 100644 index 8e23022e15..0000000000 --- a/src/main/java/org/kohsuke/github/Preview.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.kohsuke.github; - -import org.kohsuke.github.internal.Previews; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -// TODO: Auto-generated Javadoc -/** - * Indicates that the method/class/etc marked maps to GitHub API in the preview period. - *

    - * These APIs are subject to change and not a part of the backward compatibility commitment. - * - * It is advised to update the target's documentation with text indicating that a preview feature being used. - * - * @author Kohsuke Kawaguchi - */ -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface Preview { - - /** - * An optional field defining what API media types must be set inorder to support the usage of this annotations - * target. - *

    - * This value must be set using the existing constants defined in {@link Previews} - * - * @return The API preview media type. - */ - public Previews[] value(); - -} diff --git a/src/main/java/org/kohsuke/github/RateLimitHandler.java b/src/main/java/org/kohsuke/github/RateLimitHandler.java deleted file mode 100644 index a17e9a33b3..0000000000 --- a/src/main/java/org/kohsuke/github/RateLimitHandler.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.kohsuke.github; - -import org.kohsuke.github.connector.GitHubConnectorResponse; - -import java.io.IOException; -import java.io.InterruptedIOException; -import java.net.HttpURLConnection; - -import javax.annotation.Nonnull; - -// TODO: Auto-generated Javadoc -/** - * Pluggable strategy to determine what to do when the API rate limit is reached. - * - * @author Kohsuke Kawaguchi - * @see GitHubBuilder#withRateLimitHandler(GitHubRateLimitHandler) - * GitHubBuilder#withRateLimitHandler(GitHubRateLimitHandler) - * @see AbuseLimitHandler - * @deprecated Switch to {@link GitHubRateLimitHandler} or even better provide {@link RateLimitChecker}s. - */ -@Deprecated -public abstract class RateLimitHandler extends GitHubRateLimitHandler { - - /** - * Called when the library encounters HTTP error indicating that the API rate limit has been exceeded. - * - *

    - * Any exception thrown from this method will cause the request to fail, and the caller of github-api will receive - * an exception. If this method returns normally, another request will be attempted. For that to make sense, the - * implementation needs to wait for some time. - * - * @param connectorResponse - * Response information for this request. - * - * @throws IOException - * the io exception - * @see API documentation from GitHub - */ - public void onError(@Nonnull GitHubConnectorResponse connectorResponse) throws IOException { - GHIOException e = new HttpException("API rate limit reached", - connectorResponse.statusCode(), - connectorResponse.header("Status"), - connectorResponse.request().url().toString()).withResponseHeaderFields(connectorResponse.allHeaders()); - onError(e, connectorResponse.toHttpURLConnection()); - } - - /** - * Called when the library encounters HTTP error indicating that the API rate limit is reached. - * - *

    - * Any exception thrown from this method will cause the request to fail, and the caller of github-api will receive - * an exception. If this method returns normally, another request will be attempted. For that to make sense, the - * implementation needs to wait for some time. - * - * @param e - * Exception from Java I/O layer. If you decide to fail the processing, you can throw this exception (or - * wrap this exception into another exception and throw it.) - * @param uc - * Connection that resulted in an error. Useful for accessing other response headers. - * @throws IOException - * the io exception - * @see API documentation from GitHub - */ - @Deprecated - public abstract void onError(IOException e, HttpURLConnection uc) throws IOException; - - /** - * Block until the API rate limit is reset. Useful for long-running batch processing. - */ - @Deprecated - public static final RateLimitHandler WAIT = new RateLimitHandler() { - @Override - public void onError(IOException e, HttpURLConnection uc) throws IOException { - try { - Thread.sleep(parseWaitTime(uc)); - } catch (InterruptedException x) { - throw (InterruptedIOException) new InterruptedIOException().initCause(e); - } - } - - private long parseWaitTime(HttpURLConnection uc) { - String v = uc.getHeaderField("X-RateLimit-Reset"); - if (v == null) - return 10000; // can't tell - - return Math.max(10000, Long.parseLong(v) * 1000 - System.currentTimeMillis()); - } - }; - - /** - * Fail immediately. - */ - @Deprecated - public static final RateLimitHandler FAIL = new RateLimitHandler() { - @Override - public void onError(IOException e, HttpURLConnection uc) throws IOException { - throw e; - } - }; -} diff --git a/src/main/java/org/kohsuke/github/authorization/ImmutableAuthorizationProvider.java b/src/main/java/org/kohsuke/github/authorization/ImmutableAuthorizationProvider.java index ebab1bcaef..09ee6ae467 100644 --- a/src/main/java/org/kohsuke/github/authorization/ImmutableAuthorizationProvider.java +++ b/src/main/java/org/kohsuke/github/authorization/ImmutableAuthorizationProvider.java @@ -1,9 +1,5 @@ package org.kohsuke.github.authorization; -import java.io.UnsupportedEncodingException; -import java.nio.charset.StandardCharsets; -import java.util.Base64; - import javax.annotation.CheckForNull; /** @@ -72,31 +68,6 @@ public static AuthorizationProvider fromJwtToken(String jwtToken) { return new ImmutableAuthorizationProvider(String.format("Bearer %s", jwtToken)); } - /** - * Builds and returns a {@link AuthorizationProvider} from the given user/password pair - * - * @param login - * The login for the user, usually the same as the username - * @param password - * The password for the associated user - * @return a correctly configured {@link AuthorizationProvider} that will always return the credentials for the same - * user and password combo - * @deprecated Login with password credentials are no longer supported by GitHub - */ - @Deprecated - public static AuthorizationProvider fromLoginAndPassword(String login, String password) { - try { - String authorization = (String.format("%s:%s", login, password)); - String charsetName = StandardCharsets.UTF_8.name(); - String b64encoded = Base64.getEncoder().encodeToString(authorization.getBytes(charsetName)); - String encodedAuthorization = String.format("Basic %s", b64encoded); - return new UserProvider(encodedAuthorization, login); - } catch (UnsupportedEncodingException e) { - // If UTF-8 isn't supported, there are bigger problems - throw new IllegalStateException("Could not generate encoded authorization", e); - } - } - @Override public String getEncodedAuthorization() { return this.authorization; diff --git a/src/main/java/org/kohsuke/github/connector/GitHubConnector.java b/src/main/java/org/kohsuke/github/connector/GitHubConnector.java index 63ffe9892d..1e929df0e8 100644 --- a/src/main/java/org/kohsuke/github/connector/GitHubConnector.java +++ b/src/main/java/org/kohsuke/github/connector/GitHubConnector.java @@ -1,8 +1,7 @@ package org.kohsuke.github.connector; -import org.kohsuke.github.HttpConnector; +import org.kohsuke.github.GHIOException; import org.kohsuke.github.internal.DefaultGitHubConnector; -import org.kohsuke.github.internal.GitHubConnectorHttpConnectorAdapter; import java.io.IOException; @@ -47,9 +46,11 @@ public interface GitHubConnector { /** * Stub implementation that is always off-line. - * - * This connector currently uses {@link GitHubConnectorHttpConnectorAdapter} to maintain backward compatibility as - * much as possible. */ - GitHubConnector OFFLINE = new GitHubConnectorHttpConnectorAdapter(HttpConnector.OFFLINE); + GitHubConnector OFFLINE = new GitHubConnector() { + @Override + public GitHubConnectorResponse send(GitHubConnectorRequest connectorRequest) throws IOException { + throw new GHIOException("Offline"); + } + }; } diff --git a/src/main/java/org/kohsuke/github/connector/GitHubConnectorResponse.java b/src/main/java/org/kohsuke/github/connector/GitHubConnectorResponse.java index 2b1b5a701c..b71fc8abc5 100644 --- a/src/main/java/org/kohsuke/github/connector/GitHubConnectorResponse.java +++ b/src/main/java/org/kohsuke/github/connector/GitHubConnectorResponse.java @@ -7,7 +7,6 @@ import java.io.Closeable; import java.io.IOException; import java.io.InputStream; -import java.net.HttpURLConnection; import java.util.*; import java.util.zip.GZIPInputStream; @@ -61,20 +60,6 @@ protected GitHubConnectorResponse(@Nonnull GitHubConnectorRequest request, this.headers = Collections.unmodifiableMap(caseInsensitiveMap); } - /** - * Get this response as a {@link HttpURLConnection}. - * - * @return an object that implements at least the response related methods of {@link HttpURLConnection}. - * @deprecated This method is present only to provide backward compatibility with other deprecated components. - */ - @Deprecated - @Nonnull - public HttpURLConnection toHttpURLConnection() { - HttpURLConnection connection; - connection = new GitHubConnectorResponseHttpUrlConnectionAdapter(this); - return connection; - } - /** * Gets the value of a header field for this response. * diff --git a/src/main/java/org/kohsuke/github/connector/GitHubConnectorResponseHttpUrlConnectionAdapter.java b/src/main/java/org/kohsuke/github/connector/GitHubConnectorResponseHttpUrlConnectionAdapter.java deleted file mode 100644 index 30ae888b90..0000000000 --- a/src/main/java/org/kohsuke/github/connector/GitHubConnectorResponseHttpUrlConnectionAdapter.java +++ /dev/null @@ -1,265 +0,0 @@ -package org.kohsuke.github.connector; - -import org.kohsuke.github.HttpException; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.security.Permission; -import java.util.*; - -/** - * Adapter class for {@link org.kohsuke.github.connector.GitHubConnectorResponse} to be usable as a - * {@link HttpURLConnection}. - * - * Behavior is equivalent to a {@link HttpURLConnection} after {@link HttpURLConnection#connect()} has been called. - * Methods that make no sense throw {@link UnsupportedOperationException}. - * - * @author Liam Newman - */ -@Deprecated -class GitHubConnectorResponseHttpUrlConnectionAdapter extends HttpURLConnection { - - private final GitHubConnectorResponse connectorResponse; - - public GitHubConnectorResponseHttpUrlConnectionAdapter(GitHubConnectorResponse connectorResponse) { - super(connectorResponse.request().url()); - this.connected = true; - this.connectorResponse = connectorResponse; - } - - @Override - public String getHeaderFieldKey(int n) { - List keys = new ArrayList<>(connectorResponse.allHeaders().keySet()); - return keys.get(n); - } - - @Override - public String getHeaderField(int n) { - return connectorResponse.header(getHeaderFieldKey(n)); - } - - @Override - public void setInstanceFollowRedirects(boolean followRedirects) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean getInstanceFollowRedirects() { - throw new UnsupportedOperationException(); - } - - @Override - public String getRequestMethod() { - return connectorResponse.request().method(); - } - - @Override - public int getResponseCode() throws IOException { - return connectorResponse.statusCode(); - } - - @Override - public String getResponseMessage() throws IOException { - return connectorResponse.header("Status"); - } - - @Override - public long getHeaderFieldDate(String name, long defaultValue) { - String dateString = getHeaderField(name); - try { - return Date.parse(dateString); - } catch (Exception e) { - } - return defaultValue; - } - - @Override - public Permission getPermission() throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public InputStream getErrorStream() { - try { - if (connectorResponse.statusCode() >= HTTP_BAD_REQUEST) { - return connectorResponse.bodyStream(); - } - } catch (IOException e) { - } - return null; - } - - @Override - public void setConnectTimeout(int timeout) { - throw new UnsupportedOperationException(); - } - - @Override - public int getConnectTimeout() { - throw new UnsupportedOperationException(); - } - - @Override - public void setReadTimeout(int timeout) { - throw new UnsupportedOperationException(); - } - - @Override - public int getReadTimeout() { - throw new UnsupportedOperationException(); - } - - @Override - public int getContentLength() { - long l = getContentLengthLong(); - if (l > Integer.MAX_VALUE) - return -1; - return (int) l; - } - - @Override - public long getContentLengthLong() { - return getHeaderFieldLong("content-length", -1); - } - - @Override - public String getContentType() { - return connectorResponse.header("content-type"); - } - - @Override - public String getContentEncoding() { - return connectorResponse.header("content-encoding"); - } - - @Override - public long getExpiration() { - return getHeaderFieldDate("expires", 0); - } - - @Override - public long getDate() { - return getHeaderFieldDate("date", 0); - } - - @Override - public long getLastModified() { - return getHeaderFieldDate("last-modified", 0); - } - - @Override - public String getHeaderField(String name) { - return connectorResponse.header(name); - } - - @Override - public Map> getHeaderFields() { - return connectorResponse.allHeaders(); - } - - @Override - public int getHeaderFieldInt(String name, int defaultValue) { - String value = getHeaderField(name); - try { - return Integer.parseInt(value); - } catch (Exception e) { - } - return defaultValue; - } - - @Override - public long getHeaderFieldLong(String name, long defaultValue) { - String value = getHeaderField(name); - try { - return Long.parseLong(value); - } catch (Exception e) { - } - return defaultValue; - } - - @Override - public Object getContent() throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public Object getContent(Class[] classes) throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public InputStream getInputStream() throws IOException { - // This should only be possible in abuse or rate limit scenario - if (connectorResponse.statusCode() >= HTTP_BAD_REQUEST) { - throw new HttpException(connectorResponse); - } - return connectorResponse.bodyStream(); - } - - @Override - public OutputStream getOutputStream() throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public String toString() { - return this.getClass().getName() + ": " + connectorResponse.toString(); - } - - @Override - public boolean getDoInput() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean getDoOutput() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean getUseCaches() { - throw new UnsupportedOperationException(); - } - - @Override - public long getIfModifiedSince() { - return getHeaderFieldDate("If-Modified-Since", 0); - } - - @Override - public void setDefaultUseCaches(boolean defaultusecaches) { - throw new UnsupportedOperationException(); - } - - @Override - public String getRequestProperty(String key) { - return connectorResponse.request().header(key); - } - - @Override - public boolean getAllowUserInteraction() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean getDefaultUseCaches() { - throw new UnsupportedOperationException(); - } - - @Override - public void disconnect() { - // ignored - } - - @Override - public boolean usingProxy() { - throw new UnsupportedOperationException(); - } - - @Override - public void connect() throws IOException { - // no op - } -} diff --git a/src/main/java/org/kohsuke/github/extras/HttpClientGitHubConnector.java b/src/main/java/org/kohsuke/github/extras/HttpClientGitHubConnector.java index 21c943fa58..52f7e610d7 100644 --- a/src/main/java/org/kohsuke/github/extras/HttpClientGitHubConnector.java +++ b/src/main/java/org/kohsuke/github/extras/HttpClientGitHubConnector.java @@ -1,29 +1,119 @@ package org.kohsuke.github.extras; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import org.apache.commons.io.IOUtils; import org.kohsuke.github.connector.GitHubConnector; import org.kohsuke.github.connector.GitHubConnectorRequest; import org.kohsuke.github.connector.GitHubConnectorResponse; import java.io.IOException; +import java.io.InputStream; +import java.io.InterruptedIOException; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.List; +import java.util.Map; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; /** - * {@link GitHubConnector} for platforms that do not support Java 11 HttpClient. + * {@link GitHubConnector} for {@link HttpClient}. * * @author Liam Newman */ @SuppressFBWarnings(value = { "CT_CONSTRUCTOR_THROW" }, justification = "Basic validation") public class HttpClientGitHubConnector implements GitHubConnector { + private final HttpClient client; + /** - * Instantiates a new Impatient http connector. + * Instantiates a new HttpClientGitHubConnector with a default HttpClient. */ public HttpClientGitHubConnector() { - throw new UnsupportedOperationException("java.net.http.HttpClient is only supported in Java 11+."); + // GitHubClient handles redirects manually as Java HttpClient copies all the headers when redirecting + // even when redirecting to a different host which is problematic as we don't want + // to push the Authorization header when redirected to a different host. + // This problem was discovered when upload-artifact@v4 was released as the new + // service we are redirected to for downloading the artifacts doesn't support + // having the Authorization header set. + // The new implementation does not push the Authorization header when redirected + // to a different host, which is similar to what Okhttp is doing: + // https://github.com/square/okhttp/blob/f9dfd4e8cc070ca2875a67d8f7ad939d95e7e296/okhttp/src/main/kotlin/okhttp3/internal/http/RetryAndFollowUpInterceptor.kt#L313-L318 + // See also https://github.com/arduino/report-size-deltas/pull/83 for more context + this(HttpClient.newBuilder().followRedirects(HttpClient.Redirect.NEVER).build()); + } + + /** + * Instantiates a new HttpClientGitHubConnector. + * + * @param client + * the HttpClient to be used + */ + public HttpClientGitHubConnector(HttpClient client) { + this.client = client; } @Override public GitHubConnectorResponse send(GitHubConnectorRequest connectorRequest) throws IOException { - throw new UnsupportedOperationException("java.net.http.HttpClient is only supported in Java 11+."); + HttpRequest.Builder builder = HttpRequest.newBuilder(); + try { + builder.uri(connectorRequest.url().toURI()); + } catch (URISyntaxException e) { + throw new IOException("Invalid URL", e); + } + + for (Map.Entry> e : connectorRequest.allHeaders().entrySet()) { + List v = e.getValue(); + if (v != null) { + builder.header(e.getKey(), String.join(", ", v)); + } + } + + HttpRequest.BodyPublisher publisher = HttpRequest.BodyPublishers.noBody(); + if (connectorRequest.hasBody()) { + publisher = HttpRequest.BodyPublishers.ofByteArray(IOUtils.toByteArray(connectorRequest.body())); + } + builder.method(connectorRequest.method(), publisher); + + HttpRequest request = builder.build(); + + try { + HttpResponse httpResponse = client.send(request, HttpResponse.BodyHandlers.ofInputStream()); + return new HttpClientGitHubConnectorResponse(connectorRequest, httpResponse); + } catch (InterruptedException e) { + throw (InterruptedIOException) new InterruptedIOException(e.getMessage()).initCause(e); + } + } + + /** + * Initial response information when a response is initially received and before the body is processed. + * + * Implementation specific to {@link HttpResponse}. + */ + private static class HttpClientGitHubConnectorResponse extends GitHubConnectorResponse.ByteArrayResponse { + + @Nonnull + private final HttpResponse response; + + protected HttpClientGitHubConnectorResponse(@Nonnull GitHubConnectorRequest request, + @Nonnull HttpResponse response) { + super(request, response.statusCode(), response.headers().map()); + this.response = response; + } + + @CheckForNull + @Override + protected InputStream rawBodyStream() throws IOException { + return response.body(); + } + + @Override + public void close() throws IOException { + super.close(); + IOUtils.closeQuietly(response.body()); + } } } diff --git a/src/main/java/org/kohsuke/github/extras/ImpatientHttpConnector.java b/src/main/java/org/kohsuke/github/extras/ImpatientHttpConnector.java deleted file mode 100644 index c02d75bdf1..0000000000 --- a/src/main/java/org/kohsuke/github/extras/ImpatientHttpConnector.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.kohsuke.github.extras; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import org.kohsuke.github.HttpConnector; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.concurrent.TimeUnit; - -/** - * {@link HttpConnector} wrapper that sets timeout - * - * @author Kohsuke Kawaguchi - */ -public class ImpatientHttpConnector implements HttpConnector { - private final HttpConnector base; - private final int readTimeout, connectTimeout; - - /** - * Instantiates a new Impatient http connector. - * - * @param base - * the base - * @param connectTimeout - * HTTP connection timeout in milliseconds - * @param readTimeout - * HTTP read timeout in milliseconds - */ - public ImpatientHttpConnector(HttpConnector base, int connectTimeout, int readTimeout) { - this.base = base; - this.connectTimeout = connectTimeout; - this.readTimeout = readTimeout; - } - - /** - * Instantiates a new Impatient http connector. - * - * @param base - * the base - * @param timeout - * the timeout - */ - public ImpatientHttpConnector(HttpConnector base, int timeout) { - this(base, timeout, timeout); - } - - /** - * Instantiates a new Impatient http connector. - * - * @param base - * the base - */ - public ImpatientHttpConnector(HttpConnector base) { - this(base, CONNECT_TIMEOUT, READ_TIMEOUT); - } - - public HttpURLConnection connect(URL url) throws IOException { - HttpURLConnection con = base.connect(url); - con.setConnectTimeout(connectTimeout); - con.setReadTimeout(readTimeout); - return con; - } - - /** - * Default connection timeout in milliseconds - */ - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static int CONNECT_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(10); - - /** - * Default read timeout in milliseconds - */ - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") - public static int READ_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(10); -} diff --git a/src/main/java/org/kohsuke/github/extras/OkHttp3Connector.java b/src/main/java/org/kohsuke/github/extras/OkHttp3Connector.java deleted file mode 100644 index 24819a7a4c..0000000000 --- a/src/main/java/org/kohsuke/github/extras/OkHttp3Connector.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.kohsuke.github.extras; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import okhttp3.OkHttpClient; -import okhttp3.OkUrlFactory; -import org.kohsuke.github.HttpConnector; -import org.kohsuke.github.extras.okhttp3.OkHttpGitHubConnector; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URL; - -/** - * {@link HttpConnector} for {@link OkHttpClient}. - *

    - * Unlike {@link #DEFAULT}, OkHttp does response caching. Making a conditional request against GitHubAPI and receiving a - * 304 response does not count against the rate limit. See http://developer.github.com/v3/#conditional-requests - * - * @author Roberto Tyley - * @author Kohsuke Kawaguchi - * @see OkHttpGitHubConnector - */ -@Deprecated -@SuppressFBWarnings(value = { "EI_EXPOSE_REP2" }, justification = "Deprecated") -public class OkHttp3Connector implements HttpConnector { - private final OkUrlFactory urlFactory; - - /** - * Instantiates a new Ok http 3 connector. - * - * @param urlFactory - * the url factory - */ - /* - * @see org.kohsuke.github.extras.okhttp3.OkHttpGitHubConnector - */ - @Deprecated - public OkHttp3Connector(OkUrlFactory urlFactory) { - this.urlFactory = urlFactory; - } - - public HttpURLConnection connect(URL url) throws IOException { - return urlFactory.open(url); - } -} diff --git a/src/main/java/org/kohsuke/github/extras/OkHttpConnector.java b/src/main/java/org/kohsuke/github/extras/OkHttpConnector.java deleted file mode 100644 index 27a1731d65..0000000000 --- a/src/main/java/org/kohsuke/github/extras/OkHttpConnector.java +++ /dev/null @@ -1,105 +0,0 @@ -package org.kohsuke.github.extras; - -import com.squareup.okhttp.CacheControl; -import com.squareup.okhttp.ConnectionSpec; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.OkUrlFactory; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import org.kohsuke.github.HttpConnector; -import org.kohsuke.github.extras.okhttp3.OkHttpGitHubConnector; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URL; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocketFactory; - -/** - * {@link HttpConnector} for {@link OkHttpClient}. - *

    - * Unlike {@link #DEFAULT}, OkHttp does response caching. Making a conditional request against GitHubAPI and receiving a - * 304 response does not count against the rate limit. See http://developer.github.com/v3/#conditional-requests - * - * @author Roberto Tyley - * @author Kohsuke Kawaguchi - * @deprecated This class depends on an unsupported version of OkHttp. Switch to {@link OkHttpGitHubConnector}. - * @see OkHttpGitHubConnector - */ -@Deprecated -@SuppressFBWarnings(value = { "CT_CONSTRUCTOR_THROW" }, justification = "Deprecated") -public class OkHttpConnector implements HttpConnector { - private static final String HEADER_NAME = "Cache-Control"; - private final OkUrlFactory urlFactory; - - private final String maxAgeHeaderValue; - - /** - * Instantiates a new Ok http connector. - * - * @param urlFactory - * the url factory - */ - public OkHttpConnector(OkUrlFactory urlFactory) { - this(urlFactory, 0); - } - - /** - * package private for tests to be able to change max-age for cache. - * - * @param urlFactory - * @param cacheMaxAge - */ - OkHttpConnector(OkUrlFactory urlFactory, int cacheMaxAge) { - urlFactory.client().setSslSocketFactory(TlsSocketFactory()); - urlFactory.client().setConnectionSpecs(TlsConnectionSpecs()); - this.urlFactory = urlFactory; - - if (cacheMaxAge >= 0 && urlFactory.client() != null && urlFactory.client().getCache() != null) { - maxAgeHeaderValue = new CacheControl.Builder().maxAge(cacheMaxAge, TimeUnit.SECONDS).build().toString(); - } else { - maxAgeHeaderValue = null; - } - } - - public HttpURLConnection connect(URL url) throws IOException { - HttpURLConnection urlConnection = urlFactory.open(url); - if (maxAgeHeaderValue != null) { - // By default OkHttp honors max-age, meaning it will use local cache - // without checking the network within that time frame. - // However, that can result in stale data being returned during that time so - // we force network-based checking no matter how often the query is made. - // OkHttp still automatically does ETag checking and returns cached data when - // GitHub reports 304, but those do not count against rate limit. - urlConnection.setRequestProperty(HEADER_NAME, maxAgeHeaderValue); - } - - return urlConnection; - } - - /** Returns TLSv1.2 only SSL Socket Factory. */ - private SSLSocketFactory TlsSocketFactory() { - SSLContext sc; - try { - sc = SSLContext.getInstance("TLSv1.2"); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e.getMessage(), e); - } - try { - sc.init(null, null, null); - return sc.getSocketFactory(); - } catch (KeyManagementException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - - /** Returns connection spec with TLS v1.2 in it */ - private List TlsConnectionSpecs() { - return Arrays.asList(ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT); - } -} diff --git a/src/main/java/org/kohsuke/github/extras/okhttp3/ObsoleteUrlFactory.java b/src/main/java/org/kohsuke/github/extras/okhttp3/ObsoleteUrlFactory.java deleted file mode 100644 index dbbbae6a6c..0000000000 --- a/src/main/java/org/kohsuke/github/extras/okhttp3/ObsoleteUrlFactory.java +++ /dev/null @@ -1,1439 +0,0 @@ -package org.kohsuke.github.extras.okhttp3; - -/* - * Copyright (C) 2014 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import okhttp3.Call; -import okhttp3.Callback; -import okhttp3.Dispatcher; -import okhttp3.Handshake; -import okhttp3.Headers; -import okhttp3.HttpUrl; -import okhttp3.Interceptor; -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Protocol; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; -import okhttp3.ResponseBody; -import okio.Buffer; -import okio.BufferedSink; -import okio.Okio; -import okio.Pipe; -import okio.Timeout; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InterruptedIOException; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.InetSocketAddress; -import java.net.MalformedURLException; -import java.net.ProtocolException; -import java.net.Proxy; -import java.net.SocketPermission; -import java.net.SocketTimeoutException; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLStreamHandler; -import java.net.URLStreamHandlerFactory; -import java.security.Permission; -import java.security.Principal; -import java.security.cert.Certificate; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.concurrent.TimeUnit; - -import javax.annotation.Nullable; -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLSocketFactory; - -import static java.net.HttpURLConnection.HTTP_NOT_MODIFIED; -import static java.net.HttpURLConnection.HTTP_NO_CONTENT; - -/** - * OkHttp 3.14 dropped support for the long-deprecated OkUrlFactory class, which allows you to use the HttpURLConnection - * API with OkHttp's implementation. This class does the same thing using only public APIs in OkHttp. It requires OkHttp - * 3.14 or newer. - * - *

    - * Rather than pasting this 1100 line gist into your source code, please upgrade to OkHttp's request/response API. Your - * code will be shorter, easier to read, and you'll be able to use interceptors. - */ -@SuppressFBWarnings(value = { "EI_EXPOSE_REP", "EI_EXPOSE_REP2" }, justification = "Deprecated external code") -@Deprecated -public final class ObsoleteUrlFactory implements URLStreamHandlerFactory, Cloneable { - static final String SELECTED_PROTOCOL = "ObsoleteUrlFactory-Selected-Protocol"; - - static final String RESPONSE_SOURCE = "ObsoleteUrlFactory-Response-Source"; - - static final Set METHODS = new LinkedHashSet<>( - Arrays.asList("OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "PATCH")); - - static final TimeZone UTC = TimeZone.getTimeZone("GMT"); - - static final int HTTP_CONTINUE = 100; - - static final ThreadLocal STANDARD_DATE_FORMAT = ThreadLocal.withInitial(() -> { - // Date format specified by RFC 7231 section 7.1.1.1. - DateFormat rfc1123 = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US); - rfc1123.setLenient(false); - rfc1123.setTimeZone(UTC); - return rfc1123; - }); - - static final Comparator FIELD_NAME_COMPARATOR = (a, b) -> { - if (Objects.equals(a, b)) { - return 0; - } else if (Objects.isNull(a)) { - return -1; - } else if (Objects.isNull(b)) { - return 1; - } else { - return String.CASE_INSENSITIVE_ORDER.compare(a, b); - } - }; - - private OkHttpClient client; - - /** - * Instantiates a new Obsolete url factory. - * - * @param client - * the client - */ - public ObsoleteUrlFactory(OkHttpClient client) { - this.client = client; - } - - /** - * Client ok http client. - * - * @return the ok http client - */ - public OkHttpClient client() { - return client; - } - - /** - * Sets client. - * - * @param client - * the client - * @return the client - */ - public ObsoleteUrlFactory setClient(OkHttpClient client) { - this.client = client; - return this; - } - - /** - * Returns a copy of this stream handler factory that includes a shallow copy of the internal - * {@linkplain OkHttpClient HTTP client}. - */ - @Override - public ObsoleteUrlFactory clone() { - return new ObsoleteUrlFactory(client); - } - - /** - * Open http url connection. - * - * @param url - * the url - * @return the http url connection - */ - public HttpURLConnection open(URL url) { - return open(url, client.proxy()); - } - - HttpURLConnection open(URL url, @Nullable Proxy proxy) { - String protocol = url.getProtocol(); - OkHttpClient copy = client.newBuilder().proxy(proxy).build(); - - if (protocol.equals("http")) - return new OkHttpURLConnection(url, copy); - if (protocol.equals("https")) - return new OkHttpsURLConnection(url, copy); - throw new IllegalArgumentException("Unexpected protocol: " + protocol); - } - - /** - * Creates a URLStreamHandler as a {@link java.net.URL#setURLStreamHandlerFactory}. - * - *

    - * This code configures OkHttp to handle all HTTP and HTTPS connections created with - * {@link java.net.URL#openConnection()}: - * - *

    -     * {
    -     *     @code
    -     *
    -     *     OkHttpClient okHttpClient = new OkHttpClient();
    -     *     URL.setURLStreamHandlerFactory(new ObsoleteUrlFactory(okHttpClient));
    -     * }
    -     * 
    - */ - @Override - public URLStreamHandler createURLStreamHandler(final String protocol) { - if (!protocol.equals("http") && !protocol.equals("https")) - return null; - - return new URLStreamHandler() { - @Override - protected URLConnection openConnection(URL url) { - return open(url); - } - - @Override - protected URLConnection openConnection(URL url, Proxy proxy) { - return open(url, proxy); - } - - @Override - protected int getDefaultPort() { - if (protocol.equals("http")) - return 80; - if (protocol.equals("https")) - return 443; - throw new AssertionError(); - } - }; - } - - static String format(Date value) { - return STANDARD_DATE_FORMAT.get().format(value); - } - - static boolean permitsRequestBody(String method) { - return !(method.equals("GET") || method.equals("HEAD")); - } - - /** Returns true if the response must have a (possibly 0-length) body. See RFC 7231. */ - static boolean hasBody(Response response) { - // HEAD requests never yield a body regardless of the response headers. - if (response.request().method().equals("HEAD")) { - return false; - } - - int responseCode = response.code(); - if ((responseCode < HTTP_CONTINUE || responseCode >= 200) && responseCode != HTTP_NO_CONTENT - && responseCode != HTTP_NOT_MODIFIED) { - return true; - } - - // If the Content-Length or Transfer-Encoding headers disagree with the response code, the - // response is malformed. For best compatibility, we honor the headers. - if (contentLength(response.headers()) != -1 - || "chunked".equalsIgnoreCase(response.header("Transfer-Encoding"))) { - return true; - } - - return false; - } - - static long contentLength(Headers headers) { - String s = headers.get("Content-Length"); - if (s == null) - return -1; - try { - return Long.parseLong(s); - } catch (NumberFormatException e) { - return -1; - } - } - - static String responseSourceHeader(Response response) { - Response networkResponse = response.networkResponse(); - if (networkResponse == null) { - return response.cacheResponse() == null ? "NONE" : "CACHE " + response.code(); - } else { - return response.cacheResponse() == null - ? "NETWORK " + response.code() - : "CONDITIONAL_CACHE " + networkResponse.code(); - } - } - - static String statusLineToString(Response response) { - return (response.protocol() == Protocol.HTTP_1_0 ? "HTTP/1.0" : "HTTP/1.1") + ' ' + response.code() + ' ' - + response.message(); - } - - static String toHumanReadableAscii(String s) { - for (int i = 0, length = s.length(), c; i < length; i += Character.charCount(c)) { - c = s.codePointAt(i); - if (c > '\u001f' && c < '\u007f') - continue; - - try (Buffer buffer = new Buffer()) { - buffer.writeUtf8(s, 0, i); - buffer.writeUtf8CodePoint('?'); - for (int j = i + Character.charCount(c); j < length; j += Character.charCount(c)) { - c = s.codePointAt(j); - buffer.writeUtf8CodePoint(c > '\u001f' && c < '\u007f' ? c : '?'); - } - return buffer.readUtf8(); - } - } - return s; - } - - static Map> toMultimap(Headers headers, @Nullable String valueForNullKey) { - Map> result = new TreeMap<>(FIELD_NAME_COMPARATOR); - for (int i = 0, size = headers.size(); i < size; i++) { - String fieldName = headers.name(i); - String value = headers.value(i); - - List allValues = new ArrayList<>(); - List otherValues = result.get(fieldName); - if (otherValues != null) { - allValues.addAll(otherValues); - } - allValues.add(value); - result.put(fieldName, Collections.unmodifiableList(allValues)); - } - if (valueForNullKey != null) { - result.put(null, Collections.unmodifiableList(Collections.singletonList(valueForNullKey))); - } - return Collections.unmodifiableMap(result); - } - - static String getSystemProperty(String key, @Nullable String defaultValue) { - String value; - try { - value = System.getProperty(key); - } catch (SecurityException | IllegalArgumentException ex) { - return defaultValue; - } - return value != null ? value : defaultValue; - } - - static String defaultUserAgent() { - String agent = getSystemProperty("http.agent", null); - return agent != null ? toHumanReadableAscii(agent) : "ObsoleteUrlFactory"; - } - - static IOException propagate(Throwable throwable) throws IOException { - if (throwable instanceof IOException) - throw (IOException) throwable; - if (throwable instanceof Error) - throw (Error) throwable; - if (throwable instanceof RuntimeException) - throw (RuntimeException) throwable; - throw new AssertionError(); - } - - static final class OkHttpURLConnection extends HttpURLConnection implements Callback { - // These fields are confined to the application thread that uses HttpURLConnection. - OkHttpClient client; - final NetworkInterceptor networkInterceptor = new NetworkInterceptor(); - Headers.Builder requestHeaders = new Headers.Builder(); - Headers responseHeaders; - boolean executed; - Call call; - - /** Like the superclass field of the same name, but a long and available on all platforms. */ - long fixedContentLength = -1L; - - // These fields are guarded by lock. - private final Object lock = new Object(); - private Response response; - private Throwable callFailure; - Response networkResponse; - boolean connectPending = true; - Proxy proxy; - Handshake handshake; - - OkHttpURLConnection(URL url, OkHttpClient client) { - super(url); - this.client = client; - } - - @Override - public void connect() throws IOException { - if (executed) - return; - - Call call = buildCall(); - executed = true; - call.enqueue(this); - - synchronized (lock) { - try { - while (connectPending && response == null && callFailure == null) { - lock.wait(); // Wait 'til the network interceptor is reached or the call fails. - } - if (callFailure != null) { - throw propagate(callFailure); - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); // Retain interrupted status. - throw new InterruptedIOException(); - } - } - } - - @Override - public void disconnect() { - // Calling disconnect() before a connection exists should have no effect. - if (call == null) - return; - - networkInterceptor.proceed(); // Unblock any waiting async thread. - call.cancel(); - } - - @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "hasBody checks for this") - @Override - public InputStream getErrorStream() { - try { - Response response = getResponse(true); - if (hasBody(response) && response.code() >= HTTP_BAD_REQUEST) { - return new ResponseBodyInputStream(response.body()); - } - return null; - } catch (IOException e) { - return null; - } - } - - Headers getHeaders() throws IOException { - if (responseHeaders == null) { - Response response = getResponse(true); - Headers headers = response.headers(); - responseHeaders = headers.newBuilder() - .add(SELECTED_PROTOCOL, response.protocol().toString()) - .add(RESPONSE_SOURCE, responseSourceHeader(response)) - .build(); - } - return responseHeaders; - } - - @Override - public String getHeaderField(int position) { - try { - Headers headers = getHeaders(); - if (position < 0 || position >= headers.size()) - return null; - return headers.value(position); - } catch (IOException e) { - return null; - } - } - - @Override - public String getHeaderField(String fieldName) { - try { - return fieldName == null ? statusLineToString(getResponse(true)) : getHeaders().get(fieldName); - } catch (IOException e) { - return null; - } - } - - @Override - public String getHeaderFieldKey(int position) { - try { - Headers headers = getHeaders(); - if (position < 0 || position >= headers.size()) - return null; - return headers.name(position); - } catch (IOException e) { - return null; - } - } - - @Override - public Map> getHeaderFields() { - try { - return toMultimap(getHeaders(), statusLineToString(getResponse(true))); - } catch (IOException e) { - return Collections.emptyMap(); - } - } - - @Override - public Map> getRequestProperties() { - if (connected) { - throw new IllegalStateException("Cannot access request header fields after connection is set"); - } - - return toMultimap(requestHeaders.build(), null); - } - - @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", - justification = "Good request will have body") - @Override - public InputStream getInputStream() throws IOException { - if (!doInput) { - throw new ProtocolException("This protocol does not support input"); - } - - Response response = getResponse(false); - if (response.code() >= HTTP_BAD_REQUEST) - throw new FileNotFoundException(url.toString()); - return new ResponseBodyInputStream(response.body()); - } - - @Override - public OutputStream getOutputStream() throws IOException { - OutputStreamRequestBody requestBody = (OutputStreamRequestBody) buildCall().request().body(); - if (requestBody == null) { - throw new ProtocolException("method does not support a request body: " + method); - } - - if (requestBody instanceof StreamedRequestBody) { - connect(); - networkInterceptor.proceed(); - } - - if (requestBody.closed) { - throw new ProtocolException("cannot write request body after response has been read"); - } - - return requestBody.outputStream; - } - - @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", - justification = "usingProxy() handles this") - @Override - public Permission getPermission() { - URL url = getURL(); - String hostname = url.getHost(); - int hostPort = url.getPort() != -1 ? url.getPort() : HttpUrl.defaultPort(url.getProtocol()); - if (usingProxy()) { - InetSocketAddress proxyAddress = (InetSocketAddress) client.proxy().address(); - hostname = proxyAddress.getHostName(); - hostPort = proxyAddress.getPort(); - } - return new SocketPermission(hostname + ":" + hostPort, "connect, resolve"); - } - - @Override - public String getRequestProperty(String field) { - if (field == null) - return null; - return requestHeaders.get(field); - } - - @Override - public void setConnectTimeout(int timeoutMillis) { - client = client.newBuilder().connectTimeout(timeoutMillis, TimeUnit.MILLISECONDS).build(); - } - - @Override - public void setInstanceFollowRedirects(boolean followRedirects) { - client = client.newBuilder().followRedirects(followRedirects).build(); - } - - @Override - public boolean getInstanceFollowRedirects() { - return client.followRedirects(); - } - - @Override - public int getConnectTimeout() { - return client.connectTimeoutMillis(); - } - - @Override - public void setReadTimeout(int timeoutMillis) { - client = client.newBuilder().readTimeout(timeoutMillis, TimeUnit.MILLISECONDS).build(); - } - - @Override - public int getReadTimeout() { - return client.readTimeoutMillis(); - } - - @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE") - private Call buildCall() throws IOException { - if (call != null) { - return call; - } - - connected = true; - if (doOutput) { - if (method.equals("GET")) { - method = "POST"; - } else if (!permitsRequestBody(method)) { - throw new ProtocolException(method + " does not support writing"); - } - } - - if (requestHeaders.get("User-Agent") == null) { - requestHeaders.add("User-Agent", defaultUserAgent()); - } - - OutputStreamRequestBody requestBody = null; - if (permitsRequestBody(method)) { - String contentType = requestHeaders.get("Content-Type"); - if (contentType == null) { - contentType = "application/x-www-form-urlencoded"; - requestHeaders.add("Content-Type", contentType); - } - - boolean stream = fixedContentLength != -1L || chunkLength > 0; - - long contentLength = -1L; - String contentLengthString = requestHeaders.get("Content-Length"); - if (fixedContentLength != -1L) { - contentLength = fixedContentLength; - } else if (contentLengthString != null) { - contentLength = Long.parseLong(contentLengthString); - } - - requestBody = stream ? new StreamedRequestBody(contentLength) : new BufferedRequestBody(contentLength); - requestBody.timeout.timeout(client.writeTimeoutMillis(), TimeUnit.MILLISECONDS); - } - - HttpUrl url; - try { - url = HttpUrl.get(getURL().toString()); - } catch (IllegalArgumentException e) { - MalformedURLException malformedUrl = new MalformedURLException(); - malformedUrl.initCause(e); - throw malformedUrl; - } - - Request request = new Request.Builder().url(url) - .headers(requestHeaders.build()) - .method(method, requestBody) - .build(); - - OkHttpClient.Builder clientBuilder = client.newBuilder(); - clientBuilder.interceptors().clear(); - clientBuilder.interceptors().add(UnexpectedException.INTERCEPTOR); - clientBuilder.networkInterceptors().clear(); - clientBuilder.networkInterceptors().add(networkInterceptor); - - // Use a separate dispatcher so that limits aren't impacted. But use the same executor service! - clientBuilder.dispatcher(new Dispatcher(client.dispatcher().executorService())); - - // If we're currently not using caches, make sure the engine's client doesn't have one. - if (!getUseCaches()) { - clientBuilder.cache(null); - } - - return call = clientBuilder.build().newCall(request); - } - - private Response getResponse(boolean networkResponseOnError) throws IOException { - synchronized (lock) { - if (response != null) - return response; - if (callFailure != null) { - if (networkResponseOnError && networkResponse != null) - return networkResponse; - throw propagate(callFailure); - } - } - - Call call = buildCall(); - networkInterceptor.proceed(); - - OutputStreamRequestBody requestBody = (OutputStreamRequestBody) call.request().body(); - if (requestBody != null) - requestBody.outputStream.close(); - - if (executed) { - synchronized (lock) { - try { - while (response == null && callFailure == null) { - lock.wait(); // Wait until the response is returned or the call fails. - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); // Retain interrupted status. - throw new InterruptedIOException(); - } - } - } else { - executed = true; - try { - onResponse(call, call.execute()); - } catch (IOException e) { - onFailure(call, e); - } - } - - synchronized (lock) { - if (callFailure != null) - throw propagate(callFailure); - if (response != null) - return response; - } - - throw new AssertionError(); - } - - @Override - public boolean usingProxy() { - if (proxy != null) - return true; - Proxy clientProxy = client.proxy(); - return clientProxy != null && clientProxy.type() != Proxy.Type.DIRECT; - } - - @Override - public String getResponseMessage() throws IOException { - return getResponse(true).message(); - } - - @Override - public int getResponseCode() throws IOException { - return getResponse(true).code(); - } - - @Override - public void setRequestProperty(String field, String newValue) { - if (connected) { - throw new IllegalStateException("Cannot set request property after connection is made"); - } - if (field == null) { - throw new NullPointerException("field == null"); - } - if (newValue == null) { - return; - } - - requestHeaders.set(field, newValue); - } - - @Override - public void setIfModifiedSince(long newValue) { - super.setIfModifiedSince(newValue); - if (ifModifiedSince != 0) { - requestHeaders.set("If-Modified-Since", format(new Date(ifModifiedSince))); - } else { - requestHeaders.removeAll("If-Modified-Since"); - } - } - - @Override - public void addRequestProperty(String field, String value) { - if (connected) { - throw new IllegalStateException("Cannot add request property after connection is made"); - } - if (field == null) { - throw new NullPointerException("field == null"); - } - if (value == null) { - return; - } - - requestHeaders.add(field, value); - } - - @Override - public void setRequestMethod(String method) throws ProtocolException { - if (!METHODS.contains(method)) { - throw new ProtocolException("Expected one of " + METHODS + " but was " + method); - } - this.method = method; - } - - @Override - public void setFixedLengthStreamingMode(int contentLength) { - setFixedLengthStreamingMode((long) contentLength); - } - - @Override - public void setFixedLengthStreamingMode(long contentLength) { - if (super.connected) - throw new IllegalStateException("Already connected"); - if (chunkLength > 0) - throw new IllegalStateException("Already in chunked mode"); - if (contentLength < 0) - throw new IllegalArgumentException("contentLength < 0"); - this.fixedContentLength = contentLength; - super.fixedContentLength = (int) Math.min(contentLength, Integer.MAX_VALUE); - } - - @Override - public void onFailure(Call call, IOException e) { - synchronized (lock) { - this.callFailure = (e instanceof UnexpectedException) ? e.getCause() : e; - lock.notifyAll(); - } - } - - @Override - public void onResponse(Call call, Response response) { - synchronized (lock) { - this.response = response; - this.handshake = response.handshake(); - this.url = response.request().url().url(); - lock.notifyAll(); - } - } - - final class NetworkInterceptor implements Interceptor { - // Guarded by HttpUrlConnection.this. - private boolean proceed; - - /** - * Proceed. - */ - public void proceed() { - synchronized (lock) { - this.proceed = true; - lock.notifyAll(); - } - } - - @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", - justification = "If we get here there is a connection and request.body() is checked") - @Override - public Response intercept(Chain chain) throws IOException { - Request request = chain.request(); - - synchronized (lock) { - connectPending = false; - proxy = chain.connection().route().proxy(); - handshake = chain.connection().handshake(); - lock.notifyAll(); - - try { - while (!proceed) { - lock.wait(); // Wait until proceed() is called. - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); // Retain interrupted status. - throw new InterruptedIOException(); - } - } - - // Try to lock in the Content-Length before transmitting the request body. - if (request.body() instanceof OutputStreamRequestBody) { - OutputStreamRequestBody requestBody = (OutputStreamRequestBody) request.body(); - request = requestBody.prepareToSendRequest(request); - } - - Response response = chain.proceed(request); - - synchronized (lock) { - networkResponse = response; - url = response.request().url().url(); - } - - return response; - } - } - } - - abstract static class OutputStreamRequestBody extends RequestBody { - Timeout timeout; - long expectedContentLength; - OutputStream outputStream; - boolean closed; - - void initOutputStream(BufferedSink sink, long expectedContentLength) { - this.timeout = sink.timeout(); - this.expectedContentLength = expectedContentLength; - - // An output stream that writes to sink. If expectedContentLength is not -1, then this expects - // exactly that many bytes to be written. - this.outputStream = new OutputStream() { - private long bytesReceived; - - @Override - public void write(int b) throws IOException { - write(new byte[]{ (byte) b }, 0, 1); - } - - @Override - public void write(byte[] source, int offset, int byteCount) throws IOException { - if (closed) - throw new IOException("closed"); // Not IllegalStateException! - - if (expectedContentLength != -1L && bytesReceived + byteCount > expectedContentLength) { - throw new ProtocolException("expected " + expectedContentLength + " bytes but received " - + bytesReceived + byteCount); - } - - bytesReceived += byteCount; - try { - sink.write(source, offset, byteCount); - } catch (InterruptedIOException e) { - throw new SocketTimeoutException(e.getMessage()); - } - } - - @Override - public void flush() throws IOException { - if (closed) - return; // Weird, but consistent with historical behavior. - sink.flush(); - } - - @Override - public void close() throws IOException { - closed = true; - - if (expectedContentLength != -1L && bytesReceived < expectedContentLength) { - throw new ProtocolException( - "expected " + expectedContentLength + " bytes but received " + bytesReceived); - } - - sink.close(); - } - }; - } - - @Override - public long contentLength() { - return expectedContentLength; - } - - @Override - public final @Nullable MediaType contentType() { - return null; // Let the caller provide this in a regular header. - } - - /** - * Prepare to send request request. - * - * @param request - * the request - * @return the request - * @throws IOException - * the io exception - */ - public Request prepareToSendRequest(Request request) throws IOException { - return request; - } - } - - static final class BufferedRequestBody extends OutputStreamRequestBody { - final Buffer buffer = new Buffer(); - long contentLength = -1L; - - BufferedRequestBody(long expectedContentLength) { - initOutputStream(buffer, expectedContentLength); - } - - @Override - public long contentLength() { - return contentLength; - } - - @Override - public Request prepareToSendRequest(Request request) throws IOException { - if (request.header("Content-Length") != null) - return request; - - outputStream.close(); - contentLength = buffer.size(); - return request.newBuilder() - .removeHeader("Transfer-Encoding") - .header("Content-Length", Long.toString(buffer.size())) - .build(); - } - - @Override - public void writeTo(BufferedSink sink) { - buffer.copyTo(sink.buffer(), 0, buffer.size()); - } - } - - static final class StreamedRequestBody extends OutputStreamRequestBody { - private final Pipe pipe = new Pipe(8192); - - StreamedRequestBody(long expectedContentLength) { - initOutputStream(Okio.buffer(pipe.sink()), expectedContentLength); - } - - @Override - public boolean isOneShot() { - return true; - } - - @Override - public void writeTo(BufferedSink sink) throws IOException { - Buffer buffer = new Buffer(); - while (pipe.source().read(buffer, 8192) != -1L) { - sink.write(buffer, buffer.size()); - } - } - } - - abstract static class DelegatingHttpsURLConnection extends HttpsURLConnection { - private final HttpURLConnection delegate; - - DelegatingHttpsURLConnection(HttpURLConnection delegate) { - super(delegate.getURL()); - this.delegate = delegate; - } - - /** - * Handshake handshake. - * - * @return the handshake - */ - protected abstract Handshake handshake(); - - @Override - public abstract void setHostnameVerifier(HostnameVerifier hostnameVerifier); - - @Override - public abstract HostnameVerifier getHostnameVerifier(); - - @Override - public abstract void setSSLSocketFactory(SSLSocketFactory sslSocketFactory); - - @Override - public abstract SSLSocketFactory getSSLSocketFactory(); - - @Override - public String getCipherSuite() { - Handshake handshake = handshake(); - return handshake != null ? handshake.cipherSuite().javaName() : null; - } - - @Override - public Certificate[] getLocalCertificates() { - Handshake handshake = handshake(); - if (handshake == null) - return null; - List result = handshake.localCertificates(); - return !result.isEmpty() ? result.toArray(new Certificate[result.size()]) : null; - } - - @Override - public Certificate[] getServerCertificates() { - Handshake handshake = handshake(); - if (handshake == null) - return null; - List result = handshake.peerCertificates(); - return !result.isEmpty() ? result.toArray(new Certificate[result.size()]) : null; - } - - @Override - public Principal getPeerPrincipal() { - Handshake handshake = handshake(); - return handshake != null ? handshake.peerPrincipal() : null; - } - - @Override - public Principal getLocalPrincipal() { - Handshake handshake = handshake(); - return handshake != null ? handshake.localPrincipal() : null; - } - - @Override - public void connect() throws IOException { - connected = true; - delegate.connect(); - } - - @Override - public void disconnect() { - delegate.disconnect(); - } - - @Override - public InputStream getErrorStream() { - return delegate.getErrorStream(); - } - - @Override - public String getRequestMethod() { - return delegate.getRequestMethod(); - } - - @Override - public int getResponseCode() throws IOException { - return delegate.getResponseCode(); - } - - @Override - public String getResponseMessage() throws IOException { - return delegate.getResponseMessage(); - } - - @Override - public void setRequestMethod(String method) throws ProtocolException { - delegate.setRequestMethod(method); - } - - @Override - public boolean usingProxy() { - return delegate.usingProxy(); - } - - @Override - public boolean getInstanceFollowRedirects() { - return delegate.getInstanceFollowRedirects(); - } - - @Override - public void setInstanceFollowRedirects(boolean followRedirects) { - delegate.setInstanceFollowRedirects(followRedirects); - } - - @Override - public boolean getAllowUserInteraction() { - return delegate.getAllowUserInteraction(); - } - - @Override - public Object getContent() throws IOException { - return delegate.getContent(); - } - - @Override - public Object getContent(Class[] types) throws IOException { - return delegate.getContent(types); - } - - @Override - public String getContentEncoding() { - return delegate.getContentEncoding(); - } - - @Override - public int getContentLength() { - return delegate.getContentLength(); - } - - // Should only be invoked on Java 8+ or Android API 24+. - @Override - public long getContentLengthLong() { - return delegate.getContentLengthLong(); - } - - @Override - public String getContentType() { - return delegate.getContentType(); - } - - @Override - public long getDate() { - return delegate.getDate(); - } - - @Override - public boolean getDefaultUseCaches() { - return delegate.getDefaultUseCaches(); - } - - @Override - public boolean getDoInput() { - return delegate.getDoInput(); - } - - @Override - public boolean getDoOutput() { - return delegate.getDoOutput(); - } - - @Override - public long getExpiration() { - return delegate.getExpiration(); - } - - @Override - public String getHeaderField(int pos) { - return delegate.getHeaderField(pos); - } - - @Override - public Map> getHeaderFields() { - return delegate.getHeaderFields(); - } - - @Override - public Map> getRequestProperties() { - return delegate.getRequestProperties(); - } - - @Override - public void addRequestProperty(String field, String newValue) { - delegate.addRequestProperty(field, newValue); - } - - @Override - public String getHeaderField(String key) { - return delegate.getHeaderField(key); - } - - // Should only be invoked on Java 8+ or Android API 24+. - @Override - public long getHeaderFieldLong(String field, long defaultValue) { - return delegate.getHeaderFieldLong(field, defaultValue); - } - - @Override - public long getHeaderFieldDate(String field, long defaultValue) { - return delegate.getHeaderFieldDate(field, defaultValue); - } - - @Override - public int getHeaderFieldInt(String field, int defaultValue) { - return delegate.getHeaderFieldInt(field, defaultValue); - } - - @Override - public String getHeaderFieldKey(int position) { - return delegate.getHeaderFieldKey(position); - } - - @Override - public long getIfModifiedSince() { - return delegate.getIfModifiedSince(); - } - - @Override - public InputStream getInputStream() throws IOException { - return delegate.getInputStream(); - } - - @Override - public long getLastModified() { - return delegate.getLastModified(); - } - - @Override - public OutputStream getOutputStream() throws IOException { - return delegate.getOutputStream(); - } - - @Override - public Permission getPermission() throws IOException { - return delegate.getPermission(); - } - - @Override - public String getRequestProperty(String field) { - return delegate.getRequestProperty(field); - } - - @Override - public URL getURL() { - return delegate.getURL(); - } - - @Override - public boolean getUseCaches() { - return delegate.getUseCaches(); - } - - @Override - public void setAllowUserInteraction(boolean newValue) { - delegate.setAllowUserInteraction(newValue); - } - - @Override - public void setDefaultUseCaches(boolean newValue) { - delegate.setDefaultUseCaches(newValue); - } - - @Override - public void setDoInput(boolean newValue) { - delegate.setDoInput(newValue); - } - - @Override - public void setDoOutput(boolean newValue) { - delegate.setDoOutput(newValue); - } - - // Should only be invoked on Java 8+ or Android API 24+. - @Override - public void setFixedLengthStreamingMode(long contentLength) { - delegate.setFixedLengthStreamingMode(contentLength); - } - - @Override - public void setIfModifiedSince(long newValue) { - delegate.setIfModifiedSince(newValue); - } - - @Override - public void setRequestProperty(String field, String newValue) { - delegate.setRequestProperty(field, newValue); - } - - @Override - public void setUseCaches(boolean newValue) { - delegate.setUseCaches(newValue); - } - - @Override - public void setConnectTimeout(int timeoutMillis) { - delegate.setConnectTimeout(timeoutMillis); - } - - @Override - public int getConnectTimeout() { - return delegate.getConnectTimeout(); - } - - @Override - public void setReadTimeout(int timeoutMillis) { - delegate.setReadTimeout(timeoutMillis); - } - - @Override - public int getReadTimeout() { - return delegate.getReadTimeout(); - } - - @Override - public String toString() { - return delegate.toString(); - } - - @Override - public void setFixedLengthStreamingMode(int contentLength) { - delegate.setFixedLengthStreamingMode(contentLength); - } - - @Override - public void setChunkedStreamingMode(int chunkLength) { - delegate.setChunkedStreamingMode(chunkLength); - } - } - - static final class OkHttpsURLConnection extends DelegatingHttpsURLConnection { - private final OkHttpURLConnection delegate; - - OkHttpsURLConnection(URL url, OkHttpClient client) { - this(new OkHttpURLConnection(url, client)); - } - - OkHttpsURLConnection(OkHttpURLConnection delegate) { - super(delegate); - this.delegate = delegate; - } - - @Override - protected Handshake handshake() { - if (delegate.call == null) { - throw new IllegalStateException("Connection has not yet been established"); - } - - return delegate.handshake; - } - - @Override - public void setHostnameVerifier(HostnameVerifier hostnameVerifier) { - delegate.client = delegate.client.newBuilder().hostnameVerifier(hostnameVerifier).build(); - } - - @Override - public HostnameVerifier getHostnameVerifier() { - return delegate.client.hostnameVerifier(); - } - - @Override - public void setSSLSocketFactory(SSLSocketFactory sslSocketFactory) { - if (sslSocketFactory == null) { - throw new IllegalArgumentException("sslSocketFactory == null"); - } - // This fails in JDK 9 because OkHttp is unable to extract the trust manager. - delegate.client = delegate.client.newBuilder().sslSocketFactory(sslSocketFactory).build(); - } - - @Override - public SSLSocketFactory getSSLSocketFactory() { - return delegate.client.sslSocketFactory(); - } - } - - static final class UnexpectedException extends IOException { - static final Interceptor INTERCEPTOR = chain -> { - try { - return chain.proceed(chain.request()); - } catch (Error | RuntimeException e) { - throw new UnexpectedException(e); - } - }; - - UnexpectedException(Throwable cause) { - super(cause); - } - } - - /** - * Make sure both the ResponseBody and the InputStream are closed when the InputStream coming from the ResponseBody - * is closed. - */ - private static final class ResponseBodyInputStream extends InputStream { - - private final ResponseBody responseBody; - - private final InputStream inputStream; - - private ResponseBodyInputStream(ResponseBody responseBody) { - this.responseBody = responseBody; - this.inputStream = responseBody.byteStream(); - } - - @Override - public int read() throws IOException { - return inputStream.read(); - } - - @Override - public int read(byte b[]) throws IOException { - return inputStream.read(b); - } - - @Override - public int read(byte b[], int off, int len) throws IOException { - return inputStream.read(b, off, len); - } - - @Override - public long skip(long n) throws IOException { - return inputStream.skip(n); - } - - @Override - public int available() throws IOException { - return inputStream.available(); - } - - @Override - public synchronized void mark(int readlimit) { - inputStream.mark(readlimit); - } - - @Override - public synchronized void reset() throws IOException { - inputStream.reset(); - } - - @Override - public boolean markSupported() { - return inputStream.markSupported(); - } - - @Override - public void close() throws IOException { - try { - inputStream.close(); - } finally { - responseBody.close(); - } - } - } -} diff --git a/src/main/java/org/kohsuke/github/extras/okhttp3/OkHttpConnector.java b/src/main/java/org/kohsuke/github/extras/okhttp3/OkHttpConnector.java deleted file mode 100644 index bc09891ea2..0000000000 --- a/src/main/java/org/kohsuke/github/extras/okhttp3/OkHttpConnector.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.kohsuke.github.extras.okhttp3; - -import okhttp3.CacheControl; -import okhttp3.ConnectionSpec; -import okhttp3.OkHttpClient; -import org.kohsuke.github.HttpConnector; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.TimeUnit; - -/** - * {@link HttpConnector} for {@link OkHttpClient}. - *

    - * Unlike {@link #DEFAULT}, OkHttp does response caching. Making a conditional request against GitHubAPI and receiving a - * 304 response does not count against the rate limit. See http://developer.github.com/v3/#conditional-requests - * - * @author Liam Newman - * @deprecated Use {@link OkHttpGitHubConnector} instead. - */ -@Deprecated -public class OkHttpConnector implements HttpConnector { - private static final String HEADER_NAME = "Cache-Control"; - private final String maxAgeHeaderValue; - - private final OkHttpClient client; - private final ObsoleteUrlFactory urlFactory; - - /** - * Instantiates a new Ok http connector. - * - * @param client - * the client - */ - public OkHttpConnector(OkHttpClient client) { - this(client, 0); - } - - /** - * Instantiates a new Ok http connector. - * - * @param client - * the client - * @param cacheMaxAge - * the cache max age - */ - public OkHttpConnector(OkHttpClient client, int cacheMaxAge) { - - OkHttpClient.Builder builder = client.newBuilder(); - - builder.connectionSpecs(TlsConnectionSpecs()); - this.client = builder.build(); - if (cacheMaxAge >= 0 && this.client != null && this.client.cache() != null) { - maxAgeHeaderValue = new CacheControl.Builder().maxAge(cacheMaxAge, TimeUnit.SECONDS).build().toString(); - } else { - maxAgeHeaderValue = null; - } - this.urlFactory = new ObsoleteUrlFactory(this.client); - } - - public HttpURLConnection connect(URL url) throws IOException { - HttpURLConnection urlConnection = urlFactory.open(url); - if (maxAgeHeaderValue != null) { - // By default OkHttp honors max-age, meaning it will use local cache - // without checking the network within that timeframe. - // However, that can result in stale data being returned during that time so - // we force network-based checking no matter how often the query is made. - // OkHttp still automatically does ETag checking and returns cached data when - // GitHub reports 304, but those do not count against rate limit. - urlConnection.setRequestProperty(HEADER_NAME, maxAgeHeaderValue); - } - - return urlConnection; - } - - /** Returns connection spec with TLS v1.2 in it */ - private List TlsConnectionSpecs() { - return Arrays.asList(ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT); - } -} diff --git a/src/main/java/org/kohsuke/github/internal/DefaultGitHubConnector.java b/src/main/java/org/kohsuke/github/internal/DefaultGitHubConnector.java index 1b00b01596..d7cb0b7522 100644 --- a/src/main/java/org/kohsuke/github/internal/DefaultGitHubConnector.java +++ b/src/main/java/org/kohsuke/github/internal/DefaultGitHubConnector.java @@ -1,10 +1,8 @@ package org.kohsuke.github.internal; import okhttp3.OkHttpClient; -import org.kohsuke.github.HttpConnector; import org.kohsuke.github.connector.GitHubConnector; import org.kohsuke.github.extras.HttpClientGitHubConnector; -import org.kohsuke.github.extras.okhttp3.OkHttpConnector; import org.kohsuke.github.extras.okhttp3.OkHttpGitHubConnector; /** @@ -22,9 +20,6 @@ private DefaultGitHubConnector() { /** * Creates a {@link GitHubConnector} that will be used as the default connector. * - * This method currently defaults to returning an instance of {@link GitHubConnectorHttpConnectorAdapter}. This - * preserves backward compatibility with {@link HttpConnector}. - * *

    * For testing purposes, the system property {@code test.github.connector} can be set to change the default. * Possible values: {@code default}, {@code okhttp}, {@code httpconnector}. @@ -43,21 +38,13 @@ static GitHubConnector create(String defaultConnectorProperty) { if (defaultConnectorProperty.equalsIgnoreCase("okhttp")) { return new OkHttpGitHubConnector(new OkHttpClient.Builder().build()); - } else if (defaultConnectorProperty.equalsIgnoreCase("okhttpconnector")) { - return new GitHubConnectorHttpConnectorAdapter(new OkHttpConnector(new OkHttpClient.Builder().build())); - } else if (defaultConnectorProperty.equalsIgnoreCase("urlconnection")) { - return new GitHubConnectorHttpConnectorAdapter(HttpConnector.DEFAULT); } else if (defaultConnectorProperty.equalsIgnoreCase("httpclient")) { return new HttpClientGitHubConnector(); } else if (defaultConnectorProperty.equalsIgnoreCase("default")) { - try { - return new HttpClientGitHubConnector(); - } catch (UnsupportedOperationException | LinkageError e) { - return new GitHubConnectorHttpConnectorAdapter(HttpConnector.DEFAULT); - } + return new HttpClientGitHubConnector(); } else { throw new IllegalStateException( - "Property 'test.github.connector' must reference a valid built-in connector - okhttp, okhttpconnector, urlconnection, or default."); + "Property 'test.github.connector' must reference a valid built-in connector - okhttp, httpclient, or default."); } } } diff --git a/src/main/java/org/kohsuke/github/internal/GitHubConnectorHttpConnectorAdapter.java b/src/main/java/org/kohsuke/github/internal/GitHubConnectorHttpConnectorAdapter.java deleted file mode 100644 index 3dc0e9d7b0..0000000000 --- a/src/main/java/org/kohsuke/github/internal/GitHubConnectorHttpConnectorAdapter.java +++ /dev/null @@ -1,202 +0,0 @@ -package org.kohsuke.github.internal; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import org.apache.commons.io.IOUtils; -import org.kohsuke.github.*; -import org.kohsuke.github.connector.GitHubConnector; -import org.kohsuke.github.connector.GitHubConnectorRequest; -import org.kohsuke.github.connector.GitHubConnectorResponse; - -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Field; -import java.net.HttpURLConnection; -import java.net.ProtocolException; -import java.net.URL; -import java.util.List; -import java.util.Map; - -import javax.annotation.CheckForNull; -import javax.annotation.Nonnull; - -/** - * Adapts an HttpConnector to be usable as GitHubConnector. - * - * For internal use only. - * - * @author Liam Newman - */ -public final class GitHubConnectorHttpConnectorAdapter implements GitHubConnector, HttpConnector { - - /** - * Internal for testing. - */ - final HttpConnector httpConnector; - - /** - * Constructor. - * - * @param httpConnector - * the HttpConnector to be adapted. - */ - public GitHubConnectorHttpConnectorAdapter(HttpConnector httpConnector) { - this.httpConnector = httpConnector; - } - - /** - * Creates a GitHubConnector for an HttpConnector. - * - * If a well-known static HttpConnector is passed, a corresponding static GitHubConnector is returned. - * - * @param connector - * the HttpConnector to be adapted. - * @return a GitHubConnector that calls into the provided HttpConnector. - */ - @Nonnull - public static GitHubConnector adapt(@Nonnull HttpConnector connector) { - GitHubConnector gitHubConnector; - if (connector == HttpConnector.DEFAULT) { - gitHubConnector = GitHubConnector.DEFAULT; - } else if (connector == HttpConnector.OFFLINE) { - gitHubConnector = GitHubConnector.OFFLINE; - } else if (connector instanceof GitHubConnector) { - gitHubConnector = (GitHubConnector) connector; - } else { - gitHubConnector = new GitHubConnectorHttpConnectorAdapter(connector); - } - return gitHubConnector; - } - - @Nonnull - public HttpURLConnection connect(URL url) throws IOException { - return this.httpConnector.connect(url); - } - - @Nonnull - public GitHubConnectorResponse send(GitHubConnectorRequest request) throws IOException { - HttpURLConnection connection; - try { - connection = setupConnection(this, request); - } catch (IOException e) { - // An error in here should be wrapped to bypass http exception wrapping. - throw new GHIOException(e.getMessage(), e); - } - - // HttpUrlConnection is nuts. This call opens the connection and gets a response. - // Putting this on its own line for ease of debugging if needed. - int statusCode = connection.getResponseCode(); - Map> headers = connection.getHeaderFields(); - - return new HttpURLConnectionGitHubConnectorResponse(request, statusCode, headers, connection); - } - - @Nonnull - private static HttpURLConnection setupConnection(@Nonnull HttpConnector connector, - @Nonnull GitHubConnectorRequest request) throws IOException { - HttpURLConnection connection = connector.connect(request.url()); - setRequestMethod(request.method(), connection); - buildRequest(request, connection); - - return connection; - } - - /** - * Set up the request parameters or POST payload. - */ - private static void buildRequest(GitHubConnectorRequest request, HttpURLConnection connection) throws IOException { - for (Map.Entry> e : request.allHeaders().entrySet()) { - List v = e.getValue(); - if (v != null) - connection.setRequestProperty(e.getKey(), String.join(", ", v)); - } - - if (request.hasBody()) { - connection.setDoOutput(true); - IOUtils.copyLarge(request.body(), connection.getOutputStream()); - } - } - - private static void setRequestMethod(String method, HttpURLConnection connection) throws IOException { - try { - connection.setRequestMethod(method); - } catch (ProtocolException e) { - // JDK only allows one of the fixed set of verbs. Try to override that - try { - Field $method = HttpURLConnection.class.getDeclaredField("method"); - $method.setAccessible(true); - $method.set(connection, method); - } catch (Exception x) { - throw (IOException) new IOException("Failed to set the custom verb").initCause(x); - } - // sun.net.www.protocol.https.DelegatingHttpsURLConnection delegates to another HttpURLConnection - try { - Field $delegate = connection.getClass().getDeclaredField("delegate"); - $delegate.setAccessible(true); - Object delegate = $delegate.get(connection); - if (delegate instanceof HttpURLConnection) { - HttpURLConnection nested = (HttpURLConnection) delegate; - setRequestMethod(method, nested); - } - } catch (NoSuchFieldException x) { - // no problem - } catch (IllegalAccessException x) { - throw (IOException) new IOException("Failed to set the custom verb").initCause(x); - } - } - if (!connection.getRequestMethod().equals(method)) - throw new IllegalStateException("Failed to set the request method to " + method); - } - - /** - * Initial response information supplied when a response is received but before the body is processed. - * - * Implementation specific to {@link HttpURLConnection}. For internal use only. - */ - public final static class HttpURLConnectionGitHubConnectorResponse - extends - GitHubConnectorResponse.ByteArrayResponse { - - @Nonnull - private final HttpURLConnection connection; - - HttpURLConnectionGitHubConnectorResponse(@Nonnull GitHubConnectorRequest request, - int statusCode, - @Nonnull Map> headers, - @Nonnull HttpURLConnection connection) { - super(request, statusCode, headers); - this.connection = connection; - } - - @CheckForNull - @Override - protected InputStream rawBodyStream() throws IOException { - InputStream rawStream = connection.getErrorStream(); - if (rawStream == null) { - rawStream = connection.getInputStream(); - } - return rawStream; - } - - /** - * {@inheritDoc} - */ - @SuppressFBWarnings(value = { "EI_EXPOSE_REP" }, - justification = "Internal implementation class. Should not be used externally.") - @Nonnull - @Override - @Deprecated - public HttpURLConnection toHttpURLConnection() { - return connection; - } - - @Override - public void close() throws IOException { - super.close(); - try { - IOUtils.closeQuietly(connection.getInputStream()); - } catch (IOException e) { - } - } - } - -} diff --git a/src/main/java/org/kohsuke/github/internal/Previews.java b/src/main/java/org/kohsuke/github/internal/Previews.java deleted file mode 100644 index 77beb5a42d..0000000000 --- a/src/main/java/org/kohsuke/github/internal/Previews.java +++ /dev/null @@ -1,145 +0,0 @@ -package org.kohsuke.github.internal; - -/** - * Provides the media type strings for GitHub API previews - * - * https://developer.github.com/v3/previews/ - * - * @author Kohsuke Kawaguchi - */ -@Deprecated -public enum Previews { - - /** - * Check-runs and check-suites - * - * @see GitHub API Previews - */ - ANTIOPE("application/vnd.github.antiope-preview+json"), - - /** - * Enhanced Deployments - * - * @see GitHub API Previews - */ - ANT_MAN("application/vnd.github.ant-man-preview+json"), - - /** - * Create repository from template repository - * - * @see GitHub API - * Previews - */ - BAPTISTE("application/vnd.github.baptiste-preview+json"), - - /** - * Commit Search - * - * @see GitHub API Previews - */ - CLOAK("application/vnd.github.cloak-preview+json"), - - /** - * New deployment statuses and support for updating deployment status environment - * - * @see GitHub API Previews - */ - FLASH("application/vnd.github.flash-preview+json"), - - /** - * Owners of GitHub Apps can now uninstall an app using the Apps API - * - * @see GitHub API Previews - */ - GAMBIT("application/vnd.github.gambit-preview+json"), - - /** - * List branches or pull requests for a commit - * - * @see GitHub API - * Previews - */ - GROOT("application/vnd.github.groot-preview+json"), - - /** - * Manage projects - * - * @see GitHub API Previews - */ - INERTIA("application/vnd.github.inertia-preview+json"), - - /** - * Update a pull request branch - * - * @see GitHub API Previews - */ - LYDIAN("application/vnd.github.lydian-preview+json"), - - /** - * Require multiple approving reviews - * - * @see GitHub API - * Previews - */ - LUKE_CAGE("application/vnd.github.luke-cage-preview+json"), - - /** - * Manage integrations through the API - * - * @see GitHub API Previews - */ - MACHINE_MAN("application/vnd.github.machine-man-preview+json"), - - /** - * View a list of repository topics in calls that return repository results - * - * @see GitHub API Previews - */ - MERCY("application/vnd.github.mercy-preview+json"), - - /** - * New visibility parameter for the Repositories API - * - * @see GitHub - * API Previews - */ - NEBULA("application/vnd.github.nebula-preview+json"), - - /** - * Draft pull requests - * - * @see GitHub API Previews - */ - SHADOW_CAT("application/vnd.github.shadow-cat-preview+json"), - - /** - * Reactions - * - * @see GitHub API Previews - */ - SQUIRREL_GIRL("application/vnd.github.squirrel-girl-preview+json"), - - /** - * Require signed commits - * - * @see GitHub API Previews - */ - ZZZAX("application/vnd.github.zzzax-preview+json") - - ; - - private final String mediaType; - - Previews(String mediaType) { - this.mediaType = mediaType; - } - - /** - * Gets the mediaType - * - * @return the media type string - */ - public String mediaType() { - return mediaType; - } -} diff --git a/src/main/java11/org/kohsuke/github/extras/HttpClientGitHubConnector.java b/src/main/java11/org/kohsuke/github/extras/HttpClientGitHubConnector.java deleted file mode 100644 index dd8556b9b8..0000000000 --- a/src/main/java11/org/kohsuke/github/extras/HttpClientGitHubConnector.java +++ /dev/null @@ -1,117 +0,0 @@ -package org.kohsuke.github.extras; - -import org.apache.commons.io.IOUtils; -import org.kohsuke.github.connector.GitHubConnector; -import org.kohsuke.github.connector.GitHubConnectorRequest; -import org.kohsuke.github.connector.GitHubConnectorResponse; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InterruptedIOException; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.util.List; -import java.util.Map; - -import javax.annotation.CheckForNull; -import javax.annotation.Nonnull; - -/** - * {@link GitHubConnector} for {@link HttpClient}. - * - * @author Liam Newman - */ -public class HttpClientGitHubConnector implements GitHubConnector { - - private final HttpClient client; - - /** - * Instantiates a new HttpClientGitHubConnector with a default HttpClient. - */ - public HttpClientGitHubConnector() { - // GitHubClient handles redirects manually as Java HttpClient copies all the headers when redirecting - // even when redirecting to a different host which is problematic as we don't want - // to push the Authorization header when redirected to a different host. - // This problem was discovered when upload-artifact@v4 was released as the new - // service we are redirected to for downloading the artifacts doesn't support - // having the Authorization header set. - // The new implementation does not push the Authorization header when redirected - // to a different host, which is similar to what Okhttp is doing: - // https://github.com/square/okhttp/blob/f9dfd4e8cc070ca2875a67d8f7ad939d95e7e296/okhttp/src/main/kotlin/okhttp3/internal/http/RetryAndFollowUpInterceptor.kt#L313-L318 - // See also https://github.com/arduino/report-size-deltas/pull/83 for more context - this(HttpClient.newBuilder().followRedirects(HttpClient.Redirect.NEVER).build()); - } - - /** - * Instantiates a new HttpClientGitHubConnector. - * - * @param client - * the HttpClient to be used - */ - public HttpClientGitHubConnector(HttpClient client) { - this.client = client; - } - - @Override - public GitHubConnectorResponse send(GitHubConnectorRequest connectorRequest) throws IOException { - HttpRequest.Builder builder = HttpRequest.newBuilder(); - try { - builder.uri(connectorRequest.url().toURI()); - } catch (URISyntaxException e) { - throw new IOException("Invalid URL", e); - } - - for (Map.Entry> e : connectorRequest.allHeaders().entrySet()) { - List v = e.getValue(); - if (v != null) { - builder.header(e.getKey(), String.join(", ", v)); - } - } - - HttpRequest.BodyPublisher publisher = HttpRequest.BodyPublishers.noBody(); - if (connectorRequest.hasBody()) { - publisher = HttpRequest.BodyPublishers.ofByteArray(IOUtils.toByteArray(connectorRequest.body())); - } - builder.method(connectorRequest.method(), publisher); - - HttpRequest request = builder.build(); - - try { - HttpResponse httpResponse = client.send(request, HttpResponse.BodyHandlers.ofInputStream()); - return new HttpClientGitHubConnectorResponse(connectorRequest, httpResponse); - } catch (InterruptedException e) { - throw (InterruptedIOException) new InterruptedIOException(e.getMessage()).initCause(e); - } - } - - /** - * Initial response information when a response is initially received and before the body is processed. - * - * Implementation specific to {@link HttpResponse}. - */ - private static class HttpClientGitHubConnectorResponse extends GitHubConnectorResponse.ByteArrayResponse { - - @Nonnull - private final HttpResponse response; - - protected HttpClientGitHubConnectorResponse(@Nonnull GitHubConnectorRequest request, - @Nonnull HttpResponse response) { - super(request, response.statusCode(), response.headers().map()); - this.response = response; - } - - @CheckForNull - @Override - protected InputStream rawBodyStream() throws IOException { - return response.body(); - } - - @Override - public void close() throws IOException { - super.close(); - IOUtils.closeQuietly(response.body()); - } - } -} diff --git a/src/test/java/org/kohsuke/HookApp.java b/src/test/java/org/kohsuke/HookApp.java deleted file mode 100644 index 1b67eb67aa..0000000000 --- a/src/test/java/org/kohsuke/HookApp.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.kohsuke; - -import org.kohsuke.github.GHEventPayload; -import org.kohsuke.github.GitHub; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.jetty.JettyRunner; - -import java.io.IOException; -import java.io.StringReader; - -// TODO: Auto-generated Javadoc -/** - * App to test the hook script. You need some internet-facing server that can forward the request to you (typically via - * SSH reverse port forwarding.) - * - * @author Kohsuke Kawaguchi - */ -public class HookApp { - - /** - * The main method. - * - * @param args - * the arguments - * @throws Exception - * the exception - */ - public static void main(String[] args) throws Exception { - // GitHub.connect().getMyself().getRepository("sandbox").createWebHook( - // new URL("http://173.203.118.45:18080/"), EnumSet.of(GHEvent.PULL_REQUEST)); - JettyRunner jr = new JettyRunner(new HookApp()); - jr.addHttpListener(8080); - jr.start(); - } - - /** - * Do index. - * - * @param req - * the req - * @throws IOException - * Signals that an I/O exception has occurred. - */ - public void doIndex(StaplerRequest req) throws IOException { - String str = req.getParameter("payload"); - // System.out.println(str); - GHEventPayload.PullRequest o = GitHub.connect() - .parseEventPayload(new StringReader(str), GHEventPayload.PullRequest.class); - // System.out.println(o); - } -} diff --git a/src/test/java/org/kohsuke/github/AbstractGitHubWireMockTest.java b/src/test/java/org/kohsuke/github/AbstractGitHubWireMockTest.java index 044a7122ec..88a75d7af8 100644 --- a/src/test/java/org/kohsuke/github/AbstractGitHubWireMockTest.java +++ b/src/test/java/org/kohsuke/github/AbstractGitHubWireMockTest.java @@ -112,7 +112,7 @@ private static GitHubBuilder createGitHubBuilder() { } catch (IOException e) { } - return builder.withRateLimitHandler(RateLimitHandler.FAIL); + return builder.withRateLimitHandler(GitHubRateLimitHandler.FAIL); } /** @@ -127,7 +127,7 @@ protected GitHubBuilder getGitHubBuilder() { // This sets the user and password to a placeholder for wiremock testing // This makes the tests believe they are running with permissions // The recorded stubs will behave like they running with permissions - builder.withPassword(STUBBED_USER_LOGIN, STUBBED_USER_PASSWORD); + builder.withOAuthToken(STUBBED_USER_PASSWORD, STUBBED_USER_LOGIN); } return builder; diff --git a/src/test/java/org/kohsuke/github/AbuseLimitHandlerTest.java b/src/test/java/org/kohsuke/github/AbuseLimitHandlerTest.java index 5736146c4c..cc2420b234 100644 --- a/src/test/java/org/kohsuke/github/AbuseLimitHandlerTest.java +++ b/src/test/java/org/kohsuke/github/AbuseLimitHandlerTest.java @@ -3,19 +3,16 @@ import com.github.tomakehurst.wiremock.core.WireMockConfiguration; import org.apache.commons.io.IOUtils; import org.hamcrest.Matchers; -import org.junit.Assert; +import org.jetbrains.annotations.NotNull; import org.junit.Test; +import org.kohsuke.github.connector.GitHubConnectorResponse; import java.io.IOException; import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.ProtocolException; import java.nio.charset.StandardCharsets; -import java.util.Date; import java.util.Map; import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.core.IsInstanceOf.instanceOf; @@ -69,126 +66,158 @@ protected WireMockConfiguration getWireMockOptions() { public void testHandler_Fail() throws Exception { // Customized response that templates the date to keep things working snapshotNotAllowed(); - final HttpURLConnection[] savedConnection = new HttpURLConnection[1]; gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withAbuseLimitHandler(new AbuseLimitHandler() { + .withAbuseLimitHandler(new GitHubAbuseLimitHandler() { @Override - public void onError(IOException e, HttpURLConnection uc) throws IOException { - savedConnection[0] = uc; + public void onError(@NotNull GitHubConnectorResponse connectorResponse) throws IOException { // Verify - assertThat(uc.getDate(), Matchers.greaterThanOrEqualTo(new Date().getTime() - 10000)); - assertThat(uc.getExpiration(), equalTo(0L)); - assertThat(uc.getIfModifiedSince(), equalTo(0L)); - assertThat(uc.getLastModified(), equalTo(1581014017000L)); - assertThat(uc.getRequestMethod(), equalTo("GET")); - assertThat(uc.getResponseCode(), equalTo(403)); - assertThat(uc.getResponseMessage(), containsString("Forbidden")); - assertThat(uc.getURL().toString(), endsWith("/repos/hub4j-test-org/temp-testHandler_Fail")); - assertThat(uc.getHeaderFieldInt("X-RateLimit-Limit", 10), equalTo(5000)); - assertThat(uc.getHeaderFieldInt("X-RateLimit-Remaining", 10), equalTo(4000)); - assertThat(uc.getHeaderFieldInt("X-Foo", 20), equalTo(20)); - assertThat(uc.getHeaderFieldLong("X-RateLimit-Limit", 15L), equalTo(5000L)); - assertThat(uc.getHeaderFieldLong("X-RateLimit-Remaining", 15L), equalTo(4000L)); - assertThat(uc.getHeaderFieldLong("X-Foo", 20L), equalTo(20L)); - - assertThat(uc.getContentEncoding(), nullValue()); - assertThat(uc.getContentType(), equalTo("application/json; charset=utf-8")); - assertThat(uc.getContentLength(), equalTo(-1)); - - // getting an input stream in an error case should throw - IOException ioEx = Assert.assertThrows(IOException.class, () -> uc.getInputStream()); - - checkErrorMessageMatches(uc, "Must have push access to repository"); - - // calling again should still error - ioEx = Assert.assertThrows(IOException.class, () -> uc.getInputStream()); - - // calling again on a GitHubConnectorResponse should yield the same value - if (uc.toString().contains("GitHubConnectorResponseHttpUrlConnectionAdapter")) { - checkErrorMessageMatches(uc, "Must have push access to repository"); - } else { - try (InputStream errorStream = uc.getErrorStream()) { - assertThat(errorStream, notNullValue()); - String errorString = IOUtils.toString(errorStream, StandardCharsets.UTF_8); - fail(); - } catch (IOException ex) { - assertThat(ex, notNullValue()); - assertThat(ex.getMessage(), containsString("stream is closed")); - } - } - - assertThat(uc.getHeaderFields(), instanceOf(Map.class)); - assertThat(uc.getHeaderFields().size(), greaterThan(25)); - assertThat(uc.getHeaderField("Status"), equalTo("403 Forbidden")); - - String key = uc.getHeaderFieldKey(1); - assertThat(key, notNullValue()); - assertThat(uc.getHeaderField(1), notNullValue()); - assertThat(uc.getHeaderField(1), equalTo(uc.getHeaderField(key))); - - assertThat(uc.getRequestProperty("Accept"), equalTo("application/vnd.github+json")); - - Assert.assertThrows(IllegalStateException.class, () -> uc.getRequestProperties()); - - // Actions that are not allowed because connection already opened. - Assert.assertThrows(IllegalStateException.class, () -> uc.addRequestProperty("bogus", "item")); - - Assert.assertThrows(IllegalStateException.class, () -> uc.setAllowUserInteraction(true)); - Assert.assertThrows(IllegalStateException.class, () -> uc.setChunkedStreamingMode(1)); - Assert.assertThrows(IllegalStateException.class, () -> uc.setDoInput(true)); - Assert.assertThrows(IllegalStateException.class, () -> uc.setDoOutput(true)); - Assert.assertThrows(IllegalStateException.class, () -> uc.setFixedLengthStreamingMode(1)); - Assert.assertThrows(IllegalStateException.class, () -> uc.setFixedLengthStreamingMode(1L)); - Assert.assertThrows(IllegalStateException.class, () -> uc.setIfModifiedSince(1L)); - Assert.assertThrows(IllegalStateException.class, () -> uc.setRequestProperty("bogus", "thing")); - Assert.assertThrows(IllegalStateException.class, () -> uc.setUseCaches(true)); - - if (uc.toString().contains("GitHubConnectorResponseHttpUrlConnectionAdapter")) { - - Assert.assertThrows(UnsupportedOperationException.class, - () -> uc.getAllowUserInteraction()); - Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getConnectTimeout()); - Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getContent()); - Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getContent(null)); - Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getDefaultUseCaches()); - Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getDoInput()); - Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getDoOutput()); - Assert.assertThrows(UnsupportedOperationException.class, - () -> uc.getInstanceFollowRedirects()); - Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getOutputStream()); - Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getPermission()); - Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getReadTimeout()); - Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getUseCaches()); - Assert.assertThrows(UnsupportedOperationException.class, () -> uc.usingProxy()); - - Assert.assertThrows(UnsupportedOperationException.class, () -> uc.setConnectTimeout(10)); - Assert.assertThrows(UnsupportedOperationException.class, - () -> uc.setDefaultUseCaches(true)); - - Assert.assertThrows(UnsupportedOperationException.class, - () -> uc.setInstanceFollowRedirects(true)); - Assert.assertThrows(UnsupportedOperationException.class, () -> uc.setReadTimeout(10)); - Assert.assertThrows(ProtocolException.class, () -> uc.setRequestMethod("GET")); - } else { - uc.getDefaultUseCaches(); - assertThat(uc.getDoInput(), is(true)); - - // Depending on the underlying implementation, this may throw or not - // Assert.assertThrows(IllegalStateException.class, () -> uc.setRequestMethod("GET")); - } - - // ignored - uc.connect(); - - // disconnect does nothing, never throws - uc.disconnect(); - uc.disconnect(); - - // ignored - uc.connect(); - - AbuseLimitHandler.FAIL.onError(e, uc); + // assertThat(GitHubClient.parseInstant(connectorResponse.header("Date")).toEpochMilli(), + // Matchers.greaterThanOrEqualTo(new Date().getTime() - 10000)); + assertThat(connectorResponse.header("Expires"), nullValue()); + // assertThat(GitHubClient.parseInstant(connectorResponse.header("Last-Modified")).toEpochMilli(), + // equalTo(1581014017000L)); + assertThat(connectorResponse.statusCode(), equalTo(403)); + assertThat(connectorResponse.header("Status"), containsString("Forbidden")); + // assertThat(uc.getHeaderFieldInt("X-RateLimit-Limit", 10), equalTo(5000)); + // assertThat(uc.getHeaderFieldInt("X-RateLimit-Remaining", 10), equalTo(4000)); + // assertThat(uc.getHeaderFieldInt("X-Foo", 20), equalTo(20)); + // assertThat(uc.getHeaderFieldLong("X-RateLimit-Limit", 15L), equalTo(5000L)); + // assertThat(uc.getHeaderFieldLong("X-RateLimit-Remaining", 15L), equalTo(4000L)); + // assertThat(uc.getHeaderFieldLong("X-Foo", 20L), equalTo(20L)); + // + // assertThat(uc.getContentEncoding(), nullValue()); + // assertThat(uc.getContentType(), equalTo("application/json; charset=utf-8")); + // assertThat(uc.getContentLength(), equalTo(-1)); + // + // // getting an input stream in an error case should throw + // IOException ioEx = Assert.assertThrows(IOException.class, () -> uc.getInputStream()); + // + // try (InputStream errorStream = uc.getErrorStream()) { + // assertThat(errorStream, notNullValue()); + // String errorString = IOUtils.toString(errorStream, StandardCharsets.UTF_8); + // assertThat(errorString, containsString("Must have push access to repository")); + // } + // + // // calling again should still error + // ioEx = Assert.assertThrows(IOException.class, () -> uc.getInputStream()); + // + // // calling again on a GitHubConnectorResponse should yield the same value + // if (uc.toString().contains("GitHubConnectorResponseHttpUrlConnectionAdapter")) { + // try (InputStream errorStream = uc.getErrorStream()) { + // assertThat(errorStream, notNullValue()); + // String errorString = IOUtils.toString(errorStream, StandardCharsets.UTF_8); + // assertThat(errorString, containsString("Must have push access to repository")); + // } + // } else { + // try (InputStream errorStream = uc.getErrorStream()) { + // assertThat(errorStream, notNullValue()); + // String errorString = IOUtils.toString(errorStream, StandardCharsets.UTF_8); + // fail(); + // } catch (IOException ex) { + // assertThat(ex, notNullValue()); + // assertThat(ex.getMessage(), containsString("stream is closed")); + // } + // } + + assertThat(connectorResponse.allHeaders(), instanceOf(Map.class)); + assertThat(connectorResponse.allHeaders().size(), Matchers.greaterThan(25)); + assertThat(connectorResponse.header("Status"), equalTo("403 Forbidden")); + + // assertThat(uc.getRequestProperty("Accept"), equalTo("application/vnd.github.v3+json")); + + // checkErrorMessageMatches(uc, "Must have push access to repository"); + + // // calling again should still error + // ioEx = Assert.assertThrows(IOException.class, () -> uc.getInputStream()); + + // // calling again on a GitHubConnectorResponse should yield the same value + // if (uc.toString().contains("GitHubConnectorResponseHttpUrlConnectionAdapter")) { + // checkErrorMessageMatches(uc, "Must have push access to repository"); + // } else { + // try (InputStream errorStream = uc.getErrorStream()) { + // assertThat(errorStream, notNullValue()); + // String errorString = IOUtils.toString(errorStream, StandardCharsets.UTF_8); + // fail(); + // } catch (IOException ex) { + // assertThat(ex, notNullValue()); + // assertThat(ex.getMessage(), containsString("stream is closed")); + // } + // } + + // assertThat(uc.getHeaderFields(), instanceOf(Map.class)); + // assertThat(uc.getHeaderFields().size(), greaterThan(25)); + // assertThat(uc.getHeaderField("Status"), equalTo("403 Forbidden")); + + // String key = uc.getHeaderFieldKey(1); + // assertThat(key, notNullValue()); + // assertThat(uc.getHeaderField(1), notNullValue()); + // assertThat(uc.getHeaderField(1), equalTo(uc.getHeaderField(key))); + + // assertThat(uc.getRequestProperty("Accept"), equalTo("application/vnd.github+json")); + + // Assert.assertThrows(IllegalStateException.class, () -> uc.getRequestProperties()); + + // // Actions that are not allowed because connection already opened. + // Assert.assertThrows(IllegalStateException.class, () -> uc.addRequestProperty("bogus", + // "item")); + + // Assert.assertThrows(IllegalStateException.class, () -> uc.setAllowUserInteraction(true)); + // Assert.assertThrows(IllegalStateException.class, () -> uc.setChunkedStreamingMode(1)); + // Assert.assertThrows(IllegalStateException.class, () -> uc.setDoInput(true)); + // Assert.assertThrows(IllegalStateException.class, () -> uc.setDoOutput(true)); + // Assert.assertThrows(IllegalStateException.class, () -> uc.setFixedLengthStreamingMode(1)); + // Assert.assertThrows(IllegalStateException.class, () -> uc.setFixedLengthStreamingMode(1L)); + // Assert.assertThrows(IllegalStateException.class, () -> uc.setIfModifiedSince(1L)); + // Assert.assertThrows(IllegalStateException.class, () -> uc.setRequestProperty("bogus", + // "thing")); + // Assert.assertThrows(IllegalStateException.class, () -> uc.setUseCaches(true)); + + // if (uc.toString().contains("GitHubConnectorResponseHttpUrlConnectionAdapter")) { + + // Assert.assertThrows(UnsupportedOperationException.class, + // () -> uc.getAllowUserInteraction()); + // Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getConnectTimeout()); + // Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getContent()); + // Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getContent(null)); + // Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getDefaultUseCaches()); + // Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getDoInput()); + // Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getDoOutput()); + // Assert.assertThrows(UnsupportedOperationException.class, + // () -> uc.getInstanceFollowRedirects()); + // Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getOutputStream()); + // Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getPermission()); + // Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getReadTimeout()); + // Assert.assertThrows(UnsupportedOperationException.class, () -> uc.getUseCaches()); + // Assert.assertThrows(UnsupportedOperationException.class, () -> uc.usingProxy()); + + // Assert.assertThrows(UnsupportedOperationException.class, () -> uc.setConnectTimeout(10)); + // Assert.assertThrows(UnsupportedOperationException.class, + // () -> uc.setDefaultUseCaches(true)); + + // Assert.assertThrows(UnsupportedOperationException.class, + // () -> uc.setInstanceFollowRedirects(true)); + // Assert.assertThrows(UnsupportedOperationException.class, () -> uc.setReadTimeout(10)); + // Assert.assertThrows(ProtocolException.class, () -> uc.setRequestMethod("GET")); + // } else { + // uc.getDefaultUseCaches(); + // assertThat(uc.getDoInput(), is(true)); + + // // Depending on the underlying implementation, this may throw or not + // // Assert.assertThrows(IllegalStateException.class, () -> uc.setRequestMethod("GET")); + // } + + // // ignored + // uc.connect(); + + // // disconnect does nothing, never throws + // uc.disconnect(); + // uc.disconnect(); + + // // ignored + // uc.connect(); + + GitHubAbuseLimitHandler.FAIL.onError(connectorResponse); } }) .build(); @@ -204,11 +233,6 @@ public void onError(IOException e, HttpURLConnection uc) throws IOException { assertThat(e.getMessage(), equalTo("Abuse limit reached")); } - if (savedConnection[0].toString().contains("GitHubConnectorResponseHttpUrlConnectionAdapter")) { - // error stream is non-null above. null here because response has been closed. - assertThat(savedConnection[0].getErrorStream(), nullValue()); - } - assertThat(mockGitHub.getRequestCount(), equalTo(2)); } @@ -225,7 +249,7 @@ public void testHandler_HttpStatus_Fail() throws Exception { snapshotNotAllowed(); gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withAbuseLimitHandler(AbuseLimitHandler.FAIL) + .withAbuseLimitHandler(GitHubAbuseLimitHandler.FAIL) .build(); gitHub.getMyself(); @@ -258,7 +282,7 @@ public void testHandler_Wait() throws Exception { snapshotNotAllowed(); gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withAbuseLimitHandler(AbuseLimitHandler.WAIT) + .withAbuseLimitHandler(GitHubAbuseLimitHandler.WAIT) .build(); gitHub.getMyself(); @@ -280,9 +304,9 @@ public void testHandler_WaitStuck() throws Exception { snapshotNotAllowed(); gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withAbuseLimitHandler(new AbuseLimitHandler() { + .withAbuseLimitHandler(new GitHubAbuseLimitHandler() { @Override - public void onError(IOException e, HttpURLConnection uc) throws IOException { + public void onError(@NotNull GitHubConnectorResponse connectorResponse) throws IOException { } }) .build(); @@ -311,65 +335,64 @@ public void onError(IOException e, HttpURLConnection uc) throws IOException { public void testHandler_Wait_Secondary_Limits() throws Exception { // Customized response that templates the date to keep things working snapshotNotAllowed(); - final HttpURLConnection[] savedConnection = new HttpURLConnection[1]; + gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withAbuseLimitHandler(new AbuseLimitHandler() { + .withAbuseLimitHandler(new GitHubAbuseLimitHandler() { /** * Overriding method because the actual method will wait for one minute causing slowness in unit * tests */ @Override - public void onError(IOException e, HttpURLConnection uc) throws IOException { - savedConnection[0] = uc; + public void onError(@NotNull GitHubConnectorResponse connectorResponse) throws IOException { // Verify - assertThat(uc.getDate(), Matchers.greaterThanOrEqualTo(new Date().getTime() - 10000)); - assertThat(uc.getExpiration(), equalTo(0L)); - assertThat(uc.getIfModifiedSince(), equalTo(0L)); - assertThat(uc.getLastModified(), equalTo(1581014017000L)); - assertThat(uc.getRequestMethod(), equalTo("GET")); - assertThat(uc.getResponseCode(), equalTo(403)); - assertThat(uc.getResponseMessage(), containsString("Forbidden")); - assertThat(uc.getURL().toString(), + // assertThat(uc.getDate(), Matchers.greaterThanOrEqualTo(new Date().getTime() - 10000)); + // assertThat(uc.getExpiration(), equalTo(0L)); + // assertThat(uc.getIfModifiedSince(), equalTo(0L)); + // assertThat(uc.getLastModified(), equalTo(1581014017000L)); + assertThat(connectorResponse.request().method(), equalTo("GET")); + assertThat(connectorResponse.statusCode(), equalTo(403)); + // assertThat(uc.getResponseMessage(), containsString("Forbidden")); + assertThat(connectorResponse.request().url().toString(), endsWith("/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits")); - assertThat(uc.getHeaderFieldInt("X-RateLimit-Limit", 10), equalTo(5000)); - assertThat(uc.getHeaderFieldInt("X-RateLimit-Remaining", 10), equalTo(4000)); - assertThat(uc.getHeaderFieldInt("X-Foo", 20), equalTo(20)); - assertThat(uc.getHeaderFieldLong("X-RateLimit-Limit", 15L), equalTo(5000L)); - assertThat(uc.getHeaderFieldLong("X-RateLimit-Remaining", 15L), equalTo(4000L)); - assertThat(uc.getHeaderFieldLong("X-Foo", 20L), equalTo(20L)); - assertThat(uc.getHeaderField("gh-limited-by"), equalTo("search-elapsed-time-shared-grouped")); - assertThat(uc.getContentEncoding(), nullValue()); - assertThat(uc.getContentType(), equalTo("application/json; charset=utf-8")); - assertThat(uc.getContentLength(), equalTo(-1)); - assertThat(uc.getHeaderFields(), instanceOf(Map.class)); - assertThat(uc.getHeaderFields().size(), greaterThan(25)); - assertThat(uc.getHeaderField("Status"), equalTo("403 Forbidden")); - - checkErrorMessageMatches(uc, + assertThat(connectorResponse.header("X-RateLimit-Limit"), equalTo("5000")); + assertThat(connectorResponse.header("X-RateLimit-Remaining"), equalTo("4000")); + assertThat(connectorResponse.header("X-Foo"), is(nullValue())); // equalTo(20)); + assertThat(connectorResponse.header("gh-limited-by"), + equalTo("search-elapsed-time-shared-grouped")); + // assertThat(uc.getContentEncoding(), nullValue()); + // assertThat(uc.getContentType(), equalTo("application/json; charset=utf-8")); + // assertThat(uc.getContentLength(), equalTo(-1)); + assertThat(connectorResponse.allHeaders(), instanceOf(Map.class)); + assertThat(connectorResponse.allHeaders().size(), greaterThan(25)); + + assertThat(GitHubAbuseLimitHandler.DEFAULT_WAIT_MILLIS, equalTo(61 * 1000l)); + GitHubAbuseLimitHandler.DEFAULT_WAIT_MILLIS = 3210l; + long waitTime = parseWaitTime(connectorResponse); + assertThat(waitTime, equalTo(GitHubAbuseLimitHandler.DEFAULT_WAIT_MILLIS)); + + assertThat(connectorResponse.header("Status"), equalTo("403 Forbidden")); + + checkErrorMessageMatches(connectorResponse, "You have exceeded a secondary rate limit. Please wait a few minutes before you try again"); - AbuseLimitHandler.FAIL.onError(e, uc); + GitHubAbuseLimitHandler.WAIT.onError(connectorResponse); } }) .build(); gitHub.getMyself(); assertThat(mockGitHub.getRequestCount(), equalTo(1)); - try { - getTempRepository(); - fail(); - } catch (Exception e) { - assertThat(e, instanceOf(HttpException.class)); - assertThat(e.getMessage(), equalTo("Abuse limit reached")); - } - assertThat(mockGitHub.getRequestCount(), equalTo(2)); + + getTempRepository(); + assertThat(mockGitHub.getRequestCount(), equalTo(3)); } /** * This is making an assertion about the behaviour of the mock, so it's useful for making sure we're on the right * mock, but should not be used to validate assumptions about the behaviour of the actual GitHub API. */ - private static void checkErrorMessageMatches(HttpURLConnection uc, String substring) throws IOException { - try (InputStream errorStream = uc.getErrorStream()) { + private static void checkErrorMessageMatches(GitHubConnectorResponse connectorResponse, String substring) + throws IOException { + try (InputStream errorStream = connectorResponse.bodyStream()) { assertThat(errorStream, notNullValue()); String errorString = IOUtils.toString(errorStream, StandardCharsets.UTF_8); assertThat(errorString, containsString(substring)); @@ -387,55 +410,44 @@ private static void checkErrorMessageMatches(HttpURLConnection uc, String substr public void testHandler_Wait_Secondary_Limits_Too_Many_Requests() throws Exception { // Customized response that templates the date to keep things working snapshotNotAllowed(); - final HttpURLConnection[] savedConnection = new HttpURLConnection[1]; gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withAbuseLimitHandler(new AbuseLimitHandler() { + .withAbuseLimitHandler(new GitHubAbuseLimitHandler() { /** * Overriding method because the actual method will wait for one minute causing slowness in unit * tests */ @Override - public void onError(IOException e, HttpURLConnection uc) throws IOException { - savedConnection[0] = uc; + public void onError(@NotNull GitHubConnectorResponse connectorResponse) throws IOException { // Verify the test data is what we expected it to be for this test case - assertThat(uc.getDate(), Matchers.greaterThanOrEqualTo(new Date().getTime() - 10000)); - assertThat(uc.getExpiration(), equalTo(0L)); - assertThat(uc.getIfModifiedSince(), equalTo(0L)); - assertThat(uc.getLastModified(), equalTo(1581014017000L)); - assertThat(uc.getRequestMethod(), equalTo("GET")); - assertThat(uc.getResponseCode(), equalTo(429)); - assertThat(uc.getResponseMessage(), containsString("Many")); - assertThat(uc.getURL().toString(), + // assertThat(uc.getDate(), Matchers.greaterThanOrEqualTo(new Date().getTime() - 10000)); + // assertThat(uc.getExpiration(), equalTo(0L)); + // assertThat(uc.getIfModifiedSince(), equalTo(0L)); + // assertThat(uc.getLastModified(), equalTo(1581014017000L)); + assertThat(connectorResponse.request().method(), equalTo("GET")); + assertThat(connectorResponse.statusCode(), equalTo(429)); + assertThat(connectorResponse.request().url().toString(), endsWith( "/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests")); - assertThat(uc.getContentLength(), equalTo(-1)); - assertThat(uc.getHeaderFields(), instanceOf(Map.class)); - assertThat(uc.getHeaderField("Status"), equalTo("429 Too Many Requests")); - assertThat(uc.getHeaderField("Retry-After"), equalTo("42")); + assertThat(connectorResponse.allHeaders(), instanceOf(Map.class)); + assertThat(connectorResponse.header("Status"), equalTo("429 Too Many Requests")); + assertThat(connectorResponse.header("Retry-After"), equalTo("8")); - checkErrorMessageMatches(uc, + checkErrorMessageMatches(connectorResponse, "You have exceeded a secondary rate limit. Please wait a few minutes before you try again"); - // Because we've overridden onError to bypass the wait, we don't cover the wait calculation - // logic - // Manually invoke it to make sure it's what we intended - long waitTime = parseWaitTime(uc); - assertThat(waitTime, equalTo(42 * 1000l)); - AbuseLimitHandler.FAIL.onError(e, uc); + long waitTime = parseWaitTime(connectorResponse); + assertThat(waitTime, equalTo(8 * 1000l)); + + GitHubAbuseLimitHandler.WAIT.onError(connectorResponse); } }) .build(); gitHub.getMyself(); assertThat(mockGitHub.getRequestCount(), equalTo(1)); - try { - getTempRepository(); - fail(); - } catch (Exception e) { - assertThat(e, instanceOf(HttpException.class)); - assertThat(e.getMessage(), equalTo("Abuse limit reached")); - } - assertThat(mockGitHub.getRequestCount(), equalTo(2)); + + getTempRepository(); + assertThat(mockGitHub.getRequestCount(), equalTo(3)); } /** @@ -448,52 +460,41 @@ public void onError(IOException e, HttpURLConnection uc) throws IOException { public void testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After() throws Exception { // Customized response that templates the date to keep things working snapshotNotAllowed(); - final HttpURLConnection[] savedConnection = new HttpURLConnection[1]; gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withAbuseLimitHandler(new AbuseLimitHandler() { + .withAbuseLimitHandler(new GitHubAbuseLimitHandler() { /** * Overriding method because the actual method will wait for one minute causing slowness in unit * tests */ @Override - public void onError(IOException e, HttpURLConnection uc) throws IOException { - savedConnection[0] = uc; + public void onError(@NotNull GitHubConnectorResponse connectorResponse) throws IOException { // Verify the test data is what we expected it to be for this test case - assertThat(uc.getRequestMethod(), equalTo("GET")); - assertThat(uc.getResponseCode(), equalTo(429)); - assertThat(uc.getResponseMessage(), containsString("Many")); - assertThat(uc.getURL().toString(), + assertThat(connectorResponse.request().method(), equalTo("GET")); + assertThat(connectorResponse.statusCode(), equalTo(429)); + assertThat(connectorResponse.request().url().toString(), endsWith( "/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After")); - assertThat(uc.getContentLength(), equalTo(-1)); - assertThat(uc.getHeaderField("Status"), equalTo("429 Too Many Requests")); - assertThat(uc.getHeaderField("Retry-After"), startsWith("Mon")); + assertThat(connectorResponse.header("Status"), equalTo("429 Too Many Requests")); + assertThat(connectorResponse.header("Retry-After"), containsString("GMT")); - checkErrorMessageMatches(uc, + checkErrorMessageMatches(connectorResponse, "You have exceeded a secondary rate limit. Please wait a few minutes before you try again"); - // Because we've overridden onError to bypass the wait, we don't cover the wait calculation - // logic - // Manually invoke it to make sure it's what we intended - long waitTime = parseWaitTime(uc); - // The exact value here will depend on when the test is run, but it should be positive, and huge - assertThat(waitTime, greaterThan(1000 * 1000l)); + long waitTime = parseWaitTime(connectorResponse); + // The exact value here will depend on when the test is run + assertThat(waitTime, Matchers.lessThan(GitHubAbuseLimitHandler.DEFAULT_WAIT_MILLIS)); + assertThat(waitTime, Matchers.greaterThan(3 * 1000l)); - AbuseLimitHandler.FAIL.onError(e, uc); + GitHubAbuseLimitHandler.WAIT.onError(connectorResponse); } }) .build(); gitHub.getMyself(); assertThat(mockGitHub.getRequestCount(), equalTo(1)); - try { - getTempRepository(); - fail(); - } catch (Exception e) { - assertThat(e, instanceOf(HttpException.class)); - assertThat(e.getMessage(), equalTo("Abuse limit reached")); - } - assertThat(mockGitHub.getRequestCount(), equalTo(2)); + + getTempRepository(); + assertThat(mockGitHub.getRequestCount(), equalTo(3)); } /** @@ -506,53 +507,42 @@ public void onError(IOException e, HttpURLConnection uc) throws IOException { public void testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After() throws Exception { // Customized response that templates the date to keep things working snapshotNotAllowed(); - final HttpURLConnection[] savedConnection = new HttpURLConnection[1]; gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withAbuseLimitHandler(new AbuseLimitHandler() { + .withAbuseLimitHandler(new GitHubAbuseLimitHandler() { /** * Overriding method because the actual method will wait for one minute causing slowness in unit * tests */ @Override - public void onError(IOException e, HttpURLConnection uc) throws IOException { - savedConnection[0] = uc; + public void onError(@NotNull GitHubConnectorResponse connectorResponse) throws IOException { // Verify the test data is what we expected it to be for this test case - assertThat(uc.getRequestMethod(), equalTo("GET")); - assertThat(uc.getResponseCode(), equalTo(429)); - assertThat(uc.getResponseMessage(), containsString("Many")); - assertThat(uc.getURL().toString(), + assertThat(connectorResponse.request().method(), equalTo("GET")); + assertThat(connectorResponse.statusCode(), equalTo(429)); + assertThat(connectorResponse.request().url().toString(), endsWith( "/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After")); - assertThat(uc.getContentEncoding(), nullValue()); - assertThat(uc.getContentType(), equalTo("application/json; charset=utf-8")); - assertThat(uc.getContentLength(), equalTo(-1)); - assertThat(uc.getHeaderFields(), instanceOf(Map.class)); - assertThat(uc.getHeaderField("Status"), equalTo("429 Too Many Requests")); - assertThat(uc.getHeaderField("Retry-After"), nullValue()); - - checkErrorMessageMatches(uc, + // assertThat(uc.getContentEncoding(), nullValue()); + // assertThat(uc.getContentType(), equalTo("application/json; charset=utf-8")); + assertThat(connectorResponse.allHeaders(), instanceOf(Map.class)); + assertThat(connectorResponse.header("Status"), equalTo("429 Too Many Requests")); + assertThat(connectorResponse.header("Retry-After"), nullValue()); + + checkErrorMessageMatches(connectorResponse, "You have exceeded a secondary rate limit. Please wait a few minutes before you try again"); - // Because we've overridden onError to bypass the wait, we don't cover the wait calculation - // logic - // Manually invoke it to make sure it's what we intended - long waitTime = parseWaitTime(uc); - assertThat(waitTime, greaterThan(60000l)); + GitHubAbuseLimitHandler.DEFAULT_WAIT_MILLIS = 3210l; + long waitTime = parseWaitTime(connectorResponse); + assertThat(waitTime, equalTo(GitHubAbuseLimitHandler.DEFAULT_WAIT_MILLIS)); - AbuseLimitHandler.FAIL.onError(e, uc); + GitHubAbuseLimitHandler.WAIT.onError(connectorResponse); } }) .build(); gitHub.getMyself(); assertThat(mockGitHub.getRequestCount(), equalTo(1)); - try { - getTempRepository(); - fail(); - } catch (Exception e) { - assertThat(e, instanceOf(HttpException.class)); - assertThat(e.getMessage(), equalTo("Abuse limit reached")); - } - assertThat(mockGitHub.getRequestCount(), equalTo(2)); + + getTempRepository(); + assertThat(mockGitHub.getRequestCount(), equalTo(3)); } } diff --git a/src/test/java/org/kohsuke/github/AppTest.java b/src/test/java/org/kohsuke/github/AppTest.java index 5f34fb91b5..61c3e3818a 100755 --- a/src/test/java/org/kohsuke/github/AppTest.java +++ b/src/test/java/org/kohsuke/github/AppTest.java @@ -21,7 +21,6 @@ import java.util.stream.Collectors; import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertThrows; // TODO: Auto-generated Javadoc /** @@ -222,10 +221,6 @@ public void testIssueWithComment() throws IOException { ReactionContent.HOORAY, ReactionContent.ROCKET)); - // test retired delete reaction API throws UnsupportedOperationException - final GHReaction reactionToDelete = reaction; - assertThrows(UnsupportedOperationException.class, () -> reactionToDelete.delete()); - // test new delete reaction API v.get(1).deleteReaction(reaction); reaction = null; @@ -322,7 +317,6 @@ public void testGetDeploymentStatuses() throws IOException { try { GHDeploymentStatus ghDeploymentStatus = deployment.createStatus(GHDeploymentState.QUEUED) .description("success") - .targetUrl("http://www.github.com") .logUrl("http://www.github.com/logurl") .environmentUrl("http://www.github.com/envurl") .environment("new-ci-env") @@ -334,9 +328,6 @@ public void testGetDeploymentStatuses() throws IOException { assertThat(actualStatus.getId(), equalTo(ghDeploymentStatus.getId())); assertThat(actualStatus.getState(), equalTo(ghDeploymentStatus.getState())); assertThat(actualStatus.getLogUrl(), equalTo(ghDeploymentStatus.getLogUrl())); - // Target url was deprecated and replaced with log url. The gh api will - // prefer the log url value and return it in place of target url. - assertThat(actualStatus.getLogUrl(), equalTo(ghDeploymentStatus.getTargetUrl())); assertThat(ghDeploymentStatus.getDeploymentUrl(), equalTo(deployment.getUrl())); assertThat(ghDeploymentStatus.getRepositoryUrl(), equalTo(repository.getUrl())); } finally { @@ -452,7 +443,9 @@ private GHRepository getTestRepository() throws IOException { public void testListIssues() throws IOException { Iterable closedIssues = gitHub.getOrganization("hub4j") .getRepository("github-api") - .listIssues(GHIssueState.CLOSED); + .queryIssues() + .state(GHIssueState.CLOSED) + .list(); int x = 0; for (GHIssue issue : closedIssues) { @@ -561,21 +554,6 @@ private boolean shouldBelongToTeam(String organizationName, String teamName) thr return team.hasMember(gitHub.getMyself()); } - /** - * Test fetching team from git hub instance throws exception. - * - * @throws Exception - * the exception - */ - @Test - @SuppressWarnings("deprecation") - public void testFetchingTeamFromGitHubInstanceThrowsException() throws Exception { - GHOrganization organization = gitHub.getOrganization(GITHUB_API_TEST_ORG); - GHTeam teamByName = organization.getTeams().get("Core Developers"); - - assertThrows(UnsupportedOperationException.class, () -> gitHub.getTeam((int) teamByName.getId())); - } - /** * Test should fetch team from organization. * @@ -611,10 +589,9 @@ public void testShouldFetchTeamFromOrganization() throws Exception { @Test public void testFetchPullRequest() throws Exception { GHRepository r = gitHub.getOrganization("jenkinsci").getRepository("jenkins"); - assertThat(r.getMasterBranch(), equalTo("main")); assertThat(r.getDefaultBranch(), equalTo("main")); r.getPullRequest(1); - r.getPullRequests(GHIssueState.OPEN); + r.queryPullRequests().state(GHIssueState.OPEN).list().toList(); } /** @@ -627,8 +604,8 @@ public void testFetchPullRequest() throws Exception { @Test public void testFetchPullRequestAsList() throws Exception { GHRepository r = gitHub.getRepository("hub4j/github-api"); - assertThat(r.getMasterBranch(), equalTo("main")); - PagedIterable i = r.listPullRequests(GHIssueState.CLOSED); + assertThat(r.getDefaultBranch(), equalTo("main")); + PagedIterable i = r.queryPullRequests().state(GHIssueState.CLOSED).list(); List prs = i.toList(); assertThat(prs, notNullValue()); assertThat(prs, is(not(empty()))); @@ -808,7 +785,7 @@ public void testCommit() throws Exception { .getRepository("jenkins") .getCommit("08c1c9970af4d609ae754fbe803e06186e3206f7"); assertThat(commit.getParents().size(), equalTo(1)); - assertThat(commit.getFiles().size(), equalTo(1)); + assertThat(commit.listFiles().toList().size(), equalTo(1)); assertThat(commit.getHtmlUrl().toString(), equalTo("https://github.com/jenkinsci/jenkins/commit/08c1c9970af4d609ae754fbe803e06186e3206f7")); assertThat(commit.getLinesAdded(), equalTo(40)); @@ -822,7 +799,7 @@ public void testCommit() throws Exception { assertThat(commit.getCommitShortInfo().getCommitDate(), equalTo(commit.getCommitDate())); assertThat(commit.getCommitShortInfo().getMessage(), equalTo("creating an RC branch")); - File f = commit.getFiles().get(0); + File f = commit.listFiles().toList().get(0); assertThat(f.getLinesChanged(), equalTo(48)); assertThat(f.getLinesAdded(), equalTo(40)); assertThat(f.getLinesDeleted(), equalTo(8)); @@ -1145,19 +1122,10 @@ private void tryRenaming(GitHub gitHub) throws IOException { private void tryTeamCreation(GitHub gitHub) throws IOException { GHOrganization o = gitHub.getOrganization("HudsonLabs"); - GHTeam t = o.createTeam("auto team", Permission.PUSH); + GHTeam t = o.createTeam("auto team").permission(Permission.PUSH).create(); t.add(o.getRepository("auto-test")); } - private void testPostCommitHook(GitHub gitHub) throws IOException { - GHRepository r = gitHub.getMyself().getRepository("foo"); - Set hooks = r.getPostCommitHooks(); - hooks.add(new URL("http://kohsuke.org/test")); - // System.out.println(hooks); - hooks.remove(new URL("http://kohsuke.org/test")); - // System.out.println(hooks); - } - /** * Test org repositories. * @@ -1403,7 +1371,7 @@ public void testCommitSearch() throws IOException { assertThat(r.getTotalCount(), greaterThan(0)); GHCommit firstCommit = r.iterator().next(); - assertThat(firstCommit.getFiles(), is(not(empty()))); + assertThat(firstCommit.listFiles().toList(), is(not(empty()))); } /** @@ -1594,7 +1562,7 @@ public void testRepoLabel() throws IOException { assertThat("It is dark!", equalTo(t3.getDescription())); // Test deprecated methods - t.setDescription("Deprecated"); + t.set().description("Deprecated"); t = r.getLabel("test"); // By using the old instance t when calling setDescription it also sets color to the old value @@ -1602,7 +1570,7 @@ public void testRepoLabel() throws IOException { assertThat("123456", equalTo(t.getColor())); assertThat("Deprecated", equalTo(t.getDescription())); - t.setColor("000000"); + t.set().color("000000"); t = r.getLabel("test"); assertThat("000000", equalTo(t.getColor())); assertThat("Deprecated", equalTo(t.getDescription())); diff --git a/src/test/java/org/kohsuke/github/ArchTests.java b/src/test/java/org/kohsuke/github/ArchTests.java index a460dc7db8..8ff7d3621f 100644 --- a/src/test/java/org/kohsuke/github/ArchTests.java +++ b/src/test/java/org/kohsuke/github/ArchTests.java @@ -13,10 +13,8 @@ import org.apache.commons.lang3.builder.ReflectionToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; -import org.hamcrest.Matchers; import org.junit.BeforeClass; import org.junit.Test; -import org.kohsuke.github.extras.okhttp3.OkHttpConnector; import java.io.Closeable; import java.io.InputStream; @@ -57,17 +55,6 @@ public class ArchTests { .withImportOption(new ImportOption.DoNotIncludeJars()) .importPackages("org.kohsuke.github"); - private static final DescribedPredicate> previewAnnotationWithNoMediaType = new DescribedPredicate>( - "preview has no required media types defined") { - - @Override - public boolean test(JavaAnnotation javaAnnotation) { - boolean isPreview = javaAnnotation.getRawType().isEquivalentTo(Preview.class); - Object[] values = (Object[]) javaAnnotation.getProperties().get("value"); - return isPreview && values != null && values.length < 1; - } - }; - /** * Before class. */ @@ -94,16 +81,6 @@ public void testRequireUseOfAssertThat() { onlyAssertThatRule.check(testClassFiles); } - /** - * Test api stability. - */ - @Test - public void testApiStability() { - assertThat("OkHttpConnector must implement HttpConnector", - Arrays.asList(OkHttpConnector.class.getInterfaces()), - Matchers.containsInAnyOrder(HttpConnector.class)); - } - /** * Test require use of only specific apache commons. */ diff --git a/src/test/java/org/kohsuke/github/BridgeMethodTest.java b/src/test/java/org/kohsuke/github/BridgeMethodTest.java index f30aea7f8f..3be1c35bb0 100644 --- a/src/test/java/org/kohsuke/github/BridgeMethodTest.java +++ b/src/test/java/org/kohsuke/github/BridgeMethodTest.java @@ -5,11 +5,8 @@ import java.io.IOException; import java.lang.reflect.Method; -import java.net.URL; import java.util.ArrayList; -import java.util.Date; import java.util.List; -import java.util.Set; import javax.annotation.Nonnull; @@ -39,36 +36,6 @@ public void testBridgeMethods() throws IOException { // verifyBridgeMethods(new GHCommit(), "getAuthor", GHCommit.GHAuthor.class, GitUser.class); // verifyBridgeMethods(new GHCommit(), "getCommitter", GHCommit.GHAuthor.class, GitUser.class); - verifyBridgeMethods(GHIssue.class, "getCreatedAt", Date.class, String.class); - verifyBridgeMethods(GHIssue.class, "getId", int.class, long.class, String.class); - verifyBridgeMethods(GHIssue.class, "getUrl", String.class, URL.class); - verifyBridgeMethods(GHIssue.class, "comment", 1, void.class, GHIssueComment.class); - - verifyBridgeMethods(GHOrganization.class, "getHtmlUrl", String.class, URL.class); - verifyBridgeMethods(GHOrganization.class, "getId", int.class, long.class, String.class); - verifyBridgeMethods(GHOrganization.class, "getUrl", String.class, URL.class); - - verifyBridgeMethods(GHRepository.class, "getCollaborators", GHPersonSet.class, Set.class); - verifyBridgeMethods(GHRepository.class, "getHtmlUrl", String.class, URL.class); - verifyBridgeMethods(GHRepository.class, "getId", int.class, long.class, String.class); - verifyBridgeMethods(GHRepository.class, "getUrl", String.class, URL.class); - - verifyBridgeMethods(GHUser.class, "getFollows", GHPersonSet.class, Set.class); - verifyBridgeMethods(GHUser.class, "getFollowers", GHPersonSet.class, Set.class); - verifyBridgeMethods(GHUser.class, "getOrganizations", GHPersonSet.class, Set.class); - verifyBridgeMethods(GHUser.class, "getId", int.class, long.class, String.class); - - verifyBridgeMethods(GHTeam.class, "getId", int.class, long.class, String.class); - - verifyBridgeMethods(GHMemberChanges.FromToPermission.class, - "getTo", - String.class, - GHOrganization.Permission.class); - verifyBridgeMethods(GHMemberChanges.FromToPermission.class, - "getFrom", - String.class, - GHOrganization.Permission.class); - // verifyBridgeMethods(GitHub.class, "getMyself", GHMyself.class, GHUser.class); } diff --git a/src/test/java/org/kohsuke/github/CommitTest.java b/src/test/java/org/kohsuke/github/CommitTest.java index 257e681cca..1877c87b26 100644 --- a/src/test/java/org/kohsuke/github/CommitTest.java +++ b/src/test/java/org/kohsuke/github/CommitTest.java @@ -43,7 +43,7 @@ public void getFiles() throws Exception { PagedIterable commits = repo.queryCommits().path("pom.xml").list(); for (GHCommit commit : Iterables.limit(commits, 10)) { GHCommit expected = repo.getCommit(commit.getSHA1()); - assertThat(commit.getFiles().size(), equalTo(expected.getFiles().size())); + assertThat(commit.listFiles().toList().size(), equalTo(expected.listFiles().toList().size())); } } diff --git a/src/test/java/org/kohsuke/github/EnumTest.java b/src/test/java/org/kohsuke/github/EnumTest.java index 02ab6d912d..778df77bf4 100644 --- a/src/test/java/org/kohsuke/github/EnumTest.java +++ b/src/test/java/org/kohsuke/github/EnumTest.java @@ -1,7 +1,6 @@ package org.kohsuke.github; import org.junit.Test; -import org.kohsuke.github.internal.Previews; import static org.hamcrest.CoreMatchers.*; @@ -18,10 +17,6 @@ public class EnumTest extends AbstractGitHubWireMockTest { */ @Test public void touchEnums() { - // Previews is deprecated but we want to maintain coverage until we remove it - assertThat(Previews.values().length, equalTo(16)); - assertThat(Previews.ANTIOPE.mediaType(), equalTo("application/vnd.github.antiope-preview+json")); - assertThat(GHCheckRun.AnnotationLevel.values().length, equalTo(3)); assertThat(GHCheckRun.Conclusion.values().length, equalTo(9)); assertThat(GHCheckRun.Status.values().length, equalTo(4)); @@ -89,7 +84,7 @@ public void touchEnums() { assertThat(GHPullRequestReviewEvent.PENDING.toState(), equalTo(GHPullRequestReviewState.PENDING)); assertThat(GHPullRequestReviewEvent.PENDING.action(), nullValue()); - assertThat(GHPullRequestReviewState.values().length, equalTo(6)); + assertThat(GHPullRequestReviewState.values().length, equalTo(5)); assertThat(GHPullRequestReviewState.PENDING.toEvent(), equalTo(GHPullRequestReviewEvent.PENDING)); assertThat(GHPullRequestReviewState.APPROVED.action(), equalTo(GHPullRequestReviewEvent.APPROVE.action())); assertThat(GHPullRequestReviewState.DISMISSED.toEvent(), nullValue()); @@ -105,8 +100,6 @@ public void touchEnums() { assertThat(GHRepositoryDiscussion.State.values().length, equalTo(3)); assertThat(GHRepositorySearchBuilder.Sort.values().length, equalTo(3)); - assertThat(GHRepositorySearchBuilder.Fork.values().length, equalTo(3)); - assertThat(GHRepositorySearchBuilder.Fork.PARENT_ONLY.toString(), equalTo("")); assertThat(GHRepositorySelection.values().length, equalTo(2)); diff --git a/src/test/java/org/kohsuke/github/GHAppTest.java b/src/test/java/org/kohsuke/github/GHAppTest.java index 2ceb479e4b..431dd13037 100644 --- a/src/test/java/org/kohsuke/github/GHAppTest.java +++ b/src/test/java/org/kohsuke/github/GHAppTest.java @@ -14,7 +14,6 @@ import java.util.TimeZone; import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertThrows; // TODO: Auto-generated Javadoc /** @@ -32,7 +31,7 @@ public class GHAppTest extends AbstractGHAppInstallationTest { protected GitHubBuilder getGitHubBuilder() { return super.getGitHubBuilder() // ensure that only JWT will be used against the tests below - .withPassword(null, null) + .withOAuthToken(null, null) // Note that we used to provide a bogus token here and to rely on (apparently) manually crafted/edited // Wiremock recordings, so most of the tests cannot actually be executed against GitHub without // relying on the Wiremock recordings. @@ -62,15 +61,6 @@ public void getGitHubApp() throws IOException { assertThat(app.getPermissions().size(), is(2)); assertThat(app.getEvents().size(), is(0)); assertThat(app.getInstallationsCount(), is((long) 1)); - - // Deprecated methods - assertThrows(RuntimeException.class, () -> app.setDescription("")); - assertThrows(RuntimeException.class, () -> app.setEvents(null)); - assertThrows(RuntimeException.class, () -> app.setExternalUrl("")); - assertThrows(RuntimeException.class, () -> app.setInstallationsCount(1)); - assertThrows(RuntimeException.class, () -> app.setName("")); - assertThrows(RuntimeException.class, () -> app.setOwner(null)); - assertThrows(RuntimeException.class, () -> app.setPermissions(null)); } /** @@ -198,8 +188,7 @@ public void createToken() throws IOException { permissions.put("metadata", GHPermissionType.READ); // Create token specifying both permissions and repository ids - GHAppInstallationToken installationToken = installation.createToken() - .permissions(permissions) + GHAppInstallationToken installationToken = installation.createToken(permissions) .repositoryIds(Collections.singletonList((long) 111111111)) .create(); @@ -208,13 +197,6 @@ public void createToken() throws IOException { assertThat(installationToken.getRepositorySelection(), is(GHRepositorySelection.SELECTED)); assertThat(installationToken.getExpiresAt(), is(GitHubClient.parseDate("2019-08-10T05:54:58Z"))); - // Deprecated methods - assertThrows(RuntimeException.class, () -> installationToken.setPermissions(null)); - assertThrows(RuntimeException.class, () -> installationToken.setRoot(null)); - assertThrows(RuntimeException.class, () -> installationToken.setRepositorySelection(null)); - assertThrows(RuntimeException.class, () -> installationToken.setRepositories(null)); - assertThrows(RuntimeException.class, () -> installationToken.setPermissions(null)); - GHRepository repository = installationToken.getRepositories().get(0); assertThat(installationToken.getRepositories().size(), is(1)); assertThat(repository.getId(), is((long) 111111111)); @@ -272,19 +254,6 @@ private void testAppInstallation(GHAppInstallation appInstallation) throws IOExc assertThat(appInstallation.getTargetId(), is((long) 111111111)); assertThat(appInstallation.getTargetType(), is(GHTargetType.ORGANIZATION)); - // Deprecated methods - assertThrows(RuntimeException.class, () -> appInstallation.setAccessTokenUrl("")); - assertThrows(RuntimeException.class, () -> appInstallation.setAccount(null)); - assertThrows(RuntimeException.class, () -> appInstallation.setAppId(0)); - assertThrows(RuntimeException.class, () -> appInstallation.setEvents(null)); - assertThrows(RuntimeException.class, () -> appInstallation.setPermissions(null)); - assertThrows(RuntimeException.class, () -> appInstallation.setRepositorySelection(null)); - assertThrows(RuntimeException.class, () -> appInstallation.setRepositoriesUrl(null)); - assertThrows(RuntimeException.class, () -> appInstallation.setRoot(null)); - assertThrows(RuntimeException.class, () -> appInstallation.setSingleFileName("")); - assertThrows(RuntimeException.class, () -> appInstallation.setTargetId(0)); - assertThrows(RuntimeException.class, () -> appInstallation.setTargetType(null)); - Map permissionsMap = new HashMap(); permissionsMap.put("checks", GHPermissionType.WRITE); permissionsMap.put("pull_requests", GHPermissionType.WRITE); diff --git a/src/test/java/org/kohsuke/github/GHBranchProtectionTest.java b/src/test/java/org/kohsuke/github/GHBranchProtectionTest.java index bee19e8e0c..17d7d85f01 100755 --- a/src/test/java/org/kohsuke/github/GHBranchProtectionTest.java +++ b/src/test/java/org/kohsuke/github/GHBranchProtectionTest.java @@ -51,7 +51,7 @@ public void setUp() throws Exception { public void testEnableBranchProtections() throws Exception { // team/user restrictions require an organization repo to test against GHBranchProtection protection = branch.enableProtection() - .addRequiredChecks("test-status-check") + .addRequiredChecks(new GHBranchProtection.Check("test-status-check", null)) .requireBranchIsUpToDate() .requireCodeOwnReviews() .requireLastPushApproval() diff --git a/src/test/java/org/kohsuke/github/GHContentIntegrationTest.java b/src/test/java/org/kohsuke/github/GHContentIntegrationTest.java index c663dc1b32..a9d330ba5b 100644 --- a/src/test/java/org/kohsuke/github/GHContentIntegrationTest.java +++ b/src/test/java/org/kohsuke/github/GHContentIntegrationTest.java @@ -2,19 +2,17 @@ import org.apache.commons.io.IOUtils; import org.junit.After; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; import java.util.List; import static org.hamcrest.Matchers.*; +import static org.junit.Assert.assertThrows; // TODO: Auto-generated Javadoc /** @@ -70,8 +68,6 @@ public void setUp() throws Exception { public void testGetRepository() throws Exception { GHRepository testRepo = gitHub.getRepositoryById(repo.getId()); assertThat(testRepo.getName(), equalTo(repo.getName())); - testRepo = gitHub.getRepositoryById(Long.toString(repo.getId())); - assertThat(testRepo.getName(), equalTo(repo.getName())); } /** @@ -152,9 +148,11 @@ public void testGetDirectoryContentTrailingSlash() throws Exception { */ @Test public void testCRUDContent() throws Exception { - GHContentUpdateResponse created = repo.createContent("this is an awesome file I created\n", - "Creating a file for integration tests.", - createdFilename); + GHContentUpdateResponse created = repo.createContent() + .content("this is an awesome file I created\n") + .message("Creating a file for integration tests.") + .path(createdFilename) + .commit(); int expectedRequestCount = mockGitHub.getRequestCount(); GHContent createdContent = created.getContent(); @@ -246,7 +244,7 @@ int checkCreatedCommits(GitCommit gitCommit, GHCommit ghCommit, int expectedRequ assertThat(ghCommit.getCommitShortInfo().getMessage(), equalTo("Creating a file for integration tests.")); assertThat("Message already resolved", mockGitHub.getRequestCount(), equalTo(expectedRequestCount)); - Assert.assertThrows(GHException.class, () -> ghCommit.getCommitShortInfo().getCommentCount()); + assertThrows(GHException.class, () -> ghCommit.getCommitShortInfo().getCommentCount()); ghCommit.populate(); assertThat("Populate GHCommit", mockGitHub.getRequestCount(), equalTo(expectedRequestCount += 1)); @@ -271,13 +269,7 @@ int checkCreatedCommits(GitCommit gitCommit, GHCommit ghCommit, int expectedRequ * the exception */ GHCommit getGHCommit(GHContentUpdateResponse resp) throws Exception { - for (Method method : resp.getClass().getMethods()) { - if (method.getName().equals("getCommit") && method.getReturnType().equals(GHCommit.class)) { - return (GHCommit) method.invoke(resp); - } - } - System.out.println("Unable to find bridge method"); - return null; + return resp.getCommit().toGHCommit(); } /** @@ -340,7 +332,6 @@ int checkBasicCommitInfo(GitCommit gitCommit, GHCommit ghCommit, int expectedReq equalTo("https://github.com/hub4j-test-org/GHContentIntegrationTest/commit/" + gitCommit.getSHA1())); assertThat(gitCommit.getVerification(), notNullValue()); - assertThat(ghCommit, notNullValue()); assertThat(ghCommit.getSHA1(), notNullValue()); assertThat(ghCommit.getUrl().toString(), endsWith("/repos/hub4j-test-org/GHContentIntegrationTest/git/commits/" + ghCommit.getSHA1())); @@ -365,10 +356,6 @@ int checkCommitUserInfo(GitCommit gitCommit, GHCommit ghCommit, int expectedRequ assertThat(gitCommit.getAuthor().getName(), equalTo("Liam Newman")); assertThat(gitCommit.getAuthor().getEmail(), equalTo("bitwiseman@gmail.com")); - // Check that GHCommit.GHAuthor bridge method still works - assertThat(getGHAuthor(gitCommit).getName(), equalTo("Liam Newman")); - assertThat(getGHAuthor(gitCommit).getEmail(), equalTo("bitwiseman@gmail.com")); - assertThat(gitCommit.getAuthor().getName(), equalTo("Liam Newman")); assertThat(gitCommit.getAuthor().getEmail(), equalTo("bitwiseman@gmail.com")); assertThat(gitCommit.getCommitter().getName(), equalTo("Liam Newman")); @@ -378,68 +365,12 @@ int checkCommitUserInfo(GitCommit gitCommit, GHCommit ghCommit, int expectedRequ assertThat(ghCommit.getAuthor().getName(), equalTo("Liam Newman")); assertThat(ghCommit.getAuthor().getEmail(), equalTo("bitwiseman@gmail.com")); - // Check that GHCommit.GHAuthor bridge method still works - assertThat(getGHAuthor(ghCommit.getCommitShortInfo()).getName(), equalTo("Liam Newman")); - assertThat(getGHAuthor(ghCommit.getCommitShortInfo()).getEmail(), equalTo("bitwiseman@gmail.com")); - assertThat(ghCommit.getCommitter().getName(), equalTo("Liam Newman")); assertThat(ghCommit.getCommitter().getEmail(), equalTo("bitwiseman@gmail.com")); return expectedRequestCount; } - /** - * Gets the GH author. - * - * @param commit - * the commit - * @return the GH author - * @throws GHException - * the GH exception - * @throws IllegalAccessException - * the illegal access exception - * @throws IllegalArgumentException - * the illegal argument exception - * @throws InvocationTargetException - * the invocation target exception - */ - GHCommit.GHAuthor getGHAuthor(GitCommit commit) - throws GHException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - for (Method method : commit.getClass().getMethods()) { - if (method.getName().equals("getAuthor") && method.getReturnType().equals(GHCommit.GHAuthor.class)) { - return (GHCommit.GHAuthor) method.invoke(commit); - } - } - System.out.println("Unable to find bridge method"); - return null; - } - - /** - * Gets the GH author. - * - * @param commit - * the commit - * @return the GH author - * @throws GHException - * the GH exception - * @throws IllegalAccessException - * the illegal access exception - * @throws IllegalArgumentException - * the illegal argument exception - * @throws InvocationTargetException - * the invocation target exception - */ - GHCommit.GHAuthor getGHAuthor(GHCommit.ShortInfo commit) - throws GHException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - for (Method method : commit.getClass().getMethods()) { - if (method.getName().equals("getAuthor") && method.getReturnType().equals(GHCommit.GHAuthor.class)) { - return (GHCommit.GHAuthor) method.invoke(commit); - } - } - System.out.println("Unable to find bridge method"); - return null; - } - /** * Check commit tree. * @@ -485,9 +416,10 @@ int checkCommitTree(GitCommit gitCommit, GHCommit ghCommit, int expectedRequestC */ int checkCommitParents(GitCommit gitCommit, GHCommit ghCommit, int expectedRequestCount) throws IOException { assertThat(gitCommit.getParentSHA1s().size(), is(greaterThan(0))); - assertThat(ghCommit.getParentSHA1s().size(), is(greaterThan(0))); assertThat(gitCommit.getParentSHA1s().get(0), notNullValue()); + assertThat(ghCommit.getParentSHA1s().size(), is(greaterThan(0))); assertThat(ghCommit.getParentSHA1s().get(0), notNullValue()); + return expectedRequestCount; } diff --git a/src/test/java/org/kohsuke/github/GHEventPayloadTest.java b/src/test/java/org/kohsuke/github/GHEventPayloadTest.java index 1e1513c2e0..638e60f18b 100644 --- a/src/test/java/org/kohsuke/github/GHEventPayloadTest.java +++ b/src/test/java/org/kohsuke/github/GHEventPayloadTest.java @@ -63,13 +63,6 @@ public void commit_comment() throws Exception { assertThat(event.getSender().getLogin(), is("baxterthehacker")); assertThat(event.getComment().getOwner(), sameInstance(event.getRepository())); - - assertThrows(RuntimeException.class, () -> event.setComment(null)); - - // EventPayload checks - assertThrows(RuntimeException.class, () -> event.setOrganization(null)); - assertThrows(RuntimeException.class, () -> event.setRepository(null)); - assertThrows(RuntimeException.class, () -> event.setSender(null)); } /** @@ -139,7 +132,7 @@ public void deployment_status() throws Exception { final GHEventPayload.DeploymentStatus event = GitHub.offline() .parseEventPayload(payload.asReader(), GHEventPayload.DeploymentStatus.class); assertThat(event.getDeploymentStatus().getState(), is(GHDeploymentState.SUCCESS)); - assertThat(event.getDeploymentStatus().getTargetUrl(), nullValue()); + assertThat(event.getDeploymentStatus().getLogUrl(), nullValue()); assertThat(event.getDeployment().getSha(), is("9049f1265b7d61be4a8904a9a27120d2064dab3b")); assertThat(event.getDeployment().getEnvironment(), is("production")); assertThat(event.getDeployment().getCreator().getLogin(), is("baxterthehacker")); @@ -149,9 +142,6 @@ public void deployment_status() throws Exception { assertThat(event.getDeployment().getOwner(), sameInstance(event.getRepository())); assertThat(event.getDeploymentStatus().getOwner(), sameInstance(event.getRepository())); - - assertThrows(RuntimeException.class, () -> event.setDeployment(null)); - assertThrows(RuntimeException.class, () -> event.setDeploymentStatus(null)); } /** @@ -169,8 +159,6 @@ public void fork() throws Exception { assertThat(event.getRepository().getName(), is("public-repo")); assertThat(event.getRepository().getOwner().getLogin(), is("baxterthehacker")); assertThat(event.getSender().getLogin(), is("baxterandthehackers")); - - assertThrows(RuntimeException.class, () -> event.setForkee(null)); } // TODO uncomment when we have GHPage implemented @@ -215,9 +203,6 @@ public void issue_comment() throws Exception { assertThat(event.getIssue().getRepository(), sameInstance(event.getRepository())); assertThat(event.getComment().getParent(), sameInstance(event.getIssue())); - - assertThrows(RuntimeException.class, () -> event.setComment(null)); - assertThrows(RuntimeException.class, () -> event.setIssue(null)); } /** @@ -649,11 +634,6 @@ public void push() throws Exception { assertThat(event.getSender().getLogin(), is("baxterthehacker")); assertThat(event.getCompare(), is("https://github.com/baxterthehacker/public-repo/compare/9049f1265b7d...0d1a26e67d8f")); - - assertThrows(RuntimeException.class, () -> event.setPusher(null)); - assertThrows(RuntimeException.class, () -> event.getPusher().setEmail(null)); - assertThrows(RuntimeException.class, () -> event.getPusher().setName(null)); - } /** @@ -751,8 +731,6 @@ public void release_published() throws Exception { assertThat(event.getRelease().getName(), is("4.2")); assertThat(event.getRelease().getTagName(), is("rest-api-framework-4.2")); assertThat(event.getRelease().getBody(), is("REST-269 - unique test executions (#86) Sergey Chernov")); - - assertThrows(RuntimeException.class, () -> event.setRelease(null)); } /** @@ -840,9 +818,6 @@ public void status() throws Exception { assertThat(event.getRepository().getOwner().getLogin(), is("baxterthehacker")); assertThat(event.getTargetUrl(), nullValue()); assertThat(event.getCommit().getOwner(), sameInstance(event.getRepository())); - - assertThrows(RuntimeException.class, () -> event.setCommit(null)); - assertThrows(RuntimeException.class, () -> event.setState(GHCommitState.ERROR)); } /** @@ -903,8 +878,6 @@ private GHCheckRun verifyBasicCheckRunEvent(final GHEventPayload.CheckRun event) assertThat(event.getRepository().getOwner().getLogin(), is("Codertocat")); assertThat(event.getAction(), is("created")); assertThat(event.getRequestedAction(), nullValue()); - assertThrows(RuntimeException.class, () -> event.setCheckRun(null)); - assertThrows(RuntimeException.class, () -> event.setRequestedAction(null)); // Checks the deserialization of check_run final GHCheckRun checkRun = event.getCheckRun(); diff --git a/src/test/java/org/kohsuke/github/GHHookTest.java b/src/test/java/org/kohsuke/github/GHHookTest.java index 247505fb1d..f129d132a9 100644 --- a/src/test/java/org/kohsuke/github/GHHookTest.java +++ b/src/test/java/org/kohsuke/github/GHHookTest.java @@ -1,6 +1,6 @@ package org.kohsuke.github; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.junit.Ignore; import org.junit.Test; @@ -42,7 +42,7 @@ public void exposeResponceHeaders() throws Exception { String orgRepo = "KostyaSha-org/test"; // some login based user that has access to application - final GitHub gitHub = GitHub.connectUsingPassword(user1Login, user1Pass); + final GitHub gitHub = GitHub.connect(user1Login, user1Pass); gitHub.getMyself(); // we request read diff --git a/src/test/java/org/kohsuke/github/GHIssueTest.java b/src/test/java/org/kohsuke/github/GHIssueTest.java index a0416f4de7..bcdddea659 100644 --- a/src/test/java/org/kohsuke/github/GHIssueTest.java +++ b/src/test/java/org/kohsuke/github/GHIssueTest.java @@ -339,7 +339,7 @@ public void getUserTest() throws IOException { GHIssue issueSingle = getRepository().getIssue(issue.getNumber()); assertThat(issueSingle.getUser().root(), notNullValue()); - PagedIterable ghIssues = getRepository().listIssues(GHIssueState.OPEN); + PagedIterable ghIssues = getRepository().queryIssues().state(GHIssueState.OPEN).list(); for (GHIssue otherIssue : ghIssues) { assertThat(otherIssue.getUser().root(), notNullValue()); } diff --git a/src/test/java/org/kohsuke/github/GHMarketplacePlanTest.java b/src/test/java/org/kohsuke/github/GHMarketplacePlanTest.java index 90e697ce37..d95ef2b0f9 100644 --- a/src/test/java/org/kohsuke/github/GHMarketplacePlanTest.java +++ b/src/test/java/org/kohsuke/github/GHMarketplacePlanTest.java @@ -28,7 +28,7 @@ public class GHMarketplacePlanTest extends AbstractGitHubWireMockTest { protected GitHubBuilder getGitHubBuilder() { return super.getGitHubBuilder() // ensure that only JWT will be used against the tests below - .withPassword(null, null) + .withOAuthToken(null, null) .withJwtToken("bogus"); } diff --git a/src/test/java/org/kohsuke/github/GHOrganizationTest.java b/src/test/java/org/kohsuke/github/GHOrganizationTest.java index fcafc97aa9..71e5cad586 100644 --- a/src/test/java/org/kohsuke/github/GHOrganizationTest.java +++ b/src/test/java/org/kohsuke/github/GHOrganizationTest.java @@ -138,14 +138,13 @@ public void testCreateRepositoryWithParameterIsTemplate() throws IOException { repository = org.getRepository(GITHUB_API_TEMPLATE_TEST); - // first isTemplate() calls populate() + // first isTemplate() does not call populate() assertThat(repository.isTemplate(), equalTo(true)); assertThat(mockGitHub.getRequestCount(), equalTo(requestCount + 3)); // second isTemplate() does not call populate() assertThat(repository.isTemplate(), equalTo(true)); assertThat(mockGitHub.getRequestCount(), equalTo(requestCount + 3)); - } /** @@ -427,7 +426,10 @@ public void testCreateTeamWithRepoAccess() throws IOException { GHRepository repo = org.getRepository(REPO_NAME); // Create team with access to repository. Check access was granted. - GHTeam team = org.createTeam(TEAM_NAME_CREATE, Permission.PUSH, repo); + GHTeam team = org.createTeam(TEAM_NAME_CREATE) + .repositories(repo.getFullName()) + .permission(Permission.PUSH) + .create(); assertThat(team.getRepositories().containsKey(REPO_NAME), is(true)); assertThat(team.getPermission(), equalTo(Permission.PUSH.toString().toLowerCase())); } @@ -476,7 +478,7 @@ public void testCreateTeamWithRepoPerm() throws Exception { // Create team with access to repository. Check access was granted. GHTeam team = org.createTeam(TEAM_NAME_CREATE).create(); - team.add(repo, Permission.PUSH); + team.add(repo, GHOrganization.RepositoryRole.from(Permission.PUSH)); assertThat( repo.getTeams() @@ -534,7 +536,7 @@ public void testCreateTeam() throws IOException { GHRepository repo = org.getRepository(REPO_NAME); // Create team with no permission field. Verify that default permission is pull - GHTeam team = org.createTeam(TEAM_NAME_CREATE, repo); + GHTeam team = org.createTeam(TEAM_NAME_CREATE).repositories(repo.getFullName()).create(); assertThat(team.getRepositories().containsKey(REPO_NAME), is(true)); assertThat(team.getPermission(), equalTo(DEFAULT_PERMISSION)); } diff --git a/src/test/java/org/kohsuke/github/GHPullRequestTest.java b/src/test/java/org/kohsuke/github/GHPullRequestTest.java index c1e94336f8..664f447b16 100644 --- a/src/test/java/org/kohsuke/github/GHPullRequestTest.java +++ b/src/test/java/org/kohsuke/github/GHPullRequestTest.java @@ -48,7 +48,10 @@ public void cleanUp() throws Exception { return; } - for (GHPullRequest pr : getRepository(this.getNonRecordingGitHub()).getPullRequests(GHIssueState.OPEN)) { + for (GHPullRequest pr : getRepository(this.getNonRecordingGitHub()).queryPullRequests() + .state(GHIssueState.OPEN) + .list() + .toList()) { pr.close(); } } @@ -663,7 +666,7 @@ public void squashMerge() throws Exception { GHRef mainRef = getRepository().getRef("heads/main"); GHRef branchRef = getRepository().createRef("refs/heads/" + branchName, mainRef.getObject().getSha()); - getRepository().createContent(name, name, name, branchName); + getRepository().createContent().content(name).path(name).message(name).branch(branchName).commit(); Thread.sleep(1000); GHPullRequest p = getRepository().createPullRequest(name, branchName, "main", "## test squash"); Thread.sleep(1000); @@ -684,7 +687,13 @@ public void updateContentSquashMerge() throws Exception { GHRef mainRef = getRepository().getRef("heads/main"); GHRef branchRef = getRepository().createRef("refs/heads/" + branchName, mainRef.getObject().getSha()); - GHContentUpdateResponse response = getRepository().createContent(name, name, name, branchName); + GHContentUpdateResponse response = getRepository().createContent() + .content(name) + .path(name) + .branch(branchName) + .message(name) + .commit(); + Thread.sleep(1000); getRepository().createContent() @@ -903,7 +912,9 @@ public void getUserTest() throws IOException { prSingle.getMergeable(); assertThat(prSingle.getUser().root(), notNullValue()); - PagedIterable ghPullRequests = getRepository().listPullRequests(GHIssueState.OPEN); + PagedIterable ghPullRequests = getRepository().queryPullRequests() + .state(GHIssueState.OPEN) + .list(); for (GHPullRequest pr : ghPullRequests) { assertThat(pr.getUser().root(), notNullValue()); pr.getMergeable(); diff --git a/src/test/java/org/kohsuke/github/GHRateLimitTest.java b/src/test/java/org/kohsuke/github/GHRateLimitTest.java index 7d3001b7a4..5ec59ebb50 100644 --- a/src/test/java/org/kohsuke/github/GHRateLimitTest.java +++ b/src/test/java/org/kohsuke/github/GHRateLimitTest.java @@ -245,11 +245,6 @@ private void verifyRateLimitValues(GHRateLimit previousLimit, int remaining, boo assertThat(rateLimit.getCore().getRemaining(), equalTo(rateLimit.getRemaining())); assertThat(rateLimit.getCore().getResetEpochSeconds(), equalTo(rateLimit.getResetEpochSeconds())); assertThat(rateLimit.getCore().getResetDate(), equalTo(rateLimit.getResetDate())); - - // Additional checks for deprecated values - assertThat(rateLimit.limit, equalTo(rateLimit.getLimit())); - assertThat(rateLimit.remaining, equalTo(rateLimit.getRemaining())); - assertThat(rateLimit.reset.getTime(), equalTo(rateLimit.getResetEpochSeconds())); } /** @@ -274,7 +269,7 @@ public void testGitHubEnterpriseDoesNotHaveRateLimit() throws Exception { // ------------------------------------------------------------- // Before any queries, rate limit starts as default but may be requested - gitHub = GitHub.connectToEnterprise(mockGitHub.apiServer().baseUrl(), "bogus", "bogus"); + gitHub = GitHub.connectToEnterpriseWithOAuth(mockGitHub.apiServer().baseUrl(), "bogus", "bogus"); assertThat(mockGitHub.getRequestCount(), equalTo(0)); assertThat(gitHub.lastRateLimit(), sameInstance(GHRateLimit.DEFAULT)); @@ -300,7 +295,7 @@ public void testGitHubEnterpriseDoesNotHaveRateLimit() throws Exception { // ------------------------------------------------------------- // Some versions of GHE include header rate limit information, some do not // This response mocks the behavior without header rate limit information - gitHub = GitHub.connectToEnterprise(mockGitHub.apiServer().baseUrl(), "bogus", "bogus"); + gitHub = GitHub.connectToEnterpriseWithOAuth(mockGitHub.apiServer().baseUrl(), "bogus", "bogus"); gitHub.getMyself(); assertThat(mockGitHub.getRequestCount(), equalTo(2)); @@ -344,7 +339,7 @@ public void testGitHubEnterpriseDoesNotHaveRateLimit() throws Exception { // ------------------------------------------------------------- // Some versions of GHE include header rate limit information, some do not // This response mocks the behavior with header rate limit information - gitHub = GitHub.connectToEnterprise(mockGitHub.apiServer().baseUrl(), "bogus", "bogus"); + gitHub = GitHub.connectToEnterpriseWithOAuth(mockGitHub.apiServer().baseUrl(), "bogus", "bogus"); gitHub.getMyself(); assertThat(mockGitHub.getRequestCount(), equalTo(5)); diff --git a/src/test/java/org/kohsuke/github/GHRepositoryTest.java b/src/test/java/org/kohsuke/github/GHRepositoryTest.java index d387c93cb6..645f3e44cb 100644 --- a/src/test/java/org/kohsuke/github/GHRepositoryTest.java +++ b/src/test/java/org/kohsuke/github/GHRepositoryTest.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.JsonMappingException; import com.google.common.collect.Sets; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; @@ -129,7 +130,6 @@ public void testGetters() throws IOException { String httpTransport = "https://github.com/hub4j-test-org/temp-testGetters.git"; assertThat(r.getHttpTransportUrl(), equalTo(httpTransport)); - assertThat(r.gitHttpTransportUrl(), equalTo(httpTransport)); assertThat(r.getName(), equalTo("temp-testGetters")); assertThat(r.getFullName(), equalTo("hub4j-test-org/temp-testGetters")); @@ -251,7 +251,7 @@ public void createSignedCommitUnknownSignatureType() throws IOException { @Test public void listStargazers() throws IOException { GHRepository repository = getRepository(); - assertThat(repository.listStargazers2().toList(), is(empty())); + assertThat(repository.listStargazers().toList(), is(empty())); repository = gitHub.getOrganization("hub4j").getRepository("github-api"); Iterable stargazers = repository.listStargazers2(); @@ -599,7 +599,7 @@ public void addCollaborators() throws Exception { users.add(user); users.add(gitHub.getUser("jimmysombrero2")); - repo.addCollaborators(users, GHOrganization.Permission.PUSH); + repo.addCollaborators(users, RepositoryRole.from(GHOrganization.Permission.PUSH)); GHPersonSet collabs = repo.getCollaborators(); GHUser colabUser = collabs.byLogin("jimmysombrero"); @@ -817,42 +817,6 @@ public void ghRepositorySearchBuilderForkDefaultResetForksSearchTerms() { assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:")).count(), is(0L)); } - /** - * Gh repository search builder fork deprecated enum. - */ - @Test - public void ghRepositorySearchBuilderForkDeprecatedEnum() { - GHRepositorySearchBuilder ghRepositorySearchBuilder = new GHRepositorySearchBuilder(gitHub); - ghRepositorySearchBuilder = ghRepositorySearchBuilder.fork(GHRepositorySearchBuilder.Fork.PARENT_AND_FORKS); - assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:true")).count(), is(1L)); - assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:")).count(), is(1L)); - - ghRepositorySearchBuilder = ghRepositorySearchBuilder.fork(GHRepositorySearchBuilder.Fork.FORKS_ONLY); - assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:only")).count(), is(1L)); - assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:")).count(), is(2L)); - - ghRepositorySearchBuilder = ghRepositorySearchBuilder.fork(GHRepositorySearchBuilder.Fork.PARENT_ONLY); - assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:")).count(), is(0L)); - } - - /** - * Gh repository search builder fork deprecated string. - */ - @Test - public void ghRepositorySearchBuilderForkDeprecatedString() { - GHRepositorySearchBuilder ghRepositorySearchBuilder = new GHRepositorySearchBuilder(gitHub); - ghRepositorySearchBuilder = ghRepositorySearchBuilder.forks(GHFork.PARENT_AND_FORKS.toString()); - assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:true")).count(), is(1L)); - assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:")).count(), is(1L)); - - ghRepositorySearchBuilder = ghRepositorySearchBuilder.forks(GHFork.FORKS_ONLY.toString()); - assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:only")).count(), is(1L)); - assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:")).count(), is(2L)); - - ghRepositorySearchBuilder = ghRepositorySearchBuilder.forks(null); - assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:")).count(), is(0L)); - } - /** * List commit comments some comments. * @@ -1098,10 +1062,66 @@ public void getCollaborators() throws Exception { @Test public void getPostCommitHooks() throws Exception { GHRepository repo = getRepository(gitHub); - Set postcommitHooks = repo.getPostCommitHooks(); + Set postcommitHooks = setupPostCommitHooks(repo); assertThat(postcommitHooks, is(empty())); } + @SuppressFBWarnings(value = "DMI_COLLECTION_OF_URLS", + justification = "It causes a performance degradation, but we have already exposed it to the API") + private Set setupPostCommitHooks(final GHRepository repo) { + return new AbstractSet() { + private List getPostCommitHooks() { + try { + List r = new ArrayList<>(); + for (GHHook h : repo.getHooks()) { + if (h.getName().equals("web")) { + r.add(new URL(h.getConfig().get("url"))); + } + } + return r; + } catch (IOException e) { + throw new GHException("Failed to retrieve post-commit hooks", e); + } + } + + @Override + public Iterator iterator() { + return getPostCommitHooks().iterator(); + } + + @Override + public int size() { + return getPostCommitHooks().size(); + } + + @Override + public boolean add(URL url) { + try { + repo.createWebHook(url); + return true; + } catch (IOException e) { + throw new GHException("Failed to update post-commit hooks", e); + } + } + + @Override + public boolean remove(Object url) { + try { + String _url = ((URL) url).toExternalForm(); + for (GHHook h : repo.getHooks()) { + if (h.getName().equals("web") && h.getConfig().get("url").equals(_url)) { + h.delete(); + return true; + } + } + return false; + } catch (IOException e) { + throw new GHException("Failed to update post-commit hooks", e); + } + } + }; + } + /** * Gets the refs. * @@ -1662,24 +1682,11 @@ public void starTest() throws Exception { assertThat(repository.getOwner().getLogin(), equalTo(owner)); assertThat(repository.getStargazersCount(), is(1)); repository.star(); - assertThat(repository.listStargazers2().toList().size(), is(2)); + assertThat(repository.listStargazers().toList().size(), is(2)); repository.unstar(); assertThat(repository.listStargazers().toList().size(), is(1)); } - /** - * Test to check getRepoVariable method. - * - * @throws Exception - * the exception - */ - @Test - public void testRepoActionVariable() throws Exception { - GHRepository repository = getRepository(); - GHRepositoryVariable variable = repository.getRepoVariable("myvar"); - assertThat(variable.getValue(), is("this is my var value")); - } - /** * Test create repo action variable. * diff --git a/src/test/java/org/kohsuke/github/GHTreeBuilderTest.java b/src/test/java/org/kohsuke/github/GHTreeBuilderTest.java index 9071477889..51787918c5 100644 --- a/src/test/java/org/kohsuke/github/GHTreeBuilderTest.java +++ b/src/test/java/org/kohsuke/github/GHTreeBuilderTest.java @@ -2,7 +2,6 @@ import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import java.io.IOException; @@ -71,44 +70,6 @@ public void setUp() throws Exception { treeBuilder = repo.createTree().baseTree(mainTreeSha); } - /** - * Test text entry. - * - * @throws Exception - * the exception - */ - @Test - @Ignore("It seems that GitHub no longer supports the 'content' parameter") - public void testTextEntry() throws Exception { - treeBuilder.textEntry(PATH_SCRIPT, CONTENT_SCRIPT, true); - treeBuilder.textEntry(PATH_README, CONTENT_README, false); - - updateTree(); - - assertThat(getFileSize(PATH_SCRIPT), equalTo(CONTENT_SCRIPT.length())); - assertThat(getFileSize(PATH_README), equalTo(CONTENT_README.length())); - } - - /** - * Test sha entry. - * - * @throws Exception - * the exception - */ - @Test - public void testShaEntry() throws Exception { - String dataSha1 = new GHBlobBuilder(repo).binaryContent(CONTENT_DATA1).create().getSha(); - treeBuilder.shaEntry(PATH_DATA1, dataSha1, false); - - String dataSha2 = new GHBlobBuilder(repo).binaryContent(CONTENT_DATA2).create().getSha(); - treeBuilder.shaEntry(PATH_DATA2, dataSha2, false); - - updateTree(); - - assertThat(getFileSize(PATH_DATA1), equalTo((long) CONTENT_DATA1.length)); - assertThat(getFileSize(PATH_DATA2), equalTo((long) CONTENT_DATA2.length)); - } - /** * Test add. * diff --git a/src/test/java/org/kohsuke/github/GHUserTest.java b/src/test/java/org/kohsuke/github/GHUserTest.java index 5e67bf6451..952309a23e 100644 --- a/src/test/java/org/kohsuke/github/GHUserTest.java +++ b/src/test/java/org/kohsuke/github/GHUserTest.java @@ -159,7 +159,7 @@ public void listProjects() throws IOException { @Test public void listPublicRepositoriesPageSize62() throws IOException { GHUser user = gitHub.getUser("kohsuke"); - Iterator itr = user.listRepositories().withPageSize(62).iterator(); + Iterator itr = user.listRepositories(62).iterator(); int i = 0; for (; i < 115; i++) { assertThat(itr.hasNext(), is(true)); diff --git a/src/test/java/org/kohsuke/github/GitHubConnectionTest.java b/src/test/java/org/kohsuke/github/GitHubConnectionTest.java index fd3d6ebffb..bb863eae72 100644 --- a/src/test/java/org/kohsuke/github/GitHubConnectionTest.java +++ b/src/test/java/org/kohsuke/github/GitHubConnectionTest.java @@ -59,7 +59,7 @@ public void testOffline() throws Exception { */ @Test public void testGitHubServerWithHttp() throws Exception { - GitHub hub = GitHub.connectToEnterprise("http://enterprise.kohsuke.org/api/v3", "bogus", "bogus"); + GitHub hub = GitHub.connectToEnterpriseWithOAuth("http://enterprise.kohsuke.org/api/v3", "bogus", "bogus"); assertThat(GitHubRequest.getApiURL(hub.getClient().getApiUrl(), "/test").toString(), equalTo("http://enterprise.kohsuke.org/api/v3/test")); } @@ -72,7 +72,7 @@ public void testGitHubServerWithHttp() throws Exception { */ @Test public void testGitHubServerWithHttps() throws Exception { - GitHub hub = GitHub.connectToEnterprise("https://enterprise.kohsuke.org/api/v3", "bogus", "bogus"); + GitHub hub = GitHub.connectToEnterpriseWithOAuth("https://enterprise.kohsuke.org/api/v3", "bogus", "bogus"); assertThat(GitHubRequest.getApiURL(hub.getClient().getApiUrl(), "/test").toString(), equalTo("https://enterprise.kohsuke.org/api/v3/test")); } @@ -85,7 +85,7 @@ public void testGitHubServerWithHttps() throws Exception { */ @Test public void testGitHubServerWithoutServer() throws Exception { - GitHub hub = GitHub.connectUsingPassword("kohsuke", "bogus"); + GitHub hub = GitHub.connect("kohsuke", "bogus"); assertThat(GitHubRequest.getApiURL(hub.getClient().getApiUrl(), "/test").toString(), equalTo("https://api.github.com/test")); } @@ -129,60 +129,17 @@ public void testGitHubBuilderFromEnvironment() throws IOException { assertThat(builder.authorizationProvider, not(instanceOf(UserAuthorizationProvider.class))); assertThat(builder.authorizationProvider.getEncodedAuthorization(), equalTo("Bearer bogus jwt token string")); - props.put("password", "bogus weak password"); - setupEnvironment(props); - builder = GitHubBuilder.fromEnvironment(); + // props.put("password", "bogus weak password"); + // setupEnvironment(props); + // builder = GitHubBuilder.fromEnvironment(); - assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); - assertThat(builder.authorizationProvider.getEncodedAuthorization(), - equalTo("Basic Ym9ndXMgbG9naW46Ym9ndXMgd2VhayBwYXNzd29yZA==")); - assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), equalTo("bogus login")); + // assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); + // assertThat(builder.authorizationProvider.getEncodedAuthorization(), + // equalTo("Basic Ym9ndXMgbG9naW46Ym9ndXMgd2VhayBwYXNzd29yZA==")); + // assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), equalTo("bogus login")); } - /** - * Test git hub builder from custom environment. - * - * @throws IOException - * Signals that an I/O exception has occurred. - */ - @Test - public void testGitHubBuilderFromCustomEnvironment() throws IOException { - // we disable this test for JDK 16+ as the current hacks in setupEnvironment() don't work with JDK 16+ - Assume.assumeThat(Double.valueOf(System.getProperty("java.specification.version")), lessThan(16.0)); - - Map props = new HashMap(); - - props.put("customEndpoint", "bogus endpoint url"); - props.put("customOauth", "bogus oauth token string"); - setupEnvironment(props); - GitHubBuilder builder = GitHubBuilder - .fromEnvironment("customLogin", "customPassword", "customOauth", "customEndpoint"); - - assertThat(builder.endpoint, equalTo("bogus endpoint url")); - - assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); - assertThat(builder.authorizationProvider.getEncodedAuthorization(), equalTo("token bogus oauth token string")); - assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), nullValue()); - - props.put("customLogin", "bogus login"); - setupEnvironment(props); - builder = GitHubBuilder.fromEnvironment("customLogin", "customPassword", "customOauth", "customEndpoint"); - - assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); - assertThat(builder.authorizationProvider.getEncodedAuthorization(), equalTo("token bogus oauth token string")); - assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), equalTo("bogus login")); - - props.put("customPassword", "bogus weak password"); - setupEnvironment(props); - builder = GitHubBuilder.fromEnvironment("customLogin", "customPassword", "customOauth", "customEndpoint"); - - assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); - assertThat(builder.authorizationProvider.getEncodedAuthorization(), - equalTo("Basic Ym9ndXMgbG9naW46Ym9ndXMgd2VhayBwYXNzd29yZA==")); - assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), equalTo("bogus login")); - } - /** * Test git hub builder from credentials with environment. * @@ -204,7 +161,7 @@ public void testGitHubBuilderFromCredentialsWithEnvironment() throws IOException assertThat(builder.endpoint, equalTo("bogus endpoint url")); - assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); + // assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); assertThat(builder.authorizationProvider.getEncodedAuthorization(), equalTo("token bogus oauth token string")); assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), nullValue()); @@ -212,7 +169,7 @@ public void testGitHubBuilderFromCredentialsWithEnvironment() throws IOException setupEnvironment(props); builder = GitHubBuilder.fromCredentials(); - assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); + // assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); assertThat(builder.authorizationProvider.getEncodedAuthorization(), equalTo("token bogus oauth token string")); assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), equalTo("bogus login")); @@ -222,15 +179,6 @@ public void testGitHubBuilderFromCredentialsWithEnvironment() throws IOException assertThat(builder.authorizationProvider, not(instanceOf(UserAuthorizationProvider.class))); assertThat(builder.authorizationProvider.getEncodedAuthorization(), equalTo("Bearer bogus jwt token string")); - - props.put("password", "bogus weak password"); - setupEnvironment(props); - builder = GitHubBuilder.fromCredentials(); - - assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); - assertThat(builder.authorizationProvider.getEncodedAuthorization(), - equalTo("Basic Ym9ndXMgbG9naW46Ym9ndXMgd2VhayBwYXNzd29yZA==")); - assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), equalTo("bogus login")); } /** @@ -270,7 +218,7 @@ public void testGitHubBuilderFromCredentialsWithPropertyFile() throws IOExceptio assertThat(builder.endpoint, equalTo("bogus endpoint url")); - assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); + // assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); assertThat(builder.authorizationProvider.getEncodedAuthorization(), equalTo("token bogus oauth token string")); assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), nullValue()); @@ -279,7 +227,7 @@ public void testGitHubBuilderFromCredentialsWithPropertyFile() throws IOExceptio setupPropertyFile(props); builder = GitHubBuilder.fromCredentials(); - assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); + // assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); assertThat(builder.authorizationProvider.getEncodedAuthorization(), equalTo("token bogus oauth token string")); assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), equalTo("bogus login")); @@ -291,15 +239,6 @@ public void testGitHubBuilderFromCredentialsWithPropertyFile() throws IOExceptio assertThat(builder.authorizationProvider, not(instanceOf(UserAuthorizationProvider.class))); assertThat(builder.authorizationProvider.getEncodedAuthorization(), equalTo("Bearer bogus jwt token string")); - - props.put("password", "bogus weak password"); - setupPropertyFile(props); - builder = GitHubBuilder.fromCredentials(); - - assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); - assertThat(builder.authorizationProvider.getEncodedAuthorization(), - equalTo("Basic Ym9ndXMgbG9naW46Ym9ndXMgd2VhayBwYXNzd29yZA==")); - assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), equalTo("bogus login")); } finally { GitHubBuilder.HOME_DIRECTORY = null; File propertyFile = new File(getTestDirectory(), ".github"); @@ -335,8 +274,7 @@ public void testAnonymous() throws IOException { setupEnvironment(props); // No values present except endpoint - GitHubBuilder builder = GitHubBuilder - .fromEnvironment("customLogin", "customPassword", "customOauth", "endpoint"); + GitHubBuilder builder = GitHubBuilder.fromEnvironment(); assertThat(builder.endpoint, equalTo(mockGitHub.apiServer().baseUrl())); assertThat(builder.authorizationProvider, sameInstance(AuthorizationProvider.ANONYMOUS)); @@ -352,7 +290,7 @@ public void testAnonymous() throws IOException { public void testGithubBuilderWithAppInstallationToken() throws Exception { GitHubBuilder builder = new GitHubBuilder().withAppInstallationToken("bogus app token"); - assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); + // assertThat(builder.authorizationProvider, instanceOf(UserAuthorizationProvider.class)); assertThat(builder.authorizationProvider.getEncodedAuthorization(), equalTo("token bogus app token")); assertThat(((UserAuthorizationProvider) builder.authorizationProvider).getLogin(), is(emptyString())); diff --git a/src/test/java/org/kohsuke/github/GitHubStaticTest.java b/src/test/java/org/kohsuke/github/GitHubStaticTest.java index 16ac75b524..e2866ae055 100644 --- a/src/test/java/org/kohsuke/github/GitHubStaticTest.java +++ b/src/test/java/org/kohsuke/github/GitHubStaticTest.java @@ -2,7 +2,6 @@ import org.junit.Assert; import org.junit.Test; -import org.kohsuke.github.connector.GitHubConnector; import org.kohsuke.github.connector.GitHubConnectorResponse; import java.net.MalformedURLException; @@ -375,7 +374,6 @@ public void testMappingReaderWriter() throws Exception { // This should never happen if the internal method isn't used final GHRepository readRepoFinal = readRepo; - assertThrows(NullPointerException.class, () -> readRepoFinal.getRoot()); assertThrows(NullPointerException.class, () -> readRepoFinal.root()); assertThat(readRepoFinal.isOffline(), is(true)); assertThat(readRepo.getResponseHeaderFields(), nullValue()); @@ -383,7 +381,6 @@ public void testMappingReaderWriter() throws Exception { readRepo = GitHub.getMappingObjectReader().forType(GHRepository.class).readValue(repoString); // This should never happen if the internal method isn't used - assertThat(readRepo.getRoot().getConnector(), equalTo(GitHubConnector.OFFLINE)); assertThat(readRepo.getResponseHeaderFields(), nullValue()); String readRepoString = GitHub.getMappingObjectWriter().writeValueAsString(readRepo); @@ -419,8 +416,8 @@ public void testGitHubRequest_getApiURL() throws Exception { assertThat(e.getCause().getMessage(), equalTo("unknown protocol: gopher")); e = Assert.assertThrows(GHException.class, () -> GitHubRequest.getApiURL("bogus", "/endpoint")); - assertThat(e.getCause(), instanceOf(MalformedURLException.class)); - assertThat(e.getCause().getMessage(), equalTo("no protocol: bogus/endpoint")); + assertThat(e.getCause(), instanceOf(IllegalArgumentException.class)); + assertThat(e.getCause().getMessage(), equalTo("URI is not absolute")); e = Assert.assertThrows(GHException.class, () -> GitHubRequest.getApiURL(null, "gopher://api.test.github.com/endpoint")); diff --git a/src/test/java/org/kohsuke/github/GitHubTest.java b/src/test/java/org/kohsuke/github/GitHubTest.java index fc2c76c21f..61ca013d18 100644 --- a/src/test/java/org/kohsuke/github/GitHubTest.java +++ b/src/test/java/org/kohsuke/github/GitHubTest.java @@ -43,7 +43,7 @@ public void getRepository() throws IOException { assertThat(repo.getFullName(), equalTo("hub4j/github-api")); - GHRepository repo2 = gitHub.getRepositoryById(Long.toString(repo.getId())); + GHRepository repo2 = gitHub.getRepositoryById(repo.getId()); assertThat(repo2.getFullName(), equalTo("hub4j/github-api")); try { @@ -236,7 +236,7 @@ public void searchContentWithForks() { .language("js") .sort(GHContentSearchBuilder.Sort.INDEXED) .order(GHDirection.DESC) - .fork(GHFork.PARENT_ONLY.toString()) + .fork(GHFork.PARENT_ONLY) .list(); final PagedSearchIterable resultsWithForksDeprecated = gitHub.searchContent() @@ -244,7 +244,7 @@ public void searchContentWithForks() { .language("js") .sort(GHContentSearchBuilder.Sort.INDEXED) .order(GHDirection.DESC) - .fork(GHFork.PARENT_AND_FORKS.toString()) + .fork(GHFork.PARENT_AND_FORKS) .list(); assertThat(resultsDeprecated.getTotalCount(), equalTo(results.getTotalCount())); diff --git a/src/test/java/org/kohsuke/github/Github2faTest.java b/src/test/java/org/kohsuke/github/Github2faTest.java index a76661a8d0..8a4e10421f 100644 --- a/src/test/java/org/kohsuke/github/Github2faTest.java +++ b/src/test/java/org/kohsuke/github/Github2faTest.java @@ -49,7 +49,6 @@ public void test2faToken() throws IOException { assertThat(token.getNoteUrl().toString(), equalTo("https://localhost/this/is/a/test/token")); assertThat(token.getAppUrl().toString(), equalTo("https://localhost/this/is/a/test/app/token")); assertThat(token.getFingerprint(), nullValue()); - assertThat(token.getHtmlUrl(), nullValue()); } } diff --git a/src/test/java/org/kohsuke/github/LifecycleTest.java b/src/test/java/org/kohsuke/github/LifecycleTest.java index 2651346f78..7abbd5a7fb 100644 --- a/src/test/java/org/kohsuke/github/LifecycleTest.java +++ b/src/test/java/org/kohsuke/github/LifecycleTest.java @@ -32,7 +32,7 @@ public void testCreateRepository() throws IOException { // GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG); GHRepository repository = getTempRepository(); - assertThat(repository.getReleases(), is(empty())); + assertThat(repository.listReleases().toList(), is(empty())); GHMilestone milestone = repository.createMilestone("Initial Release", "first one"); GHIssue issue = repository.createIssue("Test Issue") @@ -55,20 +55,20 @@ public void testCreateRepository() throws IOException { private void updateAsset(GHRelease release, GHAsset asset) throws IOException { asset.setLabel("test label"); - assertThat(release.getAssets().get(0).getLabel(), equalTo("test label")); + assertThat(release.listAssets().toList().get(0).getLabel(), equalTo("test label")); } private void deleteAsset(GHRelease release, GHAsset asset) throws IOException { asset.delete(); - assertThat(release.getAssets(), is(empty())); + assertThat(release.listAssets().toList(), is(empty())); } private GHAsset uploadAsset(GHRelease release) throws IOException { GHAsset asset = release.uploadAsset(new File("LICENSE.txt"), "application/text"); assertThat(asset, notNullValue()); - List cachedAssets = release.assets(); + List cachedAssets = release.getAssets(); assertThat(cachedAssets, is(empty())); - List assets = release.getAssets(); + List assets = release.listAssets().toList(); assertThat(assets.size(), equalTo(1)); assertThat(assets.get(0).getName(), equalTo("LICENSE.txt")); assertThat(assets.get(0).getSize(), equalTo(1104L)); @@ -87,7 +87,7 @@ private GHRelease createRelease(GHRepository repository) throws IOException { .name("Test Release") .body("How exciting! To be able to programmatically create releases is a dream come true!") .create(); - List releases = repository.getReleases(); + List releases = repository.listReleases().toList(); assertThat(releases.size(), equalTo(1)); GHRelease release = releases.get(0); assertThat(release.getName(), equalTo("Test Release")); diff --git a/src/test/java/org/kohsuke/github/RateLimitHandlerTest.java b/src/test/java/org/kohsuke/github/RateLimitHandlerTest.java index b624409152..5606d00a07 100644 --- a/src/test/java/org/kohsuke/github/RateLimitHandlerTest.java +++ b/src/test/java/org/kohsuke/github/RateLimitHandlerTest.java @@ -2,9 +2,11 @@ import com.github.tomakehurst.wiremock.core.WireMockConfiguration; import org.junit.Test; +import org.kohsuke.github.connector.GitHubConnectorResponse; import java.io.IOException; -import java.net.HttpURLConnection; + +import javax.annotation.Nonnull; import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.core.IsInstanceOf.instanceOf; @@ -61,7 +63,7 @@ public void testHandler_Fail() throws Exception { snapshotNotAllowed(); gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withRateLimitHandler(RateLimitHandler.FAIL) + .withRateLimitHandler(GitHubRateLimitHandler.FAIL) .build(); gitHub.getMyself(); @@ -91,7 +93,7 @@ public void testHandler_HttpStatus_Fail() throws Exception { snapshotNotAllowed(); gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withRateLimitHandler(RateLimitHandler.FAIL) + .withRateLimitHandler(GitHubRateLimitHandler.FAIL) .build(); gitHub.getMyself(); @@ -124,7 +126,7 @@ public void testHandler_Wait() throws Exception { snapshotNotAllowed(); gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withRateLimitHandler(RateLimitHandler.WAIT) + .withRateLimitHandler(GitHubRateLimitHandler.WAIT) .build(); gitHub.getMyself(); @@ -146,9 +148,9 @@ public void testHandler_WaitStuck() throws Exception { snapshotNotAllowed(); gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withRateLimitHandler(new RateLimitHandler() { + .withRateLimitHandler(new GitHubRateLimitHandler() { @Override - public void onError(IOException e, HttpURLConnection uc) throws IOException { + public void onError(@Nonnull GitHubConnectorResponse connectorResponse) throws IOException { } }) .build(); diff --git a/src/test/java/org/kohsuke/github/RequesterRetryTest.java b/src/test/java/org/kohsuke/github/RequesterRetryTest.java index 7b88ce707f..5675036a29 100644 --- a/src/test/java/org/kohsuke/github/RequesterRetryTest.java +++ b/src/test/java/org/kohsuke/github/RequesterRetryTest.java @@ -1,30 +1,21 @@ package org.kohsuke.github; -import com.github.tomakehurst.wiremock.http.Fault; -import com.github.tomakehurst.wiremock.stubbing.Scenario; import okhttp3.ConnectionPool; import okhttp3.OkHttpClient; -import org.junit.Assume; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; +import org.kohsuke.github.connector.GitHubConnector; +import org.kohsuke.github.connector.GitHubConnectorRequest; +import org.kohsuke.github.connector.GitHubConnectorResponse; import org.kohsuke.github.extras.HttpClientGitHubConnector; -import org.kohsuke.github.extras.ImpatientHttpConnector; import org.kohsuke.github.extras.okhttp3.OkHttpGitHubConnector; -import org.kohsuke.github.internal.DefaultGitHubConnector; -import org.mockito.Mockito; - -import java.io.ByteArrayOutputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.ProtocolException; -import java.net.SocketException; -import java.net.SocketTimeoutException; + +import java.io.*; import java.net.URL; -import java.security.Permission; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -32,9 +23,9 @@ import java.util.logging.SimpleFormatter; import java.util.logging.StreamHandler; -import javax.net.ssl.SSLHandshakeException; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; -import static com.github.tomakehurst.wiremock.client.WireMock.*; import static org.hamcrest.Matchers.*; // TODO: Auto-generated Javadoc @@ -51,7 +42,7 @@ public class RequesterRetryTest extends AbstractGitHubWireMockTest { private static StreamHandler customLogHandler; /** The connection. */ - HttpURLConnection connection; + // HttpURLConnection connection; /** The base request count. */ int baseRequestCount; @@ -148,79 +139,79 @@ public void testGitHubIsApiUrlValid() throws Exception { assertThat(capturedLog, not(containsString("leaked"))); } - /** - * Test socket connection and retry. - * - * @throws Exception - * the exception - */ - // Issue #539 - @Test - public void testSocketConnectionAndRetry() throws Exception { - // Only implemented for HttpURLConnection connectors - Assume.assumeThat(DefaultGitHubConnector.create(), not(instanceOf(HttpClientGitHubConnector.class))); - - // CONNECTION_RESET_BY_PEER errors result in two requests each - // to get this failure for "3" tries we have to do 6 queries. - this.mockGitHub.apiServer() - .stubFor(get(urlMatching(".+/branches/test/timeout")) - .willReturn(aResponse().withFault(Fault.CONNECTION_RESET_BY_PEER))); - - this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()).build(); - - GHRepository repo = getRepository(); - baseRequestCount = this.mockGitHub.getRequestCount(); - try { - repo.getBranch("test/timeout"); - fail(); - } catch (Exception e) { - assertThat(e, instanceOf(HttpException.class)); - } - - String capturedLog = getTestCapturedLog(); - assertThat(capturedLog, containsString("(2 retries remaining)")); - assertThat(capturedLog, containsString("(1 retries remaining)")); - - assertThat(this.mockGitHub.getRequestCount(), equalTo(baseRequestCount + 6)); - } - - /** - * Test socket connection and retry status code. - * - * @throws Exception - * the exception - */ - // Issue #539 - @Test - public void testSocketConnectionAndRetry_StatusCode() throws Exception { - // Only implemented for HttpURLConnection connectors - Assume.assumeThat(DefaultGitHubConnector.create(), not(instanceOf(HttpClientGitHubConnector.class))); - - // CONNECTION_RESET_BY_PEER errors result in two requests each - // to get this failure for "3" tries we have to do 6 queries. - this.mockGitHub.apiServer() - .stubFor(get(urlMatching(".+/branches/test/timeout")) - .willReturn(aResponse().withFault(Fault.CONNECTION_RESET_BY_PEER))); - - this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()).build(); - - baseRequestCount = this.mockGitHub.getRequestCount(); - try { - // status code is a different code path that should also be covered by this. - gitHub.createRequest() - .withUrlPath("/repos/hub4j-test-org/github-api/branches/test/timeout") - .fetchHttpStatusCode(); - fail(); - } catch (Exception e) { - assertThat(e, instanceOf(HttpException.class)); - } - - String capturedLog = getTestCapturedLog(); - assertThat(capturedLog, containsString("(2 retries remaining)")); - assertThat(capturedLog, containsString("(1 retries remaining)")); - - assertThat(this.mockGitHub.getRequestCount(), equalTo(baseRequestCount + 6)); - } + // /** + // * Test socket connection and retry. + // * + // * @throws Exception + // * the exception + // */ + // // Issue #539 + // @Test + // public void testSocketConnectionAndRetry() throws Exception { + // // Only implemented for HttpURLConnection connectors + // Assume.assumeThat(DefaultGitHubConnector.create(), not(instanceOf(HttpClientGitHubConnector.class))); + + // // CONNECTION_RESET_BY_PEER errors result in two requests each + // // to get this failure for "3" tries we have to do 6 queries. + // this.mockGitHub.apiServer() + // .stubFor(get(urlMatching(".+/branches/test/timeout")) + // .willReturn(aResponse().withFault(Fault.CONNECTION_RESET_BY_PEER))); + + // this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()).build(); + + // GHRepository repo = getRepository(); + // baseRequestCount = this.mockGitHub.getRequestCount(); + // try { + // repo.getBranch("test/timeout"); + // fail(); + // } catch (Exception e) { + // assertThat(e, instanceOf(HttpException.class)); + // } + + // String capturedLog = getTestCapturedLog(); + // assertThat(capturedLog, containsString("(2 retries remaining)")); + // assertThat(capturedLog, containsString("(1 retries remaining)")); + + // assertThat(this.mockGitHub.getRequestCount(), equalTo(baseRequestCount + 6)); + // } + + // /** + // * Test socket connection and retry status code. + // * + // * @throws Exception + // * the exception + // */ + // // Issue #539 + // @Test + // public void testSocketConnectionAndRetry_StatusCode() throws Exception { + // // Only implemented for HttpURLConnection connectors + // Assume.assumeThat(DefaultGitHubConnector.create(), not(instanceOf(HttpClientGitHubConnector.class))); + + // // CONNECTION_RESET_BY_PEER errors result in two requests each + // // to get this failure for "3" tries we have to do 6 queries. + // this.mockGitHub.apiServer() + // .stubFor(get(urlMatching(".+/branches/test/timeout")) + // .willReturn(aResponse().withFault(Fault.CONNECTION_RESET_BY_PEER))); + + // this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()).build(); + + // baseRequestCount = this.mockGitHub.getRequestCount(); + // try { + // // status code is a different code path that should also be covered by this. + // gitHub.createRequest() + // .withUrlPath("/repos/hub4j-test-org/github-api/branches/test/timeout") + // .fetchHttpStatusCode(); + // fail(); + // } catch (Exception e) { + // assertThat(e, instanceOf(HttpException.class)); + // } + + // String capturedLog = getTestCapturedLog(); + // assertThat(capturedLog, containsString("(2 retries remaining)")); + // assertThat(capturedLog, containsString("(1 retries remaining)")); + + // assertThat(this.mockGitHub.getRequestCount(), equalTo(baseRequestCount + 6)); + // } /** * Test socket connection and retry success. @@ -228,58 +219,58 @@ public void testSocketConnectionAndRetry_StatusCode() throws Exception { * @throws Exception * the exception */ - @Test - public void testSocketConnectionAndRetry_Success() throws Exception { - // Only implemented for HttpURLConnection connectors - Assume.assumeThat(DefaultGitHubConnector.create(), not(instanceOf(HttpClientGitHubConnector.class))); - - // CONNECTION_RESET_BY_PEER errors result in two requests each - // to get this failure for "3" tries we have to do 6 queries. - // If there are only 5 errors we succeed. - this.mockGitHub.apiServer() - .stubFor(get(urlMatching(".+/branches/test/timeout")).atPriority(0) - .inScenario("Retry") - .whenScenarioStateIs(Scenario.STARTED) - .willReturn(aResponse().withFault(Fault.CONNECTION_RESET_BY_PEER))) - .setNewScenarioState("Retry-1"); - this.mockGitHub.apiServer() - .stubFor(get(urlMatching(".+/branches/test/timeout")).atPriority(0) - .inScenario("Retry") - .whenScenarioStateIs("Retry-1") - .willReturn(aResponse().withFault(Fault.CONNECTION_RESET_BY_PEER))) - .setNewScenarioState("Retry-2"); - this.mockGitHub.apiServer() - .stubFor(get(urlMatching(".+/branches/test/timeout")).atPriority(0) - .inScenario("Retry") - .whenScenarioStateIs("Retry-2") - .willReturn(aResponse().withFault(Fault.CONNECTION_RESET_BY_PEER))) - .setNewScenarioState("Retry-3"); - this.mockGitHub.apiServer() - .stubFor(get(urlMatching(".+/branches/test/timeout")).atPriority(0) - .inScenario("Retry") - .whenScenarioStateIs("Retry-3") - .willReturn(aResponse().withFault(Fault.CONNECTION_RESET_BY_PEER))) - .setNewScenarioState("Retry-4"); - this.mockGitHub.apiServer() - .stubFor(get(urlMatching(".+/branches/test/timeout")).atPriority(0) - .atPriority(0) - .inScenario("Retry") - .whenScenarioStateIs("Retry-4") - .willReturn(aResponse().withFault(Fault.CONNECTION_RESET_BY_PEER))) - .setNewScenarioState("Retry-5"); - - this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()).build(); - - GHRepository repo = getRepository(); - baseRequestCount = this.mockGitHub.getRequestCount(); - GHBranch branch = repo.getBranch("test/timeout"); - assertThat(branch, notNullValue()); - String capturedLog = getTestCapturedLog(); - assertThat(capturedLog, containsString("(2 retries remaining)")); - assertThat(capturedLog, containsString("(1 retries remaining)")); - - assertThat(this.mockGitHub.getRequestCount(), equalTo(baseRequestCount + 6)); - } + // @Test + // public void testSocketConnectionAndRetry_Success() throws Exception { + // // Only implemented for HttpURLConnection connectors + // Assume.assumeThat(DefaultGitHubConnector.create(), not(instanceOf(HttpClientGitHubConnector.class))); + + // // CONNECTION_RESET_BY_PEER errors result in two requests each + // // to get this failure for "3" tries we have to do 6 queries. + // // If there are only 5 errors we succeed. + // this.mockGitHub.apiServer() + // .stubFor(get(urlMatching(".+/branches/test/timeout")).atPriority(0) + // .inScenario("Retry") + // .whenScenarioStateIs(Scenario.STARTED) + // .willReturn(aResponse().withFault(Fault.CONNECTION_RESET_BY_PEER))) + // .setNewScenarioState("Retry-1"); + // this.mockGitHub.apiServer() + // .stubFor(get(urlMatching(".+/branches/test/timeout")).atPriority(0) + // .inScenario("Retry") + // .whenScenarioStateIs("Retry-1") + // .willReturn(aResponse().withFault(Fault.CONNECTION_RESET_BY_PEER))) + // .setNewScenarioState("Retry-2"); + // this.mockGitHub.apiServer() + // .stubFor(get(urlMatching(".+/branches/test/timeout")).atPriority(0) + // .inScenario("Retry") + // .whenScenarioStateIs("Retry-2") + // .willReturn(aResponse().withFault(Fault.CONNECTION_RESET_BY_PEER))) + // .setNewScenarioState("Retry-3"); + // this.mockGitHub.apiServer() + // .stubFor(get(urlMatching(".+/branches/test/timeout")).atPriority(0) + // .inScenario("Retry") + // .whenScenarioStateIs("Retry-3") + // .willReturn(aResponse().withFault(Fault.CONNECTION_RESET_BY_PEER))) + // .setNewScenarioState("Retry-4"); + // this.mockGitHub.apiServer() + // .stubFor(get(urlMatching(".+/branches/test/timeout")).atPriority(0) + // .atPriority(0) + // .inScenario("Retry") + // .whenScenarioStateIs("Retry-4") + // .willReturn(aResponse().withFault(Fault.CONNECTION_RESET_BY_PEER))) + // .setNewScenarioState("Retry-5"); + + // this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()).build(); + + // GHRepository repo = getRepository(); + // baseRequestCount = this.mockGitHub.getRequestCount(); + // GHBranch branch = repo.getBranch("test/timeout"); + // assertThat(branch, notNullValue()); + // String capturedLog = getTestCapturedLog(); + // assertThat(capturedLog, containsString("(2 retries remaining)")); + // assertThat(capturedLog, containsString("(1 retries remaining)")); + + // assertThat(this.mockGitHub.getRequestCount(), equalTo(baseRequestCount + 6)); + // } /** * Test response code failure exceptions. @@ -290,7 +281,7 @@ public void testSocketConnectionAndRetry_Success() throws Exception { @Test public void testResponseCodeFailureExceptions() throws Exception { // No retry for these Exceptions - HttpConnector connector = new ResponseCodeThrowingHttpConnector<>(() -> { + GitHubConnector connector = new SendThrowingGitHubConnector<>(() -> { throw new IOException("Custom"); }); this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) @@ -311,7 +302,7 @@ public void testResponseCodeFailureExceptions() throws Exception { assertThat(this.mockGitHub.getRequestCount(), equalTo(baseRequestCount)); } - connector = new ResponseCodeThrowingHttpConnector<>(() -> { + connector = new SendThrowingGitHubConnector<>(() -> { throw new FileNotFoundException("Custom"); }); this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) @@ -341,7 +332,7 @@ public void testResponseCodeFailureExceptions() throws Exception { @Test public void testInputStreamFailureExceptions() throws Exception { // No retry for these Exceptions - HttpConnector connector = new InputStreamThrowingHttpConnector<>(() -> { + GitHubConnector connector = new BodyStreamThrowingGitHubConnector<>(() -> { throw new IOException("Custom"); }); this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) @@ -400,27 +391,27 @@ public void testInputStreamFailureExceptions() throws Exception { * @throws Exception * the exception */ - @Test - public void testResponseCodeConnectionExceptions() throws Exception { - // Because the test throws at the very start of getResponseCode, there is only one connection for 3 retries - HttpConnector connector = new ResponseCodeThrowingHttpConnector<>(() -> { - throw new SocketException(); - }); - runConnectionExceptionTest(connector, 1); - runConnectionExceptionStatusCodeTest(connector, 1); - - connector = new ResponseCodeThrowingHttpConnector<>(() -> { - throw new SocketTimeoutException(); - }); - runConnectionExceptionTest(connector, 1); - runConnectionExceptionStatusCodeTest(connector, 1); - - connector = new ResponseCodeThrowingHttpConnector<>(() -> { - throw new SSLHandshakeException("TestFailure"); - }); - runConnectionExceptionTest(connector, 1); - runConnectionExceptionStatusCodeTest(connector, 1); - } + // @Test + // public void testResponseCodeConnectionExceptions() throws Exception { + // // Because the test throws at the very start of send(), there is only one connection for 3 retries + // GitHubConnector connector = new SendThrowingGitHubConnector<>(() -> { + // throw new SocketException(); + // }); + // runConnectionExceptionTest(connector, 1); + // runConnectionExceptionStatusCodeTest(connector, 1); + + // connector = new SendThrowingGitHubConnector<>(() -> { + // throw new SocketTimeoutException(); + // }); + // runConnectionExceptionTest(connector, 1); + // runConnectionExceptionStatusCodeTest(connector, 1); + + // connector = new SendThrowingGitHubConnector<>(() -> { + // throw new SSLHandshakeException("TestFailure"); + // }); + // runConnectionExceptionTest(connector, 1); + // runConnectionExceptionStatusCodeTest(connector, 1); + // } /** * Test input stream connection exceptions. @@ -428,31 +419,31 @@ public void testResponseCodeConnectionExceptions() throws Exception { * @throws Exception * the exception */ - @Test - public void testInputStreamConnectionExceptions() throws Exception { - // InputStream is where most exceptions get thrown whether connection or simple FNF - // Because the test throws after getResponseCode, there is one connection for each retry - // However, getStatusCode never calls that and so it does succeed - HttpConnector connector = new InputStreamThrowingHttpConnector<>(() -> { - throw new SocketException(); - }); - runConnectionExceptionTest(connector, 3); - runConnectionExceptionStatusCodeTest(connector, 0); - - connector = new InputStreamThrowingHttpConnector<>(() -> { - throw new SocketTimeoutException(); - }); - runConnectionExceptionTest(connector, 3); - runConnectionExceptionStatusCodeTest(connector, 0); - - connector = new InputStreamThrowingHttpConnector<>(() -> { - throw new SSLHandshakeException("TestFailure"); - }); - runConnectionExceptionTest(connector, 3); - runConnectionExceptionStatusCodeTest(connector, 0); - } - - private void runConnectionExceptionTest(HttpConnector connector, int expectedRequestCount) throws IOException { + // @Test + // public void testInputStreamConnectionExceptions() throws Exception { + // // InputStream is where most exceptions get thrown whether connection or simple FNF + // // Because the test throws after send(), there is one connection for each retry + // // However, getStatusCode never calls that and so it does succeed + // GitHubConnector connector = new BodyStreamThrowingGitHubConnector<>(() -> { + // throw new SocketException(); + // }); + // runConnectionExceptionTest(connector, 3); + // runConnectionExceptionStatusCodeTest(connector, 0); + + // connector = new BodyStreamThrowingGitHubConnector<>(() -> { + // throw new SocketTimeoutException(); + // }); + // runConnectionExceptionTest(connector, 3); + // runConnectionExceptionStatusCodeTest(connector, 0); + + // connector = new BodyStreamThrowingGitHubConnector<>(() -> { + // throw new SSLHandshakeException("TestFailure"); + // }); + // runConnectionExceptionTest(connector, 3); + // runConnectionExceptionStatusCodeTest(connector, 0); + // } + + private void runConnectionExceptionTest(GitHubConnector connector, int expectedRequestCount) throws IOException { this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) .withConnector(connector) .build(); @@ -474,7 +465,7 @@ private void runConnectionExceptionTest(HttpConnector connector, int expectedReq assertThat(this.mockGitHub.getRequestCount(), equalTo(baseRequestCount + expectedRequestCount)); } - private void runConnectionExceptionStatusCodeTest(HttpConnector connector, int expectedRequestCount) + private void runConnectionExceptionStatusCodeTest(GitHubConnector connector, int expectedRequestCount) throws IOException { // now wire in the connector this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) @@ -498,12 +489,16 @@ private void runConnectionExceptionStatusCodeTest(HttpConnector connector, int e } /** - * The Class ResponseCodeThrowingHttpConnector. + * The Class ResponseCodeThrowingGitHubConnector. * * @param * the element type */ - class ResponseCodeThrowingHttpConnector extends ImpatientHttpConnector { + static class SendThrowingGitHubConnector extends HttpClientGitHubConnector { + + final int[] count = { 0 }; + + private final Thrower thrower; /** * Instantiates a new response code throwing http connector. @@ -511,32 +506,23 @@ class ResponseCodeThrowingHttpConnector extends Impatient * @param thrower * the thrower */ - ResponseCodeThrowingHttpConnector(final Thrower thrower) { - super(new HttpConnector() { - final int[] count = { 0 }; - - @Override - public HttpURLConnection connect(URL url) throws IOException { - if (url.toString().contains(GITHUB_API_TEST_ORG)) { - count[0]++; - } - connection = Mockito.spy(new HttpURLConnectionWrapper(url) { - @Override - public int getResponseCode() throws IOException { - // While this is not the way this would go in the real world, it is a fine test - // to show that exception handling and retries are working as expected - if (getURL().toString().contains(GITHUB_API_TEST_ORG)) { - if (count[0] % 3 != 0) { - thrower.throwError(); - } - } - return super.getResponseCode(); - } - }); + SendThrowingGitHubConnector(final Thrower thrower) { + super(); + this.thrower = thrower; + } - return connection; + @Override + public GitHubConnectorResponse send(GitHubConnectorRequest connectorRequest) throws IOException { + if (connectorRequest.url().toString().contains(GITHUB_API_TEST_ORG)) { + count[0]++; + // throwing before we call super.send() simulates error + if (count[0] % 3 != 0) { + thrower.throwError(); } - }); + } + + GitHubConnectorResponse response = super.send(connectorRequest); + return new GitHubConnectorResponseWrapper(response); } } @@ -547,7 +533,11 @@ public int getResponseCode() throws IOException { * @param * the element type */ - class InputStreamThrowingHttpConnector extends ImpatientHttpConnector { + static class BodyStreamThrowingGitHubConnector extends HttpClientGitHubConnector { + + final int[] count = { 0 }; + + private final Thrower thrower; /** * Instantiates a new input stream throwing http connector. @@ -555,618 +545,134 @@ class InputStreamThrowingHttpConnector extends ImpatientH * @param thrower * the thrower */ - InputStreamThrowingHttpConnector(final Thrower thrower) { - super(new HttpConnector() { - final int[] count = { 0 }; + BodyStreamThrowingGitHubConnector(final Thrower thrower) { + super(); + this.thrower = thrower; + } + @Override + public GitHubConnectorResponse send(GitHubConnectorRequest connectorRequest) throws IOException { + if (connectorRequest.url().toString().contains(GITHUB_API_TEST_ORG)) { + count[0]++; + } + GitHubConnectorResponse response = super.send(connectorRequest); + return new GitHubConnectorResponseWrapper(response) { + @NotNull @Override - public HttpURLConnection connect(URL url) throws IOException { - if (url.toString().contains(GITHUB_API_TEST_ORG)) { - count[0]++; - } - connection = Mockito.spy(new HttpURLConnectionWrapper(url) { - @Override - public InputStream getInputStream() throws IOException { - // getResponseMessage throwing even though getResponseCode doesn't. - // While this is not the way this would go in the real world, it is a fine test - // to show that exception handling and retries are working as expected - if (getURL().toString().contains(GITHUB_API_TEST_ORG)) { - if (count[0] % 3 != 0) { - thrower.throwError(); - } - } - return super.getInputStream(); + public InputStream bodyStream() throws IOException { + if (response.request().url().toString().contains(GITHUB_API_TEST_ORG)) { + if (count[0] % 3 != 0) { + thrower.throwError(); } - }); - - return connection; + } + return super.bodyStream(); } - }); + }; } } - /** - * The Interface Thrower. - * - * @param - * the element type - */ - @FunctionalInterface - public interface Thrower { - - /** - * Throw error. - * - * @throws E - * the e - */ - void throwError() throws E; - } - - /** - * This is not great but it get the job done. Tried to do a spy of HttpURLConnection but it wouldn't work right. - * Trying to stub methods caused the spy to say it was already connected. - */ - static class HttpURLConnectionWrapper extends HttpURLConnection { - - /** The http URL connection. */ - protected final HttpURLConnection httpURLConnection; - - /** - * Instantiates a new http URL connection wrapper. - * - * @param url - * the url - * @throws IOException - * Signals that an I/O exception has occurred. - */ - HttpURLConnectionWrapper(URL url) throws IOException { - super(new URL("http://nonexistant")); - httpURLConnection = (HttpURLConnection) url.openConnection(); - } - - /** - * Connect. - * - * @throws IOException - * Signals that an I/O exception has occurred. - */ - public void connect() throws IOException { - httpURLConnection.connect(); - } - - /** - * Sets the connect timeout. - * - * @param timeout - * the new connect timeout - */ - public void setConnectTimeout(int timeout) { - httpURLConnection.setConnectTimeout(timeout); - } - - /** - * Gets the connect timeout. - * - * @return the connect timeout - */ - public int getConnectTimeout() { - return httpURLConnection.getConnectTimeout(); - } - - /** - * Sets the read timeout. - * - * @param timeout - * the new read timeout - */ - public void setReadTimeout(int timeout) { - httpURLConnection.setReadTimeout(timeout); - } - - /** - * Gets the read timeout. - * - * @return the read timeout - */ - public int getReadTimeout() { - return httpURLConnection.getReadTimeout(); - } - - /** - * Gets the url. - * - * @return the url - */ - public URL getURL() { - return httpURLConnection.getURL(); - } - - /** - * Gets the content length. - * - * @return the content length - */ - public int getContentLength() { - return httpURLConnection.getContentLength(); - } - - /** - * Gets the content length long. - * - * @return the content length long - */ - public long getContentLengthLong() { - return httpURLConnection.getContentLengthLong(); - } - - /** - * Gets the content type. - * - * @return the content type - */ - public String getContentType() { - return httpURLConnection.getContentType(); - } - - /** - * Gets the content encoding. - * - * @return the content encoding - */ - public String getContentEncoding() { - return httpURLConnection.getContentEncoding(); - } - - /** - * Gets the expiration. - * - * @return the expiration - */ - public long getExpiration() { - return httpURLConnection.getExpiration(); - } - - /** - * Gets the date. - * - * @return the date - */ - public long getDate() { - return httpURLConnection.getDate(); - } - - /** - * Gets the last modified. - * - * @return the last modified - */ - public long getLastModified() { - return httpURLConnection.getLastModified(); - } - - /** - * Gets the header field. - * - * @param name - * the name - * @return the header field - */ - public String getHeaderField(String name) { - return httpURLConnection.getHeaderField(name); - } - - /** - * Gets the header fields. - * - * @return the header fields - */ - public Map> getHeaderFields() { - return httpURLConnection.getHeaderFields(); - } - - /** - * Gets the header field int. - * - * @param name - * the name - * @param Default - * the default - * @return the header field int - */ - public int getHeaderFieldInt(String name, int Default) { - return httpURLConnection.getHeaderFieldInt(name, Default); - } - - /** - * Gets the header field long. - * - * @param name - * the name - * @param Default - * the default - * @return the header field long - */ - public long getHeaderFieldLong(String name, long Default) { - return httpURLConnection.getHeaderFieldLong(name, Default); - } - - /** - * Gets the content. - * - * @return the content - * @throws IOException - * Signals that an I/O exception has occurred. - */ - public Object getContent() throws IOException { - return httpURLConnection.getContent(); - } - - /** - * Gets the content. - * - * @param classes - * the classes - * @return the content - * @throws IOException - * Signals that an I/O exception has occurred. - */ + private static final GitHubConnectorRequest IGNORED_EMPTY_REQUEST = new GitHubConnectorRequest() { + @NotNull @Override - public Object getContent(Class[] classes) throws IOException { - return httpURLConnection.getContent(classes); - } - - /** - * Gets the input stream. - * - * @return the input stream - * @throws IOException - * Signals that an I/O exception has occurred. - */ - public InputStream getInputStream() throws IOException { - return httpURLConnection.getInputStream(); - } - - /** - * Gets the output stream. - * - * @return the output stream - * @throws IOException - * Signals that an I/O exception has occurred. - */ - public OutputStream getOutputStream() throws IOException { - return httpURLConnection.getOutputStream(); - } - - /** - * To string. - * - * @return the string - */ - public String toString() { - return httpURLConnection.toString(); - } - - /** - * Sets the do input. - * - * @param doinput - * the new do input - */ - public void setDoInput(boolean doinput) { - httpURLConnection.setDoInput(doinput); - } - - /** - * Gets the do input. - * - * @return the do input - */ - public boolean getDoInput() { - return httpURLConnection.getDoInput(); - } - - /** - * Sets the do output. - * - * @param dooutput - * the new do output - */ - public void setDoOutput(boolean dooutput) { - httpURLConnection.setDoOutput(dooutput); - } - - /** - * Gets the do output. - * - * @return the do output - */ - public boolean getDoOutput() { - return httpURLConnection.getDoOutput(); - } - - /** - * Sets the allow user interaction. - * - * @param allowuserinteraction - * the new allow user interaction - */ - public void setAllowUserInteraction(boolean allowuserinteraction) { - httpURLConnection.setAllowUserInteraction(allowuserinteraction); - } - - /** - * Gets the allow user interaction. - * - * @return the allow user interaction - */ - public boolean getAllowUserInteraction() { - return httpURLConnection.getAllowUserInteraction(); - } - - /** - * Sets the use caches. - * - * @param usecaches - * the new use caches - */ - public void setUseCaches(boolean usecaches) { - httpURLConnection.setUseCaches(usecaches); - } - - /** - * Gets the use caches. - * - * @return the use caches - */ - public boolean getUseCaches() { - return httpURLConnection.getUseCaches(); - } - - /** - * Sets the if modified since. - * - * @param ifmodifiedsince - * the new if modified since - */ - public void setIfModifiedSince(long ifmodifiedsince) { - httpURLConnection.setIfModifiedSince(ifmodifiedsince); - } - - /** - * Gets the if modified since. - * - * @return the if modified since - */ - public long getIfModifiedSince() { - return httpURLConnection.getIfModifiedSince(); - } - - /** - * Gets the default use caches. - * - * @return the default use caches - */ - public boolean getDefaultUseCaches() { - return httpURLConnection.getDefaultUseCaches(); - } - - /** - * Sets the default use caches. - * - * @param defaultusecaches - * the new default use caches - */ - public void setDefaultUseCaches(boolean defaultusecaches) { - httpURLConnection.setDefaultUseCaches(defaultusecaches); - } - - /** - * Sets the request property. - * - * @param key - * the key - * @param value - * the value - */ - public void setRequestProperty(String key, String value) { - httpURLConnection.setRequestProperty(key, value); - } - - /** - * Adds the request property. - * - * @param key - * the key - * @param value - * the value - */ - public void addRequestProperty(String key, String value) { - httpURLConnection.addRequestProperty(key, value); + public String method() { + return null; } - /** - * Gets the request property. - * - * @param key - * the key - * @return the request property - */ - public String getRequestProperty(String key) { - return httpURLConnection.getRequestProperty(key); - } - - /** - * Gets the request properties. - * - * @return the request properties - */ - public Map> getRequestProperties() { - return httpURLConnection.getRequestProperties(); + @NotNull + @Override + public Map> allHeaders() { + return null; } - /** - * Gets the header field key. - * - * @param n - * the n - * @return the header field key - */ - public String getHeaderFieldKey(int n) { - return httpURLConnection.getHeaderFieldKey(n); + @Nullable + @Override + public String header(String name) { + return null; } - /** - * Sets the fixed length streaming mode. - * - * @param contentLength - * the new fixed length streaming mode - */ - public void setFixedLengthStreamingMode(int contentLength) { - httpURLConnection.setFixedLengthStreamingMode(contentLength); + @Nullable + @Override + public String contentType() { + return null; } - /** - * Sets the fixed length streaming mode. - * - * @param contentLength - * the new fixed length streaming mode - */ - public void setFixedLengthStreamingMode(long contentLength) { - httpURLConnection.setFixedLengthStreamingMode(contentLength); + @Nullable + @Override + public InputStream body() { + return null; } - /** - * Sets the chunked streaming mode. - * - * @param chunklen - * the new chunked streaming mode - */ - public void setChunkedStreamingMode(int chunklen) { - httpURLConnection.setChunkedStreamingMode(chunklen); + @NotNull + @Override + public URL url() { + return null; } - /** - * Gets the header field. - * - * @param n - * the n - * @return the header field - */ - public String getHeaderField(int n) { - return httpURLConnection.getHeaderField(n); + @Override + public boolean hasBody() { + return false; } + }; - /** - * Sets the instance follow redirects. - * - * @param followRedirects - * the new instance follow redirects - */ - public void setInstanceFollowRedirects(boolean followRedirects) { - httpURLConnection.setInstanceFollowRedirects(followRedirects); - } + private static class GitHubConnectorResponseWrapper extends GitHubConnectorResponse { - /** - * Gets the instance follow redirects. - * - * @return the instance follow redirects - */ - public boolean getInstanceFollowRedirects() { - return httpURLConnection.getInstanceFollowRedirects(); - } + private final GitHubConnectorResponse wrapped; - /** - * Sets the request method. - * - * @param method - * the new request method - * @throws ProtocolException - * the protocol exception - */ - public void setRequestMethod(String method) throws ProtocolException { - httpURLConnection.setRequestMethod(method); + GitHubConnectorResponseWrapper(GitHubConnectorResponse response) { + super(IGNORED_EMPTY_REQUEST, -1, new HashMap<>()); + wrapped = response; } - /** - * Gets the request method. - * - * @return the request method - */ - public String getRequestMethod() { - return httpURLConnection.getRequestMethod(); + @CheckForNull + @Override + public String header(String name) { + return wrapped.header(name); } - /** - * Gets the response code. - * - * @return the response code - * @throws IOException - * Signals that an I/O exception has occurred. - */ - public int getResponseCode() throws IOException { - return httpURLConnection.getResponseCode(); + @NotNull + @Override + public InputStream bodyStream() throws IOException { + return wrapped.bodyStream(); } - /** - * Gets the response message. - * - * @return the response message - * @throws IOException - * Signals that an I/O exception has occurred. - */ - public String getResponseMessage() throws IOException { - return httpURLConnection.getResponseMessage(); + @Nonnull + @Override + public GitHubConnectorRequest request() { + return wrapped.request(); } - /** - * Gets the header field date. - * - * @param name - * the name - * @param Default - * the default - * @return the header field date - */ - public long getHeaderFieldDate(String name, long Default) { - return httpURLConnection.getHeaderFieldDate(name, Default); + @Override + public int statusCode() { + return wrapped.statusCode(); } - /** - * Disconnect. - */ - public void disconnect() { - httpURLConnection.disconnect(); + @Nonnull + @Override + public Map> allHeaders() { + return wrapped.allHeaders(); } - /** - * Using proxy. - * - * @return true, if successful - */ - public boolean usingProxy() { - return httpURLConnection.usingProxy(); + @Override + public void close() throws IOException { + wrapped.close(); } + } - /** - * Gets the permission. - * - * @return the permission - * @throws IOException - * Signals that an I/O exception has occurred. - */ - public Permission getPermission() throws IOException { - return httpURLConnection.getPermission(); - } + /** + * The Interface Thrower. + * + * @param + * the element type + */ + @FunctionalInterface + public interface Thrower { /** - * Gets the error stream. + * Throw error. * - * @return the error stream + * @throws E + * the e */ - public InputStream getErrorStream() { - return httpURLConnection.getErrorStream(); - } + void throwError() throws E; } - } diff --git a/src/test/java/org/kohsuke/github/extras/GitHubCachingTest.java b/src/test/java/org/kohsuke/github/extras/GitHubCachingTest.java deleted file mode 100644 index 2ed356555a..0000000000 --- a/src/test/java/org/kohsuke/github/extras/GitHubCachingTest.java +++ /dev/null @@ -1,207 +0,0 @@ -package org.kohsuke.github.extras; - -import com.github.tomakehurst.wiremock.core.WireMockConfiguration; -import com.squareup.okhttp.Cache; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.OkUrlFactory; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.SystemUtils; -import org.junit.Assume; -import org.junit.Before; -import org.junit.Test; -import org.kohsuke.github.AbstractGitHubWireMockTest; -import org.kohsuke.github.GHFileNotFoundException; -import org.kohsuke.github.GHIssueState; -import org.kohsuke.github.GHPullRequest; -import org.kohsuke.github.GHRef; -import org.kohsuke.github.GHRepository; -import org.kohsuke.github.GitHub; - -import java.io.File; -import java.io.IOException; - -import static org.junit.Assert.fail; - -// TODO: Auto-generated Javadoc -/** - * Test showing the behavior of OkHttpGitHubConnector cache with GitHub 404 responses. - * - * @author Liam Newman - */ -public class GitHubCachingTest extends AbstractGitHubWireMockTest { - - /** - * Instantiates a new git hub caching test. - */ - public GitHubCachingTest() { - useDefaultGitHub = false; - } - - /** The test ref name. */ - String testRefName = "heads/test/content_ref_cache"; - - /** - * Gets the wire mock options. - * - * @return the wire mock options - */ - @Override - protected WireMockConfiguration getWireMockOptions() { - return super.getWireMockOptions().extensions(templating.newResponseTransformer()); - } - - /** - * Setup repo. - * - * @throws Exception - * the exception - */ - @Before - public void setupRepo() throws Exception { - if (mockGitHub.isUseProxy()) { - for (GHPullRequest pr : getRepository(this.getNonRecordingGitHub()).getPullRequests(GHIssueState.OPEN)) { - pr.close(); - } - try { - GHRef ref = getRepository(this.getNonRecordingGitHub()).getRef(testRefName); - ref.delete(); - } catch (IOException e) { - } - } - } - - /** - * Test cached 404. - * - * @throws Exception - * the exception - */ - @Test - public void testCached404() throws Exception { - Assume.assumeFalse(SystemUtils.IS_OS_WINDOWS); - - // ISSUE #669 - snapshotNotAllowed(); - - OkHttpClient client = createClient(true); - OkHttpConnector connector = new OkHttpConnector(new OkUrlFactory(client)); - - this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withConnector(connector) - .build(); - - // Alternate client also doing caching but staying in a good state - // We use this to do sanity checks and other information gathering - GitHub gitHub2 = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withConnector(new OkHttpConnector(new OkUrlFactory(createClient(true)))) - .build(); - - // Create a branch from a known conflicting branch - GHRepository repo = getRepository(gitHub); - - String baseSha = repo.getRef("heads/test/unmergeable").getObject().getSha(); - - GHRef ref; - ref = repo.createRef("refs/" + testRefName, baseSha); - - // Verify we can query the created ref - ref = repo.getRef(testRefName); - - // Verify we can query the created ref from cache - ref = repo.getRef(testRefName); - - // Delete the ref - ref.delete(); - - // This is just to show this isn't a race condition - Thread.sleep(2000); - - // Try to get the non-existant ref (GHFileNotFound) - try { - repo.getRef(testRefName); - fail(); - } catch (GHFileNotFoundException e) { - // expected - - // FYI: Querying again when the item is actually not present does not produce a 304 - // It produces another 404, - // Try to get the non-existant ref (GHFileNotFound) - try { - repo.getRef(testRefName); - fail(); - } catch (GHFileNotFoundException ex) { - // expected - } - - } - - // This is just to show this isn't a race condition - Thread.sleep(2000); - - ref = repo.createRef("refs/" + testRefName, baseSha); - - // Verify ref exists and can be queried from uncached connection - // Expected: success - // Actual: still GHFileNotFound due to caching: GitHub incorrectly returns 304 - // even though contents of the ref have changed. - // - // There source of this issue seems to be that 404's do not return an ETAG, - // so the cache falls back to using "If-Modified-Since" which is erroneously returns a 304. - // - // NOTE: This is even worse than you might think: 404 responses don't return an ETAG, but 304 responses do. - // - // Due erroneous 304 returned from "If-Modified-Since", the ETAG returned by the first 304 - // is actually the ETAG for the NEW state of the ref query (the one where the ref exists). - // This can be verified by comparing the ETAG from gitHub2 client to the ETAG in error. - // - // This means that server thinks it telling the client that the new state is stable - // while the cache thinks it confirming the old state hasn't changed. - // - // So, after the first 304, the failure is locked in via ETAG and won't until the ref is modified again - // or until the cache ages out entry without the URL being requeried (which is why users report that refreshing - // is now help). - - try { - repo.getRef(testRefName); - } catch (GHFileNotFoundException e) { - // Sanity check: ref exists and can be queried from other client - getRepository(gitHub2).getRef(testRefName); - - // We're going to fail, query again to see the incorrect ETAG cached from first query being used - // It is the same ETAG as the one returned to the second client. - // Now we're in trouble. - repo.getRef(testRefName); - - // We should never fail the first query and pass the second, - // the test has still failed if it get here. - fail(); - } - - // OMG, the workaround succeeded! - // This correct response should be generated from a 304. - repo.getRef(testRefName); - } - - private static int clientCount = 0; - - private OkHttpClient createClient(boolean useCache) throws IOException { - OkHttpClient client = new OkHttpClient(); - - if (useCache) { - File cacheDir = new File( - "target/cache/" + baseFilesClassPath + "/" + mockGitHub.getMethodName() + clientCount++); - cacheDir.mkdirs(); - FileUtils.cleanDirectory(cacheDir); - Cache cache = new Cache(cacheDir, 100 * 1024L * 1024L); - - client.setCache(cache); - } - - return client; - } - - private static GHRepository getRepository(GitHub gitHub) throws IOException { - return gitHub.getOrganization("hub4j-test-org").getRepository("github-api"); - } - -} diff --git a/src/test/java/org/kohsuke/github/extras/OkHttpConnectorTest.java b/src/test/java/org/kohsuke/github/extras/OkHttpConnectorTest.java deleted file mode 100644 index 454c2fb032..0000000000 --- a/src/test/java/org/kohsuke/github/extras/OkHttpConnectorTest.java +++ /dev/null @@ -1,329 +0,0 @@ -package org.kohsuke.github.extras; - -import com.github.tomakehurst.wiremock.core.WireMockConfiguration; -import com.squareup.okhttp.Cache; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.OkUrlFactory; -import org.apache.commons.io.FileUtils; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.kohsuke.github.*; - -import java.io.File; -import java.io.IOException; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; -import static org.hamcrest.core.Is.is; -import static org.junit.Assume.assumeFalse; -import static org.junit.Assume.assumeTrue; - -// TODO: Auto-generated Javadoc -/** - * Test showing the behavior of OkHttpGitHubConnector with and without cache. - *

    - * Key take aways: - * - *

      - *
    • These tests are artificial and intended to highlight the differences in behavior between scenarios. However, the - * differences they indicate are stark.
    • - *
    • Caching reduces rate limit consumption by at least a factor of two in even the simplest case.
    • - *
    • The OkHttp cache is pretty smart and will often connect read and write requests made on the same client and - * invalidate caches.
    • - *
    • Changes made outside the current client cause the OkHttp cache to return stale data. This is expected and correct - * behavior.
    • - *
    • "max-age=0" addresses the problem of external changes by revalidating caches for each request. This produces the - * same number of requests as OkHttp without caching, but those requests only count towards the GitHub rate limit if - * data has changes.
    • - *
    - * - * @author Liam Newman - */ -public class OkHttpConnectorTest extends AbstractGitHubWireMockTest { - - /** - * Instantiates a new ok http connector test. - */ - public OkHttpConnectorTest() { - useDefaultGitHub = false; - } - - private static int defaultRateLimitUsed = 17; - private static int okhttpRateLimitUsed = 17; - private static int maxAgeZeroRateLimitUsed = 7; - private static int maxAgeThreeRateLimitUsed = 7; - private static int maxAgeNoneRateLimitUsed = 4; - - private static int userRequestCount = 0; - - private static int defaultNetworkRequestCount = 16; - private static int okhttpNetworkRequestCount = 16; - private static int maxAgeZeroNetworkRequestCount = 16; - private static int maxAgeThreeNetworkRequestCount = 9; - private static int maxAgeNoneNetworkRequestCount = 5; - - private static int maxAgeZeroHitCount = 10; - private static int maxAgeThreeHitCount = 10; - private static int maxAgeNoneHitCount = 11; - - private GHRateLimit rateLimitBefore; - - /** - * Gets the wire mock options. - * - * @return the wire mock options - */ - @Override - protected WireMockConfiguration getWireMockOptions() { - return super.getWireMockOptions().extensions(templating.newResponseTransformer()); - } - - /** - * Setup repo. - * - * @throws Exception - * the exception - */ - @Before - public void setupRepo() throws Exception { - if (mockGitHub.isUseProxy()) { - GHRepository repo = getRepository(getNonRecordingGitHub()); - repo.setDescription("Resetting"); - - // Let things settle a bit between tests when working against the live site - Thread.sleep(5000); - userRequestCount = 1; - } - } - - /** - * Default connector. - * - * @throws Exception - * the exception - */ - @Test - public void DefaultConnector() throws Exception { - - this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()).build(); - - doTestActions(); - - // Testing behavior after change - // Uncached connection gets updated correctly but at cost of rate limit - assertThat(getRepository(gitHub).getDescription(), is("Tricky")); - - checkRequestAndLimit(defaultNetworkRequestCount, defaultRateLimitUsed); - } - - /** - * Ok http connector no cache. - * - * @throws Exception - * the exception - */ - @Test - public void OkHttpConnector_NoCache() throws Exception { - - OkHttpClient client = createClient(false); - OkHttpConnector connector = new OkHttpConnector(new OkUrlFactory(client)); - - this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withConnector(connector) - .build(); - - doTestActions(); - - // Testing behavior after change - // Uncached okhttp connection gets updated correctly but at cost of rate limit - assertThat(getRepository(gitHub).getDescription(), is("Tricky")); - - checkRequestAndLimit(okhttpNetworkRequestCount, okhttpRateLimitUsed); - - Cache cache = client.getCache(); - assertThat("Cache", cache, is(nullValue())); - } - - /** - * Ok http connector cache max age none. - * - * @throws Exception - * the exception - */ - @Test - public void OkHttpConnector_Cache_MaxAgeNone() throws Exception { - // The responses were recorded from github, but the Date headers - // have been templated to make caching behavior work as expected. - // This is reasonable as long as the number of network requests matches up. - snapshotNotAllowed(); - - OkHttpClient client = createClient(true); - OkHttpConnector connector = new OkHttpConnector(new OkUrlFactory(client), -1); - - this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withConnector(connector) - .build(); - - doTestActions(); - - // Testing behavior after change - // NOTE: this is wrong! The live data changed! - // Due to max-age (default 60 from response) the cache returns the old data. - assertThat(getRepository(gitHub).getDescription(), is(mockGitHub.getMethodName())); - - checkRequestAndLimit(maxAgeNoneNetworkRequestCount, maxAgeNoneRateLimitUsed); - - Cache cache = client.getCache(); - - // NOTE: this is actually bad. - // This elevated hit count is the stale requests returning bad data took longer to detect a change. - assertThat("getHitCount", cache.getHitCount(), is(maxAgeNoneHitCount)); - } - - /** - * Ok http connector cache max age three. - * - * @throws Exception - * the exception - */ - @Test - public void OkHttpConnector_Cache_MaxAge_Three() throws Exception { - - // NOTE: This test is very timing sensitive. - // It can be run locally to verify behavior but snapshot data is to touchy - assumeFalse("Test only valid when not taking a snapshot", mockGitHub.isTakeSnapshot()); - assumeTrue("Test only valid when proxying (-Dtest.github.useProxy to enable)", mockGitHub.isUseProxy()); - - OkHttpClient client = createClient(true); - OkHttpConnector connector = new OkHttpConnector(new OkUrlFactory(client), 3); - - this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withConnector(connector) - .build(); - - doTestActions(); - - // Due to max-age=3 this eventually checks the site and gets updated information. Yay? - assertThat(getRepository(gitHub).getDescription(), is("Tricky")); - - checkRequestAndLimit(maxAgeThreeNetworkRequestCount, maxAgeThreeRateLimitUsed); - - Cache cache = client.getCache(); - assertThat("getHitCount", cache.getHitCount(), is(maxAgeThreeHitCount)); - } - - /** - * Ok http connector cache max age default zero. - * - * @throws Exception - * the exception - */ - @Ignore("ISSUE #597 - Correctly formatted Last-Modified headers cause this test to fail") - @Test - public void OkHttpConnector_Cache_MaxAgeDefault_Zero() throws Exception { - // The responses were recorded from github, but the Date headers - // have been templated to make caching behavior work as expected. - // This is reasonable as long as the number of network requests matches up. - snapshotNotAllowed(); - - OkHttpClient client = createClient(true); - OkHttpConnector connector = new OkHttpConnector(new OkUrlFactory(client)); - - this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withConnector(connector) - .build(); - - doTestActions(); - - // Testing behavior after change - // NOTE: max-age=0 produces the same result at uncached without added rate-limit use. - assertThat(getRepository(gitHub).getDescription(), is("Tricky")); - - checkRequestAndLimit(maxAgeZeroNetworkRequestCount, maxAgeZeroRateLimitUsed); - - Cache cache = client.getCache(); - assertThat("getHitCount", cache.getHitCount(), is(maxAgeZeroHitCount)); - } - - private void checkRequestAndLimit(int networkRequestCount, int rateLimitUsed) throws IOException { - GHRateLimit rateLimitAfter = gitHub.rateLimit(); - assertThat("Request Count", mockGitHub.getRequestCount(), is(networkRequestCount + userRequestCount)); - - // Rate limit must be under this value, but if it wiggles we don't care - assertThat("Rate Limit Change", - rateLimitBefore.remaining - rateLimitAfter.remaining, - is(lessThanOrEqualTo(rateLimitUsed + userRequestCount))); - - } - - private OkHttpClient createClient(boolean useCache) throws IOException { - OkHttpClient client = new OkHttpClient(); - - if (useCache) { - File cacheDir = new File("target/cache/" + baseFilesClassPath + "/" + mockGitHub.getMethodName()); - cacheDir.mkdirs(); - FileUtils.cleanDirectory(cacheDir); - Cache cache = new Cache(cacheDir, 100 * 1024L * 1024L); - - client.setCache(cache); - } - - return client; - } - - /** - * This is a standard set of actions to be performed with each connector - * - * @throws Exception - */ - private void doTestActions() throws Exception { - rateLimitBefore = gitHub.getRateLimit(); - - String name = mockGitHub.getMethodName(); - - GHRepository repo = getRepository(gitHub); - - // Testing behavior when nothing has changed. - pollForChange("Resetting"); - assertThat(getRepository(gitHub).getDescription(), is("Resetting")); - - repo.setDescription(name); - - pollForChange(name); - - // Test behavior after change - assertThat(getRepository(gitHub).getDescription(), is(name)); - - // Get Tricky - make a change via a different client - if (mockGitHub.isUseProxy()) { - GHRepository altRepo = getRepository(getNonRecordingGitHub()); - altRepo.setDescription("Tricky"); - } - - // Testing behavior after change - pollForChange("Tricky"); - } - - private void pollForChange(String name) throws IOException, InterruptedException { - getRepository(gitHub).getDescription(); - Thread.sleep(500); - getRepository(gitHub).getDescription(); - // This is only interesting when running the max-age=3 test which currently only runs with proxy - // Disabled to speed up the tests - if (mockGitHub.isUseProxy()) { - Thread.sleep(1000); - } - getRepository(gitHub).getDescription(); - // This is only interesting when running the max-age=3 test which currently only runs with proxy - // Disabled to speed up the tests - if (mockGitHub.isUseProxy()) { - Thread.sleep(4000); - } - } - - private static GHRepository getRepository(GitHub gitHub) throws IOException { - return gitHub.getOrganization("hub4j-test-org").getRepository("github-api"); - } - -} diff --git a/src/test/java/org/kohsuke/github/extras/authorization/AuthorizationTokenRefreshTest.java b/src/test/java/org/kohsuke/github/extras/authorization/AuthorizationTokenRefreshTest.java index 55c2431685..00b268912b 100644 --- a/src/test/java/org/kohsuke/github/extras/authorization/AuthorizationTokenRefreshTest.java +++ b/src/test/java/org/kohsuke/github/extras/authorization/AuthorizationTokenRefreshTest.java @@ -4,7 +4,7 @@ import org.junit.Test; import org.kohsuke.github.AbstractGitHubWireMockTest; import org.kohsuke.github.GHUser; -import org.kohsuke.github.RateLimitHandler; +import org.kohsuke.github.GitHubRateLimitHandler; import org.kohsuke.github.authorization.AuthorizationProvider; import java.io.IOException; @@ -42,7 +42,7 @@ public void testNewWhenOldOneExpires() throws IOException { snapshotNotAllowed(); gitHub = getGitHubBuilder().withAuthorizationProvider(new RefreshingAuthorizationProvider()) .withEndpoint(mockGitHub.apiServer().baseUrl()) - .withRateLimitHandler(RateLimitHandler.WAIT) + .withRateLimitHandler(GitHubRateLimitHandler.WAIT) .build(); final GHUser kohsuke = gitHub.getUser("kohsuke"); assertThat("Usernames match", "kohsuke".equals(kohsuke.getLogin())); @@ -58,7 +58,7 @@ public void testNewWhenOldOneExpires() throws IOException { public void testNotNewWhenOldOneIsStillValid() throws IOException { gitHub = getGitHubBuilder().withAuthorizationProvider(() -> "original token") .withEndpoint(mockGitHub.apiServer().baseUrl()) - .withRateLimitHandler(RateLimitHandler.WAIT) + .withRateLimitHandler(GitHubRateLimitHandler.WAIT) .build(); final GHUser kohsuke = gitHub.getUser("kohsuke"); assertThat("Usernames match", "kohsuke".equals(kohsuke.getLogin())); diff --git a/src/test/java/org/kohsuke/github/extras/okhttp3/GitHubCachingTest.java b/src/test/java/org/kohsuke/github/extras/okhttp3/GitHubCachingTest.java index 9694f25eb8..f66717f31a 100644 --- a/src/test/java/org/kohsuke/github/extras/okhttp3/GitHubCachingTest.java +++ b/src/test/java/org/kohsuke/github/extras/okhttp3/GitHubCachingTest.java @@ -61,7 +61,10 @@ protected WireMockConfiguration getWireMockOptions() { @Before public void setupRepo() throws Exception { if (mockGitHub.isUseProxy()) { - for (GHPullRequest pr : getRepository(this.getNonRecordingGitHub()).getPullRequests(GHIssueState.OPEN)) { + for (GHPullRequest pr : getRepository(this.getNonRecordingGitHub()).queryPullRequests() + .state(GHIssueState.OPEN) + .list() + .toList()) { pr.close(); } try { diff --git a/src/test/java/org/kohsuke/github/extras/okhttp3/OkHttpConnectorTest.java b/src/test/java/org/kohsuke/github/extras/okhttp3/OkHttpConnectorTest.java deleted file mode 100644 index 470147f2e1..0000000000 --- a/src/test/java/org/kohsuke/github/extras/okhttp3/OkHttpConnectorTest.java +++ /dev/null @@ -1,348 +0,0 @@ -package org.kohsuke.github.extras.okhttp3; - -import com.github.tomakehurst.wiremock.core.WireMockConfiguration; -import com.github.tomakehurst.wiremock.matching.RequestPatternBuilder; -import okhttp3.Cache; -import okhttp3.OkHttpClient; -import org.apache.commons.io.FileUtils; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.kohsuke.github.AbstractGitHubWireMockTest; -import org.kohsuke.github.GHRateLimit; -import org.kohsuke.github.GHRepository; -import org.kohsuke.github.GitHub; - -import java.io.File; -import java.io.IOException; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.lessThanOrEqualTo; -import static org.hamcrest.Matchers.nullValue; -import static org.hamcrest.core.Is.is; -import static org.junit.Assume.assumeFalse; -import static org.junit.Assume.assumeTrue; - -// TODO: Auto-generated Javadoc -/** - * Test showing the behavior of OkHttpConnector with and without cache. - *

    - * Key take aways: - * - *

      - *
    • These tests are artificial and intended to highlight the differences in behavior between scenarios. However, the - * differences they indicate are stark.
    • - *
    • Caching reduces rate limit consumption by at least a factor of two in even the simplest case.
    • - *
    • The OkHttp cache is pretty smart and will often connect read and write requests made on the same client and - * invalidate caches.
    • - *
    • Changes made outside the current client cause the OkHttp cache to return stale data. This is expected and correct - * behavior.
    • - *
    • "max-age=0" addresses the problem of external changes by revalidating caches for each request. This produces the - * same number of requests as OkHttp without caching, but those requests only count towards the GitHub rate limit if - * data has changes.
    • - *
    - * - * @author Liam Newman - */ -public class OkHttpConnectorTest extends AbstractGitHubWireMockTest { - - /** - * Instantiates a new ok http connector test. - */ - public OkHttpConnectorTest() { - useDefaultGitHub = false; - } - - private static int defaultRateLimitUsed = 17; - private static int okhttpRateLimitUsed = 17; - private static int maxAgeZeroRateLimitUsed = 7; - private static int maxAgeThreeRateLimitUsed = 7; - private static int maxAgeNoneRateLimitUsed = 4; - - private static int userRequestCount = 0; - - private static int defaultNetworkRequestCount = 16; - private static int okhttpNetworkRequestCount = 16; - private static int maxAgeZeroNetworkRequestCount = 16; - private static int maxAgeThreeNetworkRequestCount = 9; - private static int maxAgeNoneNetworkRequestCount = 5; - - private static int maxAgeZeroHitCount = 10; - private static int maxAgeThreeHitCount = 10; - private static int maxAgeNoneHitCount = 11; - - private GHRateLimit rateLimitBefore; - private Cache cache = null; - - /** - * Gets the wire mock options. - * - * @return the wire mock options - */ - @Override - protected WireMockConfiguration getWireMockOptions() { - return super.getWireMockOptions() - // Use the same data files as the 2.x test - .usingFilesUnderDirectory(baseRecordPath.replace("/okhttp3/", "/")) - .extensions(templating.newResponseTransformer()); - } - - /** - * Setup repo. - * - * @throws Exception - * the exception - */ - @Before - public void setupRepo() throws Exception { - if (mockGitHub.isUseProxy()) { - GHRepository repo = getRepository(getNonRecordingGitHub()); - repo.setDescription("Resetting"); - - // Let things settle a bit between tests when working against the live site - Thread.sleep(5000); - userRequestCount = 1; - } - } - - /** - * Delete cache. - * - * @throws IOException - * Signals that an I/O exception has occurred. - */ - @After - public void deleteCache() throws IOException { - if (cache != null) { - cache.delete(); - } - } - - /** - * Default connector. - * - * @throws Exception - * the exception - */ - @Test - public void DefaultConnector() throws Exception { - - this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()).build(); - - doTestActions(); - - // Testing behavior after change - // Uncached connection gets updated correctly but at cost of rate limit - assertThat(getRepository(gitHub).getDescription(), is("Tricky")); - - checkRequestAndLimit(defaultNetworkRequestCount, defaultRateLimitUsed); - } - - /** - * Ok http connector no cache. - * - * @throws Exception - * the exception - */ - @Test - public void OkHttpConnector_NoCache() throws Exception { - - OkHttpClient client = createClient(false); - OkHttpConnector connector = new OkHttpConnector(client); - - this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withConnector(connector) - .build(); - - doTestActions(); - - // Testing behavior after change - // Uncached okhttp connection gets updated correctly but at cost of rate limit - assertThat(getRepository(gitHub).getDescription(), is("Tricky")); - - checkRequestAndLimit(okhttpNetworkRequestCount, okhttpRateLimitUsed); - - assertThat("Cache", cache, is(nullValue())); - } - - /** - * Ok http connector cache max age none. - * - * @throws Exception - * the exception - */ - @Test - public void OkHttpConnector_Cache_MaxAgeNone() throws Exception { - // The responses were recorded from github, but the Date headers - // have been templated to make caching behavior work as expected. - // This is reasonable as long as the number of network requests matches up. - snapshotNotAllowed(); - - OkHttpClient client = createClient(true); - OkHttpConnector connector = new OkHttpConnector(client, -1); - - this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withConnector(connector) - .build(); - - doTestActions(); - - // Testing behavior after change - // NOTE: this is wrong! The live data changed! - // Due to max-age (default 60 from response) the cache returns the old data. - assertThat(getRepository(gitHub).getDescription(), is(mockGitHub.getMethodName())); - - checkRequestAndLimit(maxAgeNoneNetworkRequestCount, maxAgeNoneRateLimitUsed); - - // NOTE: this is actually bad. - // This elevated hit count is the stale requests returning bad data took longer to detect a change. - assertThat("getHitCount", cache.hitCount(), is(maxAgeNoneHitCount)); - } - - /** - * Ok http connector cache max age three. - * - * @throws Exception - * the exception - */ - @Test - public void OkHttpConnector_Cache_MaxAge_Three() throws Exception { - - // NOTE: This test is very timing sensitive. - // It can be run locally to verify behavior but snapshot data is to touchy - assumeFalse("Test only valid when not taking a snapshot", mockGitHub.isTakeSnapshot()); - assumeTrue("Test only valid when proxying (-Dtest.github.useProxy to enable)", mockGitHub.isUseProxy()); - - OkHttpClient client = createClient(true); - OkHttpConnector connector = new OkHttpConnector(client, 3); - - this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withConnector(connector) - .build(); - - doTestActions(); - - // Due to max-age=3 this eventually checks the site and gets updated information. Yay? - assertThat(getRepository(gitHub).getDescription(), is("Tricky")); - - checkRequestAndLimit(maxAgeThreeNetworkRequestCount, maxAgeThreeRateLimitUsed); - - assertThat("getHitCount", cache.hitCount(), is(maxAgeThreeHitCount)); - } - - /** - * Ok http connector cache max age default zero. - * - * @throws Exception - * the exception - */ - @Test - public void OkHttpConnector_Cache_MaxAgeDefault_Zero() throws Exception { - // The responses were recorded from github, but the Date headers - // have been templated to make caching behavior work as expected. - // This is reasonable as long as the number of network requests matches up. - snapshotNotAllowed(); - - OkHttpClient client = createClient(true); - OkHttpConnector connector = new OkHttpConnector(client); - - this.gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) - .withConnector(connector) - .build(); - - doTestActions(); - - // Testing behavior after change - // NOTE: max-age=0 produces the same result at uncached without added rate-limit use. - assertThat(getRepository(gitHub).getDescription(), is("Tricky")); - - checkRequestAndLimit(maxAgeZeroNetworkRequestCount, maxAgeZeroRateLimitUsed); - - assertThat("getHitCount", cache.hitCount(), is(maxAgeZeroHitCount)); - } - - private void checkRequestAndLimit(int networkRequestCount, int rateLimitUsed) throws IOException { - GHRateLimit rateLimitAfter = gitHub.rateLimit(); - assertThat("Request Count", getRequestCount(), is(networkRequestCount + userRequestCount)); - - // Rate limit must be under this value, but if it wiggles we don't care - assertThat("Rate Limit Change", - rateLimitBefore.remaining - rateLimitAfter.remaining, - is(lessThanOrEqualTo(rateLimitUsed + userRequestCount))); - - } - - private int getRequestCount() { - return mockGitHub.apiServer().countRequestsMatching(RequestPatternBuilder.allRequests().build()).getCount(); - } - - private OkHttpClient createClient(boolean useCache) throws IOException { - OkHttpClient.Builder builder = new OkHttpClient().newBuilder(); - - if (useCache) { - File cacheDir = new File("target/cache/" + baseFilesClassPath + "/" + mockGitHub.getMethodName()); - cacheDir.mkdirs(); - FileUtils.cleanDirectory(cacheDir); - cache = new Cache(cacheDir, 100 * 1024L * 1024L); - - builder.cache(cache); - } - - return builder.build(); - } - - /** - * This is a standard set of actions to be performed with each connector - * - * @throws Exception - */ - private void doTestActions() throws Exception { - rateLimitBefore = gitHub.getRateLimit(); - - String name = mockGitHub.getMethodName(); - - GHRepository repo = getRepository(gitHub); - - // Testing behavior when nothing has changed. - pollForChange("Resetting"); - assertThat(getRepository(gitHub).getDescription(), is("Resetting")); - - repo.setDescription(name); - - pollForChange(name); - - // Test behavior after change - assertThat(getRepository(gitHub).getDescription(), is(name)); - - // Get Tricky - make a change via a different client - if (mockGitHub.isUseProxy()) { - GHRepository altRepo = getRepository(getNonRecordingGitHub()); - altRepo.setDescription("Tricky"); - } - - // Testing behavior after change - pollForChange("Tricky"); - } - - private void pollForChange(String name) throws IOException, InterruptedException { - getRepository(gitHub).getDescription(); - Thread.sleep(500); - getRepository(gitHub).getDescription(); - // This is only interesting when running the max-age=3 test which currently only runs with proxy - // Disabled to speed up the tests - if (mockGitHub.isUseProxy()) { - Thread.sleep(1000); - } - getRepository(gitHub).getDescription(); - // This is only interesting when running the max-age=3 test which currently only runs with proxy - // Disabled to speed up the tests - if (mockGitHub.isUseProxy()) { - Thread.sleep(4000); - } - } - - private static GHRepository getRepository(GitHub gitHub) throws IOException { - return gitHub.getOrganization("hub4j-test-org").getRepository("github-api"); - } - -} diff --git a/src/test/java/org/kohsuke/github/extras/okhttp3/OkHttpGitHubConnectorTest.java b/src/test/java/org/kohsuke/github/extras/okhttp3/OkHttpGitHubConnectorTest.java index 678e001796..d21e853bc3 100644 --- a/src/test/java/org/kohsuke/github/extras/okhttp3/OkHttpGitHubConnectorTest.java +++ b/src/test/java/org/kohsuke/github/extras/okhttp3/OkHttpGitHubConnectorTest.java @@ -261,12 +261,12 @@ public void OkHttpConnector_Cache_MaxAgeDefault_Zero() throws Exception { } private void checkRequestAndLimit(int networkRequestCount, int rateLimitUsed) throws IOException { - GHRateLimit rateLimitAfter = gitHub.rateLimit(); + GHRateLimit rateLimitAfter = gitHub.lastRateLimit(); assertThat("Request Count", getRequestCount(), is(networkRequestCount + userRequestCount)); // Rate limit must be under this value, but if it wiggles we don't care assertThat("Rate Limit Change", - rateLimitBefore.remaining - rateLimitAfter.remaining, + rateLimitBefore.getRemaining() - rateLimitAfter.getRemaining(), is(lessThanOrEqualTo(rateLimitUsed + userRequestCount))); } diff --git a/src/test/java/org/kohsuke/github/internal/DefaultGitHubConnectorTest.java b/src/test/java/org/kohsuke/github/internal/DefaultGitHubConnectorTest.java index 997298debb..a3fcb894f6 100644 --- a/src/test/java/org/kohsuke/github/internal/DefaultGitHubConnectorTest.java +++ b/src/test/java/org/kohsuke/github/internal/DefaultGitHubConnectorTest.java @@ -4,12 +4,10 @@ import org.junit.Test; import org.kohsuke.github.AbstractGitHubWireMockTest; import org.kohsuke.github.GitHubBuilder; -import org.kohsuke.github.HttpConnector; import org.kohsuke.github.connector.GitHubConnector; import org.kohsuke.github.connector.GitHubConnectorRequest; import org.kohsuke.github.connector.GitHubConnectorResponse; import org.kohsuke.github.extras.HttpClientGitHubConnector; -import org.kohsuke.github.extras.okhttp3.OkHttpConnector; import java.io.IOException; @@ -37,55 +35,23 @@ public DefaultGitHubConnectorTest() { @Test public void testCreate() throws Exception { GitHubConnector connector; - GitHubConnectorHttpConnectorAdapter adapter; - boolean usingHttpClient = false; - try { - connector = DefaultGitHubConnector.create("httpclient"); - assertThat(connector, instanceOf(HttpClientGitHubConnector.class)); - usingHttpClient = true; - } catch (UnsupportedOperationException e) { - assertThat(e.getMessage(), equalTo("java.net.http.HttpClient is only supported in Java 11+.")); - } + connector = DefaultGitHubConnector.create("httpclient"); + assertThat(connector, instanceOf(HttpClientGitHubConnector.class)); connector = DefaultGitHubConnector.create("default"); - if (usingHttpClient) { - assertThat(connector, instanceOf(HttpClientGitHubConnector.class)); - } else { - assertThat(connector, instanceOf(GitHubConnectorHttpConnectorAdapter.class)); - adapter = (GitHubConnectorHttpConnectorAdapter) connector; - assertThat(adapter.httpConnector, equalTo(HttpConnector.DEFAULT)); - } - - connector = DefaultGitHubConnector.create("urlconnection"); - assertThat(connector, instanceOf(GitHubConnectorHttpConnectorAdapter.class)); - adapter = (GitHubConnectorHttpConnectorAdapter) connector; - assertThat(adapter.httpConnector, equalTo(HttpConnector.DEFAULT)); - - connector = DefaultGitHubConnector.create("okhttpconnector"); - assertThat(connector, instanceOf(GitHubConnectorHttpConnectorAdapter.class)); - adapter = (GitHubConnectorHttpConnectorAdapter) connector; - assertThat(adapter.httpConnector, instanceOf(OkHttpConnector.class)); + assertThat(connector, instanceOf(HttpClientGitHubConnector.class)); connector = DefaultGitHubConnector.create("okhttp"); Assert.assertThrows(IllegalStateException.class, () -> DefaultGitHubConnector.create("")); - assertThat(GitHubConnectorHttpConnectorAdapter.adapt(HttpConnector.DEFAULT), - sameInstance(GitHubConnector.DEFAULT)); - assertThat(GitHubConnectorHttpConnectorAdapter.adapt(HttpConnector.OFFLINE), - sameInstance(GitHubConnector.OFFLINE)); - gitHub = new GitHubBuilder().withConnector(new GitHubConnector() { @Override public GitHubConnectorResponse send(GitHubConnectorRequest connectorRequest) throws IOException { throw new IOException(); } }).build(); - Assert.assertThrows(UnsupportedOperationException.class, () -> gitHub.getConnector()); - gitHub.setConnector((HttpConnector) GitHubConnector.OFFLINE); - // Doesn't throw when HttpConnect is implemented - gitHub.getConnector(); } } diff --git a/src/test/resources/no-reflect-and-serialization-list b/src/test/resources/no-reflect-and-serialization-list index 4da5b76fe7..705a18d5e2 100644 --- a/src/test/resources/no-reflect-and-serialization-list +++ b/src/test/resources/no-reflect-and-serialization-list @@ -18,6 +18,8 @@ org.kohsuke.github.GitHub org.kohsuke.github.GitHub$DependentAuthorizationProvider org.kohsuke.github.GitHub$LoginLoadingUserAuthorizationProvider org.kohsuke.github.GitHubAbuseLimitHandler +org.kohsuke.github.GitHubAbuseLimitHandler$1 +org.kohsuke.github.GitHubAbuseLimitHandler$2 org.kohsuke.github.GitHubClient org.kohsuke.github.GitHubClient$BodyHandler org.kohsuke.github.GitHubClient$GHApiInfo @@ -26,6 +28,8 @@ org.kohsuke.github.GitHubConnectorResponseErrorHandler org.kohsuke.github.GitHubPageIterator org.kohsuke.github.GitHubRateLimitChecker org.kohsuke.github.GitHubRateLimitHandler +org.kohsuke.github.GitHubRateLimitHandler$1 +org.kohsuke.github.GitHubRateLimitHandler$2 org.kohsuke.github.HttpConnector org.kohsuke.github.HttpException org.kohsuke.github.PagedIterator @@ -44,6 +48,7 @@ org.kohsuke.github.authorization.ImmutableAuthorizationProvider$UserProvider org.kohsuke.github.authorization.OrgAppInstallationAuthorizationProvider org.kohsuke.github.authorization.UserAuthorizationProvider org.kohsuke.github.connector.GitHubConnector +org.kohsuke.github.connector.GitHubConnector$1 org.kohsuke.github.connector.GitHubConnectorRequest org.kohsuke.github.connector.GitHubConnectorResponse org.kohsuke.github.connector.GitHubConnectorResponse$ByteArrayResponse @@ -63,18 +68,7 @@ org.kohsuke.github.extras.authorization.JwtBuilderUtil$IJwtBuilder org.kohsuke.github.extras.authorization.JwtBuilderUtil$ReflectionBuilderImpl org.kohsuke.github.extras.authorization.JWTTokenProvider org.kohsuke.github.extras.HttpClientGitHubConnector -org.kohsuke.github.extras.okhttp3.ObsoleteUrlFactory$1 -org.kohsuke.github.extras.okhttp3.ObsoleteUrlFactory$BufferedRequestBody -org.kohsuke.github.extras.okhttp3.ObsoleteUrlFactory -org.kohsuke.github.extras.okhttp3.ObsoleteUrlFactory$DelegatingHttpsURLConnection -org.kohsuke.github.extras.okhttp3.ObsoleteUrlFactory$OkHttpsURLConnection -org.kohsuke.github.extras.okhttp3.ObsoleteUrlFactory$OkHttpURLConnection -org.kohsuke.github.extras.okhttp3.ObsoleteUrlFactory$OkHttpURLConnection$NetworkInterceptor -org.kohsuke.github.extras.okhttp3.ObsoleteUrlFactory$OutputStreamRequestBody$1 -org.kohsuke.github.extras.okhttp3.ObsoleteUrlFactory$OutputStreamRequestBody -org.kohsuke.github.extras.okhttp3.ObsoleteUrlFactory$ResponseBodyInputStream -org.kohsuke.github.extras.okhttp3.ObsoleteUrlFactory$StreamedRequestBody -org.kohsuke.github.extras.okhttp3.ObsoleteUrlFactory$UnexpectedException +org.kohsuke.github.extras.HttpClientGitHubConnector$HttpClientGitHubConnectorResponse org.kohsuke.github.extras.okhttp3.OkHttpConnector org.kohsuke.github.extras.okhttp3.OkHttpGitHubConnector org.kohsuke.github.extras.okhttp3.OkHttpGitHubConnector$OkHttpGitHubConnectorResponse @@ -85,7 +79,5 @@ org.kohsuke.github.function.InputStreamFunction org.kohsuke.github.function.SupplierThrows org.kohsuke.github.internal.DefaultGitHubConnector org.kohsuke.github.internal.EnumUtils -org.kohsuke.github.internal.GitHubConnectorHttpConnectorAdapter -org.kohsuke.github.internal.GitHubConnectorHttpConnectorAdapter$HttpURLConnectionGitHubConnectorResponse org.kohsuke.github.internal.Previews org.kohsuke.github.EnterpriseManagedSupport \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests/mappings/2-r_h_t_fail.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests/mappings/2-r_h_t_fail.json index d1127227f9..39bc810022 100644 --- a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests/mappings/2-r_h_t_fail.json +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests/mappings/2-r_h_t_fail.json @@ -11,17 +11,14 @@ } }, "response": { - "status": 403, + "status": 429, "body": "{\"message\":\"You have exceeded a secondary rate limit. Please wait a few minutes before you try again\"}", "headers": { "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}", "Content-Type": "application/json; charset=utf-8", "Server": "GitHub.com", - "Status": "403 Forbidden", - "gh-limited-by": "search-elapsed-time-shared-grouped", - "X-RateLimit-Limit": "5000", - "X-RateLimit-Remaining": "4000", - "X-RateLimit-Reset": "{{testStartDate offset='3 seconds' format='unix'}}", + "Status": "429 Too Many Requests", + "Retry-After": "8", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": [ "Accept, Authorization, Cookie, X-GitHub-OTP", @@ -45,8 +42,8 @@ }, "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", "persistent": true, - "scenarioName": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests", + "scenarioName": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits1", "requiredScenarioState": "Started", - "newScenarioState": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests-2", + "newScenarioState": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits1-2", "insertionIndex": 2 } \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests/mappings/3-r_h_t_fail.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests/mappings/3-r_h_t_fail.json index a2dc66b59d..643ed2e9db 100644 --- a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests/mappings/3-r_h_t_fail.json +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests/mappings/3-r_h_t_fail.json @@ -1,5 +1,5 @@ { - "id": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "id": "574da117-6845-46d8-b2c1-4415546ca670", "name": "repos_hub4j-test-org_temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests", "request": { "url": "/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests", @@ -11,21 +11,23 @@ } }, "response": { - "status": 429, - "body": "{\"message\":\"You have exceeded a secondary rate limit. Please wait a few minutes before you try again\"}", + "status": 200, + "bodyFileName": "3-r_h_t_fail.json", "headers": { "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}", "Content-Type": "application/json; charset=utf-8", "Server": "GitHub.com", - "Status": "429 Too Many Requests", - "Retry-After": "42", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4922", + "X-RateLimit-Reset": "{{testStartDate offset='3 seconds' format='unix'}}", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": [ "Accept, Authorization, Cookie, X-GitHub-OTP", "Accept-Encoding" ], - "ETag": "W/\"7ff3c96399f7ddf6129622d675ca9935\"", - "Last-Modified": "Thu, 06 Feb 2020 18:33:37 GMT", + "ETag": "W/\"858224998ac7d1fd6dcd43f73d375297\"", + "Last-Modified": "Thu, 06 Feb 2020 18:33:43 GMT", "X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion", "X-Accepted-OAuth-Scopes": "repo", "X-GitHub-Media-Type": "unknown, github.v3", @@ -37,13 +39,12 @@ "X-XSS-Protection": "1; mode=block", "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", "Content-Security-Policy": "default-src 'none'", - "X-GitHub-Request-Id": "CC37:2605:3F982:4E949:5E3C5BFC" + "X-GitHub-Request-Id": "CC37:2605:3FADC:4EA8C:5E3C5C02" } }, - "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "uuid": "574da117-6845-46d8-b2c1-4415546ca670", "persistent": true, - "scenarioName": "scenario-4-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests", - "requiredScenarioState": "Started", - "newScenarioState": "scenario-4-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests-2", - "insertionIndex": 2 + "scenarioName": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits1", + "requiredScenarioState": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits1-2", + "insertionIndex": 3 } \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After/mappings/2-r_h_t_fail.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After/mappings/2-r_h_t_fail.json index 41af8b707d..4d22b7d4bf 100644 --- a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After/mappings/2-r_h_t_fail.json +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After/mappings/2-r_h_t_fail.json @@ -11,17 +11,14 @@ } }, "response": { - "status": 403, + "status": 429, "body": "{\"message\":\"You have exceeded a secondary rate limit. Please wait a few minutes before you try again\"}", "headers": { "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}", "Content-Type": "application/json; charset=utf-8", "Server": "GitHub.com", - "Status": "403 Forbidden", - "gh-limited-by": "search-elapsed-time-shared-grouped", - "X-RateLimit-Limit": "5000", - "X-RateLimit-Remaining": "4000", - "X-RateLimit-Reset": "{{testStartDate offset='3 seconds' format='unix'}}", + "Status": "429 Too Many Requests", + "Retry-After": "{{now offset='8 seconds' timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": [ "Accept, Authorization, Cookie, X-GitHub-OTP", @@ -45,8 +42,8 @@ }, "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", "persistent": true, - "scenarioName": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After", + "scenarioName": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits2", "requiredScenarioState": "Started", - "newScenarioState": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After-2", + "newScenarioState": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits2-2", "insertionIndex": 2 } \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After/mappings/3-r_h_t_fail.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After/mappings/3-r_h_t_fail.json index a29ef6ac2d..f433290eab 100644 --- a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After/mappings/3-r_h_t_fail.json +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After/mappings/3-r_h_t_fail.json @@ -1,5 +1,5 @@ { - "id": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "id": "574da117-6845-46d8-b2c1-4415546ca670", "name": "repos_hub4j-test-org_temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After", "request": { "url": "/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After", @@ -11,21 +11,23 @@ } }, "response": { - "status": 429, - "body": "{\"message\":\"You have exceeded a secondary rate limit. Please wait a few minutes before you try again\"}", + "status": 200, + "bodyFileName": "3-r_h_t_fail.json", "headers": { "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}", "Content-Type": "application/json; charset=utf-8", "Server": "GitHub.com", - "Status": "429 Too Many Requests", - "Retry-After": "Mon, 21 Oct 2115 07:28:00 GMT", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4922", + "X-RateLimit-Reset": "{{testStartDate offset='3 seconds' format='unix'}}", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": [ "Accept, Authorization, Cookie, X-GitHub-OTP", "Accept-Encoding" ], - "ETag": "W/\"7ff3c96399f7ddf6129622d675ca9935\"", - "Last-Modified": "Thu, 06 Feb 2020 18:33:37 GMT", + "ETag": "W/\"858224998ac7d1fd6dcd43f73d375297\"", + "Last-Modified": "Thu, 06 Feb 2020 18:33:43 GMT", "X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion", "X-Accepted-OAuth-Scopes": "repo", "X-GitHub-Media-Type": "unknown, github.v3", @@ -37,13 +39,12 @@ "X-XSS-Protection": "1; mode=block", "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", "Content-Security-Policy": "default-src 'none'", - "X-GitHub-Request-Id": "CC37:2605:3F982:4E949:5E3C5BFC" + "X-GitHub-Request-Id": "CC37:2605:3FADC:4EA8C:5E3C5C02" } }, - "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "uuid": "574da117-6845-46d8-b2c1-4415546ca670", "persistent": true, - "scenarioName": "scenario-4-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After", - "requiredScenarioState": "Started", - "newScenarioState": "scenario-4-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_Date_Retry_After-2", - "insertionIndex": 2 + "scenarioName": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits2", + "requiredScenarioState": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits2-2", + "insertionIndex": 3 } \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After/mappings/2-r_h_t_fail.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After/mappings/2-r_h_t_fail.json new file mode 100644 index 0000000000..f5e2fd8e29 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After/mappings/2-r_h_t_fail.json @@ -0,0 +1,49 @@ +{ + "id": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "name": "repos_hub4j-test-org_temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After", + "request": { + "url": "/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "application/vnd.github+json" + } + } + }, + "response": { + "status": 429, + "body": "{\"message\":\"You have exceeded a secondary rate limit. Please wait a few minutes before you try again\"}", + "headers": { + "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}", + "Content-Type": "application/json; charset=utf-8", + "Server": "GitHub.com", + "Status": "429 Too Many Requests", + "gh-limited-by": "search-elapsed-time-shared-grouped", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"7ff3c96399f7ddf6129622d675ca9935\"", + "Last-Modified": "Thu, 06 Feb 2020 18:33:37 GMT", + "X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion", + "X-Accepted-OAuth-Scopes": "repo", + "X-GitHub-Media-Type": "unknown, github.v3", + "Access-Control-Expose-Headers": "ETag, Link, Location, gh-limited-by, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type", + "Access-Control-Allow-Origin": "*", + "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", + "X-Frame-Options": "deny", + "X-Content-Type-Options": "nosniff", + "X-XSS-Protection": "1; mode=block", + "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", + "Content-Security-Policy": "default-src 'none'", + "X-GitHub-Request-Id": "CC37:2605:3F982:4E949:5E3C5BFC" + } + }, + "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "persistent": true, + "scenarioName": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits3", + "requiredScenarioState": "Started", + "newScenarioState": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits3-2", + "insertionIndex": 2 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After/mappings/3-r_h_t_fail.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After/mappings/3-r_h_t_fail.json index d6522df8e3..9d7f608e1a 100644 --- a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After/mappings/3-r_h_t_fail.json +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After/mappings/3-r_h_t_fail.json @@ -1,5 +1,5 @@ { - "id": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "id": "574da117-6845-46d8-b2c1-4415546ca670", "name": "repos_hub4j-test-org_temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After", "request": { "url": "/repos/hub4j-test-org/temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After", @@ -11,21 +11,23 @@ } }, "response": { - "status": 429, - "body": "{\"message\":\"You have exceeded a secondary rate limit. Please wait a few minutes before you try again\"}", + "status": 200, + "bodyFileName": "3-r_h_t_fail.json", "headers": { "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}", "Content-Type": "application/json; charset=utf-8", "Server": "GitHub.com", - "Status": "429 Too Many Requests", - "gh-limited-by": "search-elapsed-time-shared-grouped", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4922", + "X-RateLimit-Reset": "{{testStartDate offset='3 seconds' format='unix'}}", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": [ "Accept, Authorization, Cookie, X-GitHub-OTP", "Accept-Encoding" ], - "ETag": "W/\"7ff3c96399f7ddf6129622d675ca9935\"", - "Last-Modified": "Thu, 06 Feb 2020 18:33:37 GMT", + "ETag": "W/\"858224998ac7d1fd6dcd43f73d375297\"", + "Last-Modified": "Thu, 06 Feb 2020 18:33:43 GMT", "X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion", "X-Accepted-OAuth-Scopes": "repo", "X-GitHub-Media-Type": "unknown, github.v3", @@ -37,13 +39,12 @@ "X-XSS-Protection": "1; mode=block", "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", "Content-Security-Policy": "default-src 'none'", - "X-GitHub-Request-Id": "CC37:2605:3F982:4E949:5E3C5BFC" + "X-GitHub-Request-Id": "CC37:2605:3FADC:4EA8C:5E3C5C02" } }, - "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "uuid": "574da117-6845-46d8-b2c1-4415546ca670", "persistent": true, - "scenarioName": "scenario-4-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After", - "requiredScenarioState": "Started", - "newScenarioState": "scenario-4-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits_Too_Many_Requests_No_Retry_After-2", - "insertionIndex": 2 + "scenarioName": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits3", + "requiredScenarioState": "scenario-1-repos-hub4j-test-org-temp-testHandler_Wait_Secondary_Limits3-2", + "insertionIndex": 3 } \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AppTest/wiremock/testGetDeploymentStatuses/mappings/4-r_h_g_deployments_315601644_statuses.json b/src/test/resources/org/kohsuke/github/AppTest/wiremock/testGetDeploymentStatuses/mappings/4-r_h_g_deployments_315601644_statuses.json index f58e353c6f..35e9858880 100644 --- a/src/test/resources/org/kohsuke/github/AppTest/wiremock/testGetDeploymentStatuses/mappings/4-r_h_g_deployments_315601644_statuses.json +++ b/src/test/resources/org/kohsuke/github/AppTest/wiremock/testGetDeploymentStatuses/mappings/4-r_h_g_deployments_315601644_statuses.json @@ -11,7 +11,7 @@ }, "bodyPatterns": [ { - "equalToJson": "{\"environment\":\"new-ci-env\",\"environment_url\":\"http://www.github.com/envurl\",\"target_url\":\"http://www.github.com\",\"log_url\":\"http://www.github.com/logurl\",\"description\":\"success\",\"state\":\"queued\"}", + "equalToJson": "{\"environment\":\"new-ci-env\",\"environment_url\":\"http://www.github.com/envurl\",\"log_url\":\"http://www.github.com/logurl\",\"description\":\"success\",\"state\":\"queued\"}", "ignoreArrayOrder": true, "ignoreExtraElements": false } diff --git a/src/test/resources/org/kohsuke/github/GHOrganizationTest/wiremock/testCreateRepositoryWithParameterIsTemplate/__files/7-r_h_github-api-template-test.json b/src/test/resources/org/kohsuke/github/GHOrganizationTest/wiremock/testCreateRepositoryWithParameterIsTemplate/__files/7-r_h_github-api-template-test.json deleted file mode 100644 index d11ecffe1e..0000000000 --- a/src/test/resources/org/kohsuke/github/GHOrganizationTest/wiremock/testCreateRepositoryWithParameterIsTemplate/__files/7-r_h_github-api-template-test.json +++ /dev/null @@ -1,129 +0,0 @@ -{ - "id": 287150018, - "node_id": "MDEwOlJlcG9zaXRvcnkyODcxNTAwMTg=", - "name": "github-api-template-test", - "full_name": "hub4j-test-org/github-api-template-test", - "private": false, - "owner": { - "login": "hub4j-test-org", - "id": 7544739, - "node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=", - "avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/hub4j-test-org", - "html_url": "https://github.com/hub4j-test-org", - "followers_url": "https://api.github.com/users/hub4j-test-org/followers", - "following_url": "https://api.github.com/users/hub4j-test-org/following{/other_user}", - "gists_url": "https://api.github.com/users/hub4j-test-org/gists{/gist_id}", - "starred_url": "https://api.github.com/users/hub4j-test-org/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/hub4j-test-org/subscriptions", - "organizations_url": "https://api.github.com/users/hub4j-test-org/orgs", - "repos_url": "https://api.github.com/users/hub4j-test-org/repos", - "events_url": "https://api.github.com/users/hub4j-test-org/events{/privacy}", - "received_events_url": "https://api.github.com/users/hub4j-test-org/received_events", - "type": "Organization", - "site_admin": false - }, - "html_url": "https://github.com/hub4j-test-org/github-api-template-test", - "description": "a test template repository used to test kohsuke's github-api", - "fork": false, - "url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test", - "forks_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/forks", - "keys_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/keys{/key_id}", - "collaborators_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/collaborators{/collaborator}", - "teams_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/teams", - "hooks_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/hooks", - "issue_events_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/issues/events{/number}", - "events_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/events", - "assignees_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/assignees{/user}", - "branches_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/branches{/branch}", - "tags_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/tags", - "blobs_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/git/blobs{/sha}", - "git_tags_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/git/tags{/sha}", - "git_refs_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/git/refs{/sha}", - "trees_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/git/trees{/sha}", - "statuses_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/statuses/{sha}", - "languages_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/languages", - "stargazers_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/stargazers", - "contributors_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/contributors", - "subscribers_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/subscribers", - "subscription_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/subscription", - "commits_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/commits{/sha}", - "git_commits_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/git/commits{/sha}", - "comments_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/comments{/number}", - "issue_comment_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/issues/comments{/number}", - "contents_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/contents/{+path}", - "compare_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/compare/{base}...{head}", - "merges_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/merges", - "archive_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/{archive_format}{/ref}", - "downloads_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/downloads", - "issues_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/issues{/number}", - "pulls_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/pulls{/number}", - "milestones_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/milestones{/number}", - "notifications_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/notifications{?since,all,participating}", - "labels_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/labels{/name}", - "releases_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/releases{/id}", - "deployments_url": "https://api.github.com/repos/hub4j-test-org/github-api-template-test/deployments", - "created_at": "2020-08-13T01:15:24Z", - "updated_at": "2020-08-13T01:15:24Z", - "pushed_at": "2020-08-13T01:15:26Z", - "git_url": "git://github.com/hub4j-test-org/github-api-template-test.git", - "ssh_url": "git@github.com:hub4j-test-org/github-api-template-test.git", - "clone_url": "https://github.com/hub4j-test-org/github-api-template-test.git", - "svn_url": "https://github.com/hub4j-test-org/github-api-template-test", - "homepage": "http://github-api.kohsuke.org/", - "size": 0, - "stargazers_count": 0, - "watchers_count": 0, - "language": null, - "has_issues": true, - "has_projects": true, - "has_downloads": true, - "has_wiki": true, - "has_pages": false, - "forks_count": 0, - "mirror_url": null, - "archived": false, - "disabled": false, - "open_issues_count": 0, - "license": null, - "visibility": "public", - "is_template": true, - "forks": 0, - "open_issues": 0, - "watchers": 0, - "default_branch": "main", - "permissions": { - "admin": true, - "push": true, - "pull": true - }, - "temp_clone_token": "", - "allow_squash_merge": true, - "allow_merge_commit": true, - "allow_rebase_merge": true, - "delete_branch_on_merge": false, - "template_repository": null, - "organization": { - "login": "hub4j-test-org", - "id": 7544739, - "node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=", - "avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/hub4j-test-org", - "html_url": "https://github.com/hub4j-test-org", - "followers_url": "https://api.github.com/users/hub4j-test-org/followers", - "following_url": "https://api.github.com/users/hub4j-test-org/following{/other_user}", - "gists_url": "https://api.github.com/users/hub4j-test-org/gists{/gist_id}", - "starred_url": "https://api.github.com/users/hub4j-test-org/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/hub4j-test-org/subscriptions", - "organizations_url": "https://api.github.com/users/hub4j-test-org/orgs", - "repos_url": "https://api.github.com/users/hub4j-test-org/repos", - "events_url": "https://api.github.com/users/hub4j-test-org/events{/privacy}", - "received_events_url": "https://api.github.com/users/hub4j-test-org/received_events", - "type": "Organization", - "site_admin": false - }, - "network_count": 0, - "subscribers_count": 8 -} diff --git a/src/test/resources/org/kohsuke/github/GHOrganizationTest/wiremock/testCreateRepositoryWithParameterIsTemplate/mappings/6-r_h_github-api-template-test.json b/src/test/resources/org/kohsuke/github/GHOrganizationTest/wiremock/testCreateRepositoryWithParameterIsTemplate/mappings/6-r_h_github-api-template-test.json index 908313f5d6..4662fd3090 100644 --- a/src/test/resources/org/kohsuke/github/GHOrganizationTest/wiremock/testCreateRepositoryWithParameterIsTemplate/mappings/6-r_h_github-api-template-test.json +++ b/src/test/resources/org/kohsuke/github/GHOrganizationTest/wiremock/testCreateRepositoryWithParameterIsTemplate/mappings/6-r_h_github-api-template-test.json @@ -47,8 +47,5 @@ }, "uuid": "3164c9df-abab-453d-982a-3d446781039d", "persistent": true, - "scenarioName": "testCreateRepositoryWithParameterIsTemplate-template-repo", - "requiredScenarioState": "Started", - "newScenarioState": "with-template-1", "insertionIndex": 6 } \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/GHOrganizationTest/wiremock/testCreateRepositoryWithParameterIsTemplate/mappings/7-r_h_github-api-template-test.json b/src/test/resources/org/kohsuke/github/GHOrganizationTest/wiremock/testCreateRepositoryWithParameterIsTemplate/mappings/7-r_h_github-api-template-test.json deleted file mode 100644 index 122ae41765..0000000000 --- a/src/test/resources/org/kohsuke/github/GHOrganizationTest/wiremock/testCreateRepositoryWithParameterIsTemplate/mappings/7-r_h_github-api-template-test.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "id": "51d54e86-a714-457b-88d6-5c045631a074", - "name": "repos_hub4j-test-org_github-api-template-test", - "request": { - "url": "/repos/hub4j-test-org/github-api-template-test", - "method": "GET", - "headers": { - "Accept": { - "equalTo": "application/vnd.github+json" - } - } - }, - "response": { - "status": 200, - "bodyFileName": "7-r_h_github-api-template-test.json", - "headers": { - "Date": "Thu, 13 Aug 2020 01:15:27 GMT", - "Content-Type": "application/json; charset=utf-8", - "Server": "GitHub.com", - "Status": "200 OK", - "X-RateLimit-Limit": "5000", - "X-RateLimit-Remaining": "4931", - "X-RateLimit-Reset": "1597282078", - "Cache-Control": "private, max-age=60, s-maxage=60", - "Vary": [ - "Accept, Authorization, Cookie, X-GitHub-OTP", - "Accept-Encoding, Accept, X-Requested-With", - "Accept-Encoding" - ], - "ETag": "W/\"9fc368e29d30f2606085100fed431a74\"", - "Last-Modified": "Thu, 13 Aug 2020 01:15:24 GMT", - "X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion", - "X-Accepted-OAuth-Scopes": "repo", - "X-GitHub-Media-Type": "github.baptiste-preview; format=json", - "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", - "X-Frame-Options": "deny", - "X-Content-Type-Options": "nosniff", - "X-XSS-Protection": "1; mode=block", - "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", - "Content-Security-Policy": "default-src 'none'", - "X-GitHub-Request-Id": "D640:8464:9DD977:C0780E:5F34942F" - } - }, - "uuid": "51d54e86-a714-457b-88d6-5c045631a074", - "persistent": true, - "scenarioName": "testCreateRepositoryWithParameterIsTemplate-template-repo", - "requiredScenarioState": "with-template-1", - "newScenarioState": "with-template-2", - "insertionIndex": 7 -} diff --git a/src/test/resources/org/kohsuke/github/GHRepositoryTest/wiremock/starTest/mappings/8-r_h_g_stargazers.json b/src/test/resources/org/kohsuke/github/GHRepositoryTest/wiremock/starTest/mappings/8-r_h_g_stargazers.json index 93a2fd7ea7..a0b09b2ecf 100644 --- a/src/test/resources/org/kohsuke/github/GHRepositoryTest/wiremock/starTest/mappings/8-r_h_g_stargazers.json +++ b/src/test/resources/org/kohsuke/github/GHRepositoryTest/wiremock/starTest/mappings/8-r_h_g_stargazers.json @@ -6,7 +6,7 @@ "method": "GET", "headers": { "Accept": { - "equalTo": "application/vnd.github+json" + "equalTo": "application/vnd.github.star+json" } } }, diff --git a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/1-r_h_ghworkflowruntest.json b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/1-r_h_ghworkflowruntest.json index 905dcd086d..5c2abb7868 100644 --- a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/1-r_h_ghworkflowruntest.json +++ b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/1-r_h_ghworkflowruntest.json @@ -9,7 +9,7 @@ "equalTo": "application/vnd.github+json" }, "Authorization": { - "equalTo": "Basic cGxhY2Vob2xkZXItdXNlcjpwbGFjZWhvbGRlci1wYXNzd29yZA==" + "equalTo": "token placeholder-password" } } }, diff --git a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/10-r_h_g_actions_artifacts_1242831517.json b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/10-r_h_g_actions_artifacts_1242831517.json index f0ed7a4ce8..f6d33e5aaf 100644 --- a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/10-r_h_g_actions_artifacts_1242831517.json +++ b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/10-r_h_g_actions_artifacts_1242831517.json @@ -9,7 +9,7 @@ "equalTo": "application/vnd.github+json" }, "Authorization": { - "equalTo": "Basic cGxhY2Vob2xkZXItdXNlcjpwbGFjZWhvbGRlci1wYXNzd29yZA==" + "equalTo": "token placeholder-password" } } }, diff --git a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/11-r_h_g_actions_artifacts.json b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/11-r_h_g_actions_artifacts.json index 971c27aa00..ba6d4554d0 100644 --- a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/11-r_h_g_actions_artifacts.json +++ b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/11-r_h_g_actions_artifacts.json @@ -9,7 +9,7 @@ "equalTo": "application/vnd.github+json" }, "Authorization": { - "equalTo": "Basic cGxhY2Vob2xkZXItdXNlcjpwbGFjZWhvbGRlci1wYXNzd29yZA==" + "equalTo": "token placeholder-password" } } }, diff --git a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/12-r_h_g_actions_artifacts_1242831742.json b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/12-r_h_g_actions_artifacts_1242831742.json index 5aa78678ea..108829cb80 100644 --- a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/12-r_h_g_actions_artifacts_1242831742.json +++ b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/12-r_h_g_actions_artifacts_1242831742.json @@ -9,7 +9,7 @@ "equalTo": "application/vnd.github+json" }, "Authorization": { - "equalTo": "Basic cGxhY2Vob2xkZXItdXNlcjpwbGFjZWhvbGRlci1wYXNzd29yZA==" + "equalTo": "token placeholder-password" } } }, diff --git a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/13-r_h_g_actions_artifacts_1242831742.json b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/13-r_h_g_actions_artifacts_1242831742.json index bc6bb62ec0..d6688b4202 100644 --- a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/13-r_h_g_actions_artifacts_1242831742.json +++ b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/13-r_h_g_actions_artifacts_1242831742.json @@ -9,7 +9,7 @@ "equalTo": "application/vnd.github+json" }, "Authorization": { - "equalTo": "Basic cGxhY2Vob2xkZXItdXNlcjpwbGFjZWhvbGRlci1wYXNzd29yZA==" + "equalTo": "token placeholder-password" } } }, diff --git a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/2-r_h_g_actions_workflows_artifacts-workflowyml.json b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/2-r_h_g_actions_workflows_artifacts-workflowyml.json index a827d744b2..cac9a5baab 100644 --- a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/2-r_h_g_actions_workflows_artifacts-workflowyml.json +++ b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/2-r_h_g_actions_workflows_artifacts-workflowyml.json @@ -9,7 +9,7 @@ "equalTo": "application/vnd.github+json" }, "Authorization": { - "equalTo": "Basic cGxhY2Vob2xkZXItdXNlcjpwbGFjZWhvbGRlci1wYXNzd29yZA==" + "equalTo": "token placeholder-password" } } }, diff --git a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/3-r_h_g_actions_runs.json b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/3-r_h_g_actions_runs.json index c253c2f2cf..977136037c 100644 --- a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/3-r_h_g_actions_runs.json +++ b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/3-r_h_g_actions_runs.json @@ -9,7 +9,7 @@ "equalTo": "application/vnd.github+json" }, "Authorization": { - "equalTo": "Basic cGxhY2Vob2xkZXItdXNlcjpwbGFjZWhvbGRlci1wYXNzd29yZA==" + "equalTo": "token placeholder-password" } } }, diff --git a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/4-r_h_g_actions_workflows_7433027_dispatches.json b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/4-r_h_g_actions_workflows_7433027_dispatches.json index 6eb55e1d10..d0d8d8c001 100644 --- a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/4-r_h_g_actions_workflows_7433027_dispatches.json +++ b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/4-r_h_g_actions_workflows_7433027_dispatches.json @@ -9,7 +9,7 @@ "equalTo": "application/vnd.github+json" }, "Authorization": { - "equalTo": "Basic cGxhY2Vob2xkZXItdXNlcjpwbGFjZWhvbGRlci1wYXNzd29yZA==" + "equalTo": "token placeholder-password" } }, "bodyPatterns": [ diff --git a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/5-r_h_g_actions_runs.json b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/5-r_h_g_actions_runs.json index 18e50b8a8c..122bbdf46a 100644 --- a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/5-r_h_g_actions_runs.json +++ b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/5-r_h_g_actions_runs.json @@ -9,7 +9,7 @@ "equalTo": "application/vnd.github+json" }, "Authorization": { - "equalTo": "Basic cGxhY2Vob2xkZXItdXNlcjpwbGFjZWhvbGRlci1wYXNzd29yZA==" + "equalTo": "token placeholder-password" } } }, diff --git a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/6-r_h_g_actions_runs_7892624040_artifacts.json b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/6-r_h_g_actions_runs_7892624040_artifacts.json index c45c036590..58efa589dd 100644 --- a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/6-r_h_g_actions_runs_7892624040_artifacts.json +++ b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/6-r_h_g_actions_runs_7892624040_artifacts.json @@ -9,7 +9,7 @@ "equalTo": "application/vnd.github+json" }, "Authorization": { - "equalTo": "Basic cGxhY2Vob2xkZXItdXNlcjpwbGFjZWhvbGRlci1wYXNzd29yZA==" + "equalTo": "token placeholder-password" } } }, diff --git a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/7-r_h_g_actions_artifacts_1242831742_zip.json b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/7-r_h_g_actions_artifacts_1242831742_zip.json index bfb65b221f..0a785c1319 100644 --- a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/7-r_h_g_actions_artifacts_1242831742_zip.json +++ b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/7-r_h_g_actions_artifacts_1242831742_zip.json @@ -9,7 +9,7 @@ "equalTo": "application/vnd.github+json" }, "Authorization": { - "equalTo": "Basic cGxhY2Vob2xkZXItdXNlcjpwbGFjZWhvbGRlci1wYXNzd29yZA==" + "equalTo": "token placeholder-password" } } }, diff --git a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/8-r_h_g_actions_artifacts_1242831517_zip.json b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/8-r_h_g_actions_artifacts_1242831517_zip.json index d8eb518e39..6fc19ededb 100644 --- a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/8-r_h_g_actions_artifacts_1242831517_zip.json +++ b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/8-r_h_g_actions_artifacts_1242831517_zip.json @@ -9,7 +9,7 @@ "equalTo": "application/vnd.github+json" }, "Authorization": { - "equalTo": "Basic cGxhY2Vob2xkZXItdXNlcjpwbGFjZWhvbGRlci1wYXNzd29yZA==" + "equalTo": "token placeholder-password" } } }, diff --git a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/9-r_h_g_actions_artifacts_1242831742.json b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/9-r_h_g_actions_artifacts_1242831742.json index 478d1773e5..593cdcc065 100644 --- a/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/9-r_h_g_actions_artifacts_1242831742.json +++ b/src/test/resources/org/kohsuke/github/GHWorkflowRunTest/wiremock/testArtifacts/mappings/9-r_h_g_actions_artifacts_1242831742.json @@ -9,7 +9,7 @@ "equalTo": "application/vnd.github+json" }, "Authorization": { - "equalTo": "Basic cGxhY2Vob2xkZXItdXNlcjpwbGFjZWhvbGRlci1wYXNzd29yZA==" + "equalTo": "token placeholder-password" } } }, diff --git a/src/test/resources/slow-or-flaky-tests.txt b/src/test/resources/slow-or-flaky-tests.txt index b9c6fbbdc2..df6827bec0 100644 --- a/src/test/resources/slow-or-flaky-tests.txt +++ b/src/test/resources/slow-or-flaky-tests.txt @@ -1,4 +1,5 @@ **/extras/** +**/AbuseLimitHandlerTest **/GHRateLimitTest **/GHPullRequestTest **/RequesterRetryTest