Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check that client methods match API defined in the REST spec #31825

Merged
merged 11 commits into from
Jul 17, 2018

Conversation

javanna
Copy link
Member

@javanna javanna commented Jul 5, 2018

We have been encountering name mismatches between API defined in our
REST spec and method names that have been added to the high-level REST
client. We should check this automatically to prevent futher mismatches,
and correct all the current ones.

This commit adds a test for this and corrects the issues found by it.

We have been encountering name mismatches between API defined in our
REST spec and method names that have been added to the high-level REST
client. We should check this automatically to prevent futher mismatches,
and correct all the current ones.

This commit adds a test for this and corrects the issues found by it.
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra

@@ -26,6 +27,9 @@ apply plugin: 'nebula.maven-scm'
group = 'org.elasticsearch.client'
archivesBaseName = 'elasticsearch-rest-high-level-client'

Task copyRestSpec = RestIntegTestTask.createCopyRestSpecTask(project, false)
test.dependsOn(copyRestSpec)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these build changes are temporary, I just hacked to make the new test work. The new test needs the spec in its classpath, yet it is not an integ test. Suggestions are welcome on how to improve this and make this cleaner.

@@ -173,7 +173,7 @@ public void putMappingAsync(PutMappingRequest putMappingRequest, RequestOptions
* @return the response
* @throws IOException in case there is a problem sending the request or parsing back the response
*/
public GetMappingsResponse getMappings(GetMappingsRequest getMappingsRequest, RequestOptions options) throws IOException {
public GetMappingsResponse getMapping(GetMappingsRequest getMappingsRequest, RequestOptions options) throws IOException {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these changes are breaking. I guess we should deprecate the old methods in 6.x and have the test ignore those? It is pretty annoying that we just released some of these (some haven't been released yet so we are lucky there) and we already need to rename them...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree we should deprecate the old names and remove in 7.0. Certainly annoying but we really are trying to be better about breaking the client.


assertThat("Some client method doesn't match a corresponding API defined in the REST spec: " + apiNotFound,
apiNotFound.size(), equalTo(0));
assertThat(apiSpec, equalTo(Arrays.stream(notSupportedApi).collect(Collectors.toSet())));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still conflicted on whether this is a good check or not, given that the client is not complete yet and 60 API are missing. yet it helps listing what is missing and possibly finding inconsistencies, for instance render search template should be already supported through search template but it does not have its own method (just a parameter in the request).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the test is fine. I think it'd be nicer to remove the notsupportedApi from the apiSpec and check that it is empty. You could even make it into a list and sort it so the results are easier to read.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure will do

@@ -632,6 +640,108 @@ public void testProvidedNamedXContents() {
assertTrue(names.contains(DiscountedCumulativeGain.NAME));
}

public void testApiNamingConventions() throws Exception {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test should probably be moved to a different class, as it needs rest spec in the classpath which is currently done from gradle. not sure if it should belong to unit tests or IT tests. it is kind of in between.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it doesn't need a running Elasticsearch server I'd keep it in unit tests. Moving it to another file is fine by me. I'm hoping that we can make the gradle copying thing not required though.....

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok let's try to make the copy not required then.

@@ -173,7 +173,7 @@ public void putMappingAsync(PutMappingRequest putMappingRequest, RequestOptions
* @return the response
* @throws IOException in case there is a problem sending the request or parsing back the response
*/
public GetMappingsResponse getMappings(GetMappingsRequest getMappingsRequest, RequestOptions options) throws IOException {
public GetMappingsResponse getMapping(GetMappingsRequest getMappingsRequest, RequestOptions options) throws IOException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree we should deprecate the old names and remove in 7.0. Certainly annoying but we really are trying to be better about breaking the client.

@@ -446,7 +446,7 @@ public void getSettingsAsync(GetSettingsRequest getSettingsRequest, RequestOptio
* @return the response
* @throws IOException in case there is a problem sending the request or parsing back the response
*/
public ForceMergeResponse forceMerge(ForceMergeRequest forceMergeRequest, RequestOptions options) throws IOException {
public ForceMergeResponse forcemerge(ForceMergeRequest forceMergeRequest, RequestOptions options) throws IOException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ew

@@ -632,6 +640,108 @@ public void testProvidedNamedXContents() {
assertTrue(names.contains(DiscountedCumulativeGain.NAME));
}

public void testApiNamingConventions() throws Exception {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it doesn't need a running Elasticsearch server I'd keep it in unit tests. Moving it to another file is fine by me. I'm hoping that we can make the gradle copying thing not required though.....

@@ -632,6 +640,108 @@ public void testProvidedNamedXContents() {
assertTrue(names.contains(DiscountedCumulativeGain.NAME));
}

public void testApiNamingConventions() throws Exception {
String[] notSupportedApi = new String[]{
"cat.aliases", "cat.allocation", "cat.count", "cat.fielddata", "cat.health", "cat.help", "cat.indices", "cat.master",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think making these one per line is going to make merges so much easier when we remove things from it.

I think you should remove cat.* via a hard coded pattern because we're not going to do it.

I think for the APIs we've decided not to implement we should have a line comment saying that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed

Modifier.isFinal(method.getClass().getModifiers()) || Modifier.isFinal(method.getModifiers()));
assertTrue(Modifier.isPublic(method.getModifiers()));

if (apiName.endsWith("_async")) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does _async come from. Like with the _ and all.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see! So you snake_caseify the method name to line up with the spec and you make sure the async version pairs up.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe worth a comment.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, I will add a comment


assertThat("Some client method doesn't match a corresponding API defined in the REST spec: " + apiNotFound,
apiNotFound.size(), equalTo(0));
assertThat(apiSpec, equalTo(Arrays.stream(notSupportedApi).collect(Collectors.toSet())));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the test is fine. I think it'd be nicer to remove the notsupportedApi from the apiSpec and check that it is empty. You could even make it into a list and sort it so the results are easier to read.

}

private static String toSnakeCase(String camelCase) {
List<Character> chars = new ArrayList<>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StringBuilder instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:)

}
}

assertThat("Some client method doesn't match a corresponding API defined in the REST spec: " + apiNotFound,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is going to fail if we add APIs for plugins and when we add them for xpack. But we can cross that bridge when we come to it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes at the moment I think even modules are not considered. We should improve that, it can also be done later I think.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we stuff the spec for modules into the main REST spec for historical reasons.

@@ -47,6 +47,7 @@ dependencies {
testCompile "com.carrotsearch.randomizedtesting:randomizedtesting-runner:${versions.randomizedrunner}"
testCompile "junit:junit:${versions.junit}"
testCompile "org.hamcrest:hamcrest-all:${versions.hamcrest}"
testCompile "org.elasticsearch:rest-api-spec:${version}"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

funnily, this makes it work from intellij, as stuff is found on filesystem, extracted from jars. not sure what this does in Eclipse.

while (e.hasMoreElements()) {
JarEntry entry = e.nextElement();
if (entry.getName().startsWith( classpathPrefix) && entry.getName().endsWith(".json")) {
parseSpecFile(restApiParser, null/*entry.getName()?*/, restSpec);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this side of the branch does not quite work yet, currently stuck at java.security.AccessControlException: access denied ("java.io.FilePermission" "file:/home/javanna/elastic/elasticsearch/rest-api-spec/build/distributions/rest-api-spec-7.0.0-alpha1-SNAPSHOT.jar" "read") at line 98 above.

});
}
} else {
Path dir = PathUtils.get(ClientYamlSuiteRestSpec.class.getResource(classpathPrefix).toURI());
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this one is still exercised in the new unit test when run from idea, I guess that once copying is not required it should not be exercised anymore by the integ test stuff.

@javanna
Copy link
Member Author

javanna commented Jul 6, 2018

@nik9000 I addressed all comments besides the part around not copying spec files around.

@nik9000
Copy link
Member

nik9000 commented Jul 6, 2018

@nik9000 I addressed all comments besides the part around not copying spec files around.

I'll have a look at the spec copying thing on Monday I think.

@javanna javanna removed the WIP label Jul 16, 2018
@javanna
Copy link
Member Author

javanna commented Jul 16, 2018

@nik9000 I made the copying work like we discussed. The change should not be disruptive, all the rest should work this time. I have tried things and the new test works from both IntelliJ and command line. Would you mind checking what Eclipse does? I have left a TODO for the xpack API, I ignore them for now and I think it should be a followup.

@javanna
Copy link
Member Author

javanna commented Jul 16, 2018

@hub-cap feel free to have a look as well!


boolean remove = apiSpec.remove(apiName);
if (remove == false && deprecatedMethods.contains(apiName) == false) {
//TODO xpack api are currently ignored, we need to load xpack yaml spec too
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you create a GH issue and assign it to me to finish up the xpack.* here?

ClientYamlSuiteRestSpec restSpec = new ClientYamlSuiteRestSpec();
ClientYamlSuiteRestApiParser restApiParser = new ClientYamlSuiteRestApiParser();
Path dir = PathUtils.get(ClientYamlSuiteRestSpec.class.getResource(classpathPrefix).toURI());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason these got moved around here? Seems like the imports and the dir are exactly the same, albeit just moved a few lines.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is because he tried to make a change to this file but it didn't work out and he reversed it by hand. @javanna , can you entirely revert the changes to this file?

Copy link
Contributor

@hub-cap hub-cap left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor Q. Id love to see this merged asap so I can do the work for the xpack.* spec methods before we go crazy adding them all!

Copy link
Member

@nik9000 nik9000 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM and it works in Eclipse.

ClientYamlSuiteRestSpec restSpec = new ClientYamlSuiteRestSpec();
ClientYamlSuiteRestApiParser restApiParser = new ClientYamlSuiteRestApiParser();
Path dir = PathUtils.get(ClientYamlSuiteRestSpec.class.getResource(classpathPrefix).toURI());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is because he tried to make a change to this file but it didn't work out and he reversed it by hand. @javanna , can you entirely revert the changes to this file?

@javanna
Copy link
Member Author

javanna commented Jul 16, 2018

I addressed the latest comments, this should be ready, I will merge once I get a green build. Thanks for the reviews!

@javanna javanna merged commit 049966a into elastic:master Jul 17, 2018
dnhatn added a commit that referenced this pull request Jul 20, 2018
* master:
  Painless: Simplify Naming in Lookup Package (#32177)
  Handle missing values in painless (#32207)
  add support for write index resolution when creating/updating documents (#31520)
  ECS Task IAM profile credentials ignored in repository-s3 plugin (#31864)
  Remove indication of future multi-homing support (#32187)
  Rest test - allow for snapshots to take 0 milliseconds
  Make x-pack-core generate a pom file
  Rest HL client: Add put watch action (#32026)
  Build: Remove pom generation for plugin zip files (#32180)
  Fix comments causing errors with Java 11
  Fix rollup on date fields that don't support epoch_millis (#31890)
  Detect and prevent configuration that triggers a Gradle bug (#31912)
  [test] port linux package packaging tests (#31943)
  Revert "Introduce a Hashing Processor (#31087)" (#32178)
  Remove empty @return from JavaDoc
  Adjust SSLDriver behavior for JDK11 changes (#32145)
  [test] use randomized runner in packaging tests (#32109)
  Add support for field aliases. (#32172)
  Painless: Fix caching bug and clean up addPainlessClass. (#32142)
  Call setReferences() on custom referring tokenfilters in _analyze (#32157)
  Fix BwC Tests looking for UUID Pre 6.4 (#32158)
  Improve docs for search preferences (#32159)
  use before instead of onOrBefore
  Add more contexts to painless execute api (#30511)
  Add EC2 credential test for repository-s3 (#31918)
  A replica can be promoted and started in one cluster state update (#32042)
  Fix Java 11 javadoc compile problem
  Fix CP for namingConventions when gradle home has spaces (#31914)
  Fix `range` queries on `_type` field for singe type indices (#31756)
  [DOCS] Update TLS on Docker for 6.3 (#32114)
  ESIndexLevelReplicationTestCase doesn't support replicated failures but it's good to know what they are
  Remove versionType from translog (#31945)
  Switch distribution to new style Requests (#30595)
  Build: Skip jar tests if jar disabled
  Painless: Add PainlessClassBuilder (#32141)
  Build: Make additional test deps of check (#32015)
  Disable C2 from using AVX-512 on JDK 10 (#32138)
  Build: Move shadow customizations into common code (#32014)
  Painless: Fix Bug with Duplicate PainlessClasses (#32110)
  Remove empty @param from Javadoc
  Re-disable packaging tests on suse boxes
  Docs: Fix missing example script quote (#32010)
  [ML] Wait for aliases in multi-node tests (#32086)
  [ML] Move analyzer dependencies out of categorization config (#32123)
  Ensure to release translog snapshot in primary-replica resync (#32045)
  Handle TokenizerFactory  TODOs (#32063)
  Relax TermVectors API to work with textual fields other than TextFieldType (#31915)
  Updates the build to gradle 4.9 (#32087)
  Mute :qa:mixed-cluster indices.stats/10_index/Index - all’
  Check that client methods match API defined in the REST spec (#31825)
  Enable testing in FIPS140 JVM (#31666)
  Fix put mappings java API documentation (#31955)
  Add exclusion option to `keep_types` token filter (#32012)
  [Test] Modify assert statement for ssl handshake (#32072)
javanna referenced this pull request Jul 20, 2018
Moves the customizations to the build to produce nice shadow jars and
javadocs into common build code, mostly BuildPlugin with a little into
the root build.gradle file. This means that any project that applies the
shadow plugin will automatically be set up just like the high level rest
client:
* The non-shadow jar will not be built
* The shadow jar will not have a "classifier"
* Tests will run against the shadow jar
* Javadoc will include all of the shadowed classes
* Service files in `META-INF/services` will be merged
javanna added a commit that referenced this pull request Jul 22, 2018
We have been encountering name mismatches between API defined in our
REST spec and method names that have been added to the high-level REST
client. We should check this automatically to prevent furher mismatches,
and correct all the current ones.

This commit adds a test for this and corrects the issues found by it.
dnhatn added a commit that referenced this pull request Jul 25, 2018
* 6.x:
  Security: revert to old way of merging automata (#32254)
  Fix a test bug in RangeQueryBuilderTests introduced in the field aliases backport.
  Introduce Application Privileges with support for Kibana RBAC (#32309)
  Undo a debugging change that snuck in during the field aliases merge.
  [test] port linux package packaging tests (#31943)
  Painless: Update More Methods to New Naming Scheme (#32305)
  Tribe: Add error with secure settings copied to tribe (#32298)
  Add V_6_3_3 version constant
  Add ERR to ranking evaluation documentation (#32314)
  [DOCS] Added link to 6.3.2 RNs
  [DOCS] Updates 6.3.2 release notes with PRs from ml-cpp repo (#32334)
  [Kerberos] Add Kerberos authentication support (#32263)
  [ML] Extract persistent task methods from MlMetadata (#32319)
  Backport - Add Snapshots Status API to High Level Rest Client (#32295)
  Make release notes ignore the `>test-failure` label. (#31309)
  [DOCS] Adds release highlights for search for 6.4 (#32095)
  Allow Integ Tests to run in a FIPS-140 JVM (#32316)
  Add support for field aliases to 6.x. (#32184)
  Register ERR metric with NamedXContentRegistry (#32320)
  fixes broken build for third-party-tests (#32315) Relates #31918 / Closes infra/issues/6085
  [DOCS] Rollup Caps API incorrectly mentions GET Jobs API (#32280)
  Rest HL client: Add put watch action (#32026) (#32191)
  Add WeightedAvg metric aggregation (#31037)
  Consistent encoder names (#29492)
  Switch monitoring to new style Requests (#32255)
  specify subdirs of lib, bin, modules in package (#32253)
  Rename ranking evaluation `quality_level` to `metric_score` (#32168)
  Add new permission for JDK11 to load JAAS libraries (#32132)
  Switch x-pack:core to new style Requests (#32252)
  Watcher: Store username on watch execution (#31873)
  Silence SSL reload test that fails on JDK 11
  Painless: Clean up add methods in PainlessLookup (#32258)
  CCE when re-throwing "shard not available" exception in TransportShardMultiGetAction (#32185)
  Fail shard if IndexShard#storeStats runs into an IOException (#32241)
  Fix `range` queries on `_type` field for singe type indices (#31756) (#32161)
  AwaitsFix RecoveryIT#testHistoryUUIDIsGenerated
  Add new fields to monitoring template for Beats state (#32085) (#32273)
  [TEST] improve REST high-level client naming conventions check (#32244)
  Check that client methods match API defined in the REST spec (#31825)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants