Subject: [PATCH] Handle rate limiting with a more specific message
---
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
diff --git a/src/org/openstreetmap/josm/io/OsmApi.java b/src/org/openstreetmap/josm/io/OsmApi.java
|
a
|
b
|
|
| 830 | 830 | CredentialsManager.getInstance().purgeCredentialsCache(RequestorType.SERVER); |
| 831 | 831 | throw new OsmApiException(retCode, errorHeader, errorBody, activeConnection.getURL().toString(), |
| 832 | 832 | doAuthenticate ? retrieveBasicAuthorizationLogin(client) : null, response.getContentType()); |
| | 833 | case 429: // This is the code that OSM uses for rate limiting |
| | 834 | // FIXME: Use a specific exception, we may also want to inform the user that they may want to wait an hour. |
| | 835 | throw new OsmApiException(retCode, errorHeader, errorBody, activeConnection.getURL().toString(), |
| | 836 | doAuthenticate ? retrieveBasicAuthorizationLogin(client) : null, response.getContentType()); |
| 833 | 837 | default: |
| 834 | 838 | throw new OsmApiException(retCode, errorHeader, errorBody); |
| 835 | 839 | } |
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
diff --git a/test/unit/org/openstreetmap/josm/io/OsmApiTest.java b/test/unit/org/openstreetmap/josm/io/OsmApiTest.java
|
a
|
b
|
|
| 1 | 1 | // License: GPL. For details, see LICENSE file. |
| 2 | 2 | package org.openstreetmap.josm.io; |
| 3 | 3 | |
| | 4 | import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; |
| 4 | 5 | import static org.junit.jupiter.api.Assertions.assertEquals; |
| | 6 | import static org.junit.jupiter.api.Assertions.assertThrows; |
| 5 | 7 | |
| 6 | 8 | import java.io.ByteArrayInputStream; |
| 7 | 9 | import java.nio.charset.StandardCharsets; |
| | 10 | import java.util.Collections; |
| 8 | 11 | |
| | 12 | import org.junit.jupiter.api.AfterEach; |
| | 13 | import org.junit.jupiter.api.BeforeEach; |
| 9 | 14 | import org.junit.jupiter.api.Test; |
| | 15 | import org.junit.jupiter.api.extension.RegisterExtension; |
| | 16 | import org.openstreetmap.josm.TestUtils; |
| | 17 | import org.openstreetmap.josm.data.coor.LatLon; |
| | 18 | import org.openstreetmap.josm.data.oauth.IOAuthToken; |
| | 19 | import org.openstreetmap.josm.data.oauth.OAuth20Exception; |
| | 20 | import org.openstreetmap.josm.data.oauth.OAuth20Parameters; |
| | 21 | import org.openstreetmap.josm.data.oauth.OAuth20Token; |
| | 22 | import org.openstreetmap.josm.data.oauth.OAuthAccessTokenHolder; |
| 10 | 23 | import org.openstreetmap.josm.data.osm.Changeset; |
| | 24 | import org.openstreetmap.josm.data.osm.Node; |
| 11 | 25 | import org.openstreetmap.josm.data.osm.User; |
| 12 | 26 | import org.openstreetmap.josm.gui.progress.NullProgressMonitor; |
| 13 | 27 | |
| | 28 | import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder; |
| | 29 | import com.github.tomakehurst.wiremock.client.WireMock; |
| | 30 | import com.github.tomakehurst.wiremock.core.WireMockConfiguration; |
| | 31 | import com.github.tomakehurst.wiremock.junit5.WireMockExtension; |
| | 32 | import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; |
| | 33 | |
| 14 | 34 | /** |
| 15 | 35 | * Unit tests of {@link OsmApi} class. |
| 16 | 36 | */ |
| | 37 | @org.openstreetmap.josm.testutils.annotations.OsmApi(org.openstreetmap.josm.testutils.annotations.OsmApi.APIType.NONE) |
| 17 | 38 | class OsmApiTest { |
| | 39 | @RegisterExtension |
| | 40 | static WireMockExtension wireMockExtension = WireMockExtension.newInstance().options( |
| | 41 | WireMockConfiguration.options().usingFilesUnderDirectory(TestUtils.getTestDataRoot()) |
| | 42 | ).failOnUnmatchedRequests(true).build(); |
| | 43 | |
| | 44 | @BeforeEach |
| | 45 | void setup(WireMockRuntimeInfo info) throws OAuth20Exception { |
| | 46 | OAuthAccessTokenHolder.getInstance().setAccessToken(info.getHttpBaseUrl(), new OAuth20Token(new OAuth20Parameters("clientId", "clientSecret", |
| | 47 | "tokenUrl", "authorizeUrl", info.getHttpBaseUrl(), "redirectUrl"), |
| | 48 | "{\"access_token\": \"test_token\", \"token_type\": \"bearer\"}")); |
| | 49 | } |
| | 50 | |
| | 51 | @AfterEach |
| | 52 | void tearDown(WireMockRuntimeInfo info) { |
| | 53 | OAuthAccessTokenHolder.getInstance().setAccessToken(info.getHttpBaseUrl(), (IOAuthToken) null); |
| | 54 | } |
| | 55 | |
| 18 | 56 | /** |
| 19 | 57 | * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/12675">Bug #12675</a>. |
| 20 | 58 | * @throws IllegalDataException if an error occurs |
| 21 | 59 | */ |
| 22 | 60 | @Test |
| 23 | 61 | void testTicket12675() throws IllegalDataException { |
| | 62 | |
| 24 | 63 | OsmApi api = OsmApi.getOsmApi(); |
| 25 | 64 | Changeset cs = new Changeset(); |
| 26 | 65 | cs.setUser(User.getAnonymous()); |
| … |
… |
|
| 36 | 75 | NullProgressMonitor.INSTANCE).iterator().next(); |
| 37 | 76 | assertEquals(User.getAnonymous(), cs2.getUser()); |
| 38 | 77 | } |
| | 78 | |
| | 79 | @Test |
| | 80 | void testTooManyRequests429(WireMockRuntimeInfo info) { |
| | 81 | final OsmApi osmApi = OsmApi.getOsmApi(info.getHttpBaseUrl()); |
| | 82 | final ResponseDefinitionBuilder responseDefinitionBuilder = WireMock.status(429).withBody("Upload has been blocked due to rate limiting. Please try again later.") |
| | 83 | .withHeader("Error", "Upload has been blocked due to rate limiting. Please try again later."); |
| | 84 | info.getWireMock().register(WireMock.get("/capabilities").willReturn(WireMock.aResponse().withBodyFile("api/0.6/capabilities"))); |
| | 85 | info.getWireMock().register(WireMock.put("/0.6/changeset/create").willReturn(WireMock.aResponse().withBody(Integer.toString(Integer.MAX_VALUE)))); |
| | 86 | info.getWireMock().register(WireMock.post("/0.6/changeset/2147483647/upload").willReturn(responseDefinitionBuilder)); |
| | 87 | Changeset changeset = new Changeset(); |
| | 88 | assertDoesNotThrow(() -> osmApi.openChangeset(changeset, NullProgressMonitor.INSTANCE)); |
| | 89 | assertEquals(Integer.MAX_VALUE, changeset.getId()); |
| | 90 | osmApi.setChangeset(changeset); |
| | 91 | assertThrows(OsmApiException.class, () -> osmApi.uploadDiff(Collections.singletonList(new Node(LatLon.ZERO)), NullProgressMonitor.INSTANCE)); |
| | 92 | } |
| 39 | 93 | } |