SOLR-18188: Tests, switch from Apache HttpClient to Jetty HttpClient#4266
SOLR-18188: Tests, switch from Apache HttpClient to Jetty HttpClient#4266dsmiley wants to merge 24 commits intoapache:mainfrom
Conversation
…ient etc. is still allowed. Don't import org.apache.http classes. Mostly done via Google Jules.
Introduce URLUtil.buildURI
epugh
left a comment
There was a problem hiding this comment.
14 out of 67 reviewed, this is all looking great! Really excited to see this big lift done, and the tests are reading much nicer.
solr/core/src/test/org/apache/solr/cloud/api/collections/CollectionReloadTest.java
Outdated
Show resolved
Hide resolved
| createCollectionPost.setEntity(new StringEntity(requestBody)); | ||
| HttpResponse httpResponse = | ||
| ((CloudLegacySolrClient) cluster.getSolrClient()) | ||
| var response2 = |
There was a problem hiding this comment.
This is much nicer, much less clunky plumbing!
There was a problem hiding this comment.
even thoguh we set all the same things.
...re/src/test/org/apache/solr/cloud/api/collections/TestCollectionsAPIViaSolrCloudCluster.java
Outdated
Show resolved
Hide resolved
| 400, httpClient.newRequest(baseUrl + aliasApi).method(HttpMethod.PUT).send().getStatus()); | ||
|
|
||
| String body = | ||
| "{\n" |
There was a problem hiding this comment.
i had good luck with the """ tags to simplify json formatted strings. Since you are reformatting a lot in this PR, might be worth embracing it for the JSON?
There was a problem hiding this comment.
I may change some of these where I add new code but otherwise don't want to change more lines in a massive PR.
solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudClusterSSL.java
Outdated
Show resolved
Hide resolved
| url = url + pickRandom("", "&nrtReplicas=1", "&replicationFactor=1"); | ||
| HttpGet createCollectionGet = new HttpGet(url); | ||
| getHttpClient().execute(createCollectionGet); | ||
| url1 = url1 + pickRandom("", "&nrtReplicas=1", "&replicationFactor=1"); |
There was a problem hiding this comment.
ah my old friend, you are back again numbered variable..
There was a problem hiding this comment.
I'm able to address most/all of those issues via simply using switch-expressions, which creates blocks of isolated scope
solr/core/src/test/org/apache/solr/core/TestSolrConfigHandler.java
Outdated
Show resolved
Hide resolved
|
|
||
| @SuppressWarnings({"rawtypes"}) | ||
| private static LinkedHashMapWriter getRespMap(String baseUrl, String path) throws Exception { | ||
| // a hack... if possible pass in an httpClient and also be able to init RestTestHarness with it |
There was a problem hiding this comment.
is this a note to yourself for future work in this PR, or for a future developer? if it's for a future dev, maybe elaborate a bit more and add that tag we use? todo or something?
There was a problem hiding this comment.
"hack" is possibly overstated. It's not ideal to create a new harness (which creates a client) when I'd rather somehow re-use a client. I don't think I feel strongly enough now to bother with TODO here.
There was a problem hiding this comment.
I did a little... trick/hack enabling use of TestHarness created for a different baseUrl, and thus this method is now removed.
| .newRequest(baseUrl + "/cluster/filestore/files" + path) | ||
| .send(); | ||
| assertEquals(200, resp.getStatus()); | ||
| ByteBuffer buf = ByteBuffer.wrap(resp.getContent()); |
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
dsmiley
left a comment
There was a problem hiding this comment.
This PR is huge...
Honestly review-wise... if tests pass...
I'll try and draw attention to "interesting" things.
|
|
||
| /** A basic name-only {@link Principal}. */ | ||
| public final class SimplePrincipal implements Principal { | ||
| // TODO use a record. But javadoc tooling complained as it was confused (Java version issue?) |
There was a problem hiding this comment.
this mystery was solved previously, unblocking this nice conversion
|
|
||
| public class AliasIntegrationTest extends SolrCloudTestCase { | ||
|
|
||
| private CloseableHttpClient httpClient; |
There was a problem hiding this comment.
usually no field is needed since it's easy to grab a managed Jetty HttpClient from places
| httpClient | ||
| .newRequest(baseUrl + aliasApi) | ||
| .method(HttpMethod.PUT) | ||
| .body(new StringRequestContent("application/json", body, StandardCharsets.UTF_8)) | ||
| .send()); |
There was a problem hiding this comment.
I preferred this "fluent" style whenever possible as I thinks it helps readability
| } catch (Exception exc) { | ||
| Throwable rootCause = SolrException.getRootCause(exc); | ||
| if (rootCause instanceof NoHttpResponseException) { | ||
| if (rootCause instanceof IOException) { |
There was a problem hiding this comment.
in tests we trust... 🙏
NoHttpResponseException is Apache HttpClient specific
...ework/src/java/org/apache/solr/cloud/api/collections/AbstractCloudBackupRestoreTestCase.java
Show resolved
Hide resolved
solr/test-framework/src/java/org/apache/solr/handler/BackupRestoreUtils.java
Show resolved
Hide resolved
…88-migrateToJettyHttpClient # Conflicts: # solr/solrj/src/test/org/apache/solr/client/solrj/embedded/JettyWebappTest.java
Didn't need version suffixes on vars since they are now scoped.
* better exception handling. * allow passing an absolute URL thus overriding the base
…ettyHttpClient # Conflicts: # solr/test-framework/build.gradle
…onstruct RestTestHarness is now immutable and no longer owns resources, making it cheap to create on-the-fly for different URLs without complex lifecycle management. Changes to RestTestHarness: - Removed Closeable interface - RTH no longer owns the HttpClient - Removed RESTfulServerProvider interface and setServerProvider() method - Removed the "://" hack for detecting absolute URLs in buildUri() - New constructor: RestTestHarness(HttpClient, String baseUrl) - Convenience constructor: RestTestHarness(JettySolrRunner, String coreOrCollection) Gets HttpClient from jetty.getSolrClient().getHttpClient() - Added newWithUrl(String) helper to create new instance with different URL sharing the same HttpClient Updated test infrastructure: - Simplified testForResponseElement() by removing testServerBaseUrl and cloudSolrClient parameters; now requires non-null harness - Simplified reqhandlertests() to take only RestTestHarness parameter - Removed all close() calls and try-with-resources blocks - Updated tests to create RTH instances on-the-fly instead of mutating via setServerProvider() - TestReqParamsAPI, TestSolrConfigHandlerCloud, and others now use harness.newWithUrl() to query specific replica URLs - TestSolrConfigHandlerConcurrent.getAsMap() now takes RestTestHarness instead of HttpClient + URI
RestTestHarness: URI based RestTestHarness.head restored; different signature
RestTestHarness: URI based RestTestHarness.head restored; different signature Fixed a few bugs
|
I made a significant change to make RestTestHarness cheap to create without any need to close it, and also making it immutable. I think I should split this big PR, a new one centered on RestTestHarness and most of its users and thus also including the URLUtils.buildURI addition. WDYT @epugh ? I could do that ~quickly and then we come back to this PR. |
|
RestTestHarness & URLUtils stuff is now reverted from this PR; see #4270 for them. Now this PR is smaller, albeit still pretty big. |
|
I think that was a good decision. I will review and run the tests locally |
https://issues.apache.org/jira/browse/SOLR-18188
This PR switches nearly all tests that were using Apache HttpClient directly to instead use Jetty HttpClient (or in some cases a plain SolrClient given we can do a lot with them). Also any tests with
import org.apache.http.As of this writing, I deferred ~8 tests that casted a cloud client to CloudLegacySolrClient to then call getHttpClient merely to create an HttpSolrClient with the same backing client -- maybe for efficiency. TBD on their fate.
SimplePrinciple was made a record and used in places where an Apache variant was used.
In URLUtils, I added a new method: buildURI which is needed in RestTestHarness, BackupRestoreUtils, and I think eventually more places. It handles URI encoding matters. Apparently Apache HttpClient was doing things implicitly that Jetty doesn't.
This is another step in a journey that continues
(follow-up note: scope was reduced. see #4270 for the rest).