├── Gemfile
├── _config.yml
├── .gitignore
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .editorconfig
├── settings.gradle.kts
├── src
└── main
│ └── java
│ └── io
│ └── reactiverse
│ └── elasticsearch
│ └── client
│ └── package-info.java
├── shim-generator
├── src
│ └── main
│ │ ├── resources
│ │ └── logback.xml
│ │ └── java
│ │ └── shimgen
│ │ ├── NestedClientFinder.java
│ │ ├── Analyze.java
│ │ └── ShimMaker.java
└── build.gradle.kts
├── .github
└── workflows
│ └── ci-cd.yml
├── integration-tests
├── build.gradle.kts
└── src
│ └── test
│ └── java
│ └── integration
│ ├── MutinyTests.java
│ ├── RxJava2Tests.java
│ └── CallbackTests.java
├── README.md
├── gradlew.bat
├── elasticsearch-client-rxjava2
└── build.gradle.kts
├── elasticsearch-client-rxjava3
└── build.gradle.kts
├── elasticsearch-client-mutiny
└── build.gradle.kts
├── gradlew
└── LICENSE
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'github-pages', group: :jekyll_plugins
4 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 |
2 | theme: jekyll-theme-minimal
3 | repository: reactiverse/elasticsearch-client
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.ipr
2 | *.iws
3 | *.iml
4 | .gradle/
5 | .idea/
6 | build/
7 | out/
8 | **/src/main/generated
9 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/reactiverse/elasticsearch-client/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | trim_trailing_whitespace = true
8 | end_of_line = lf
9 | insert_final_newline = true
10 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | rootProject.name = "elasticsearch-client"
18 |
19 | include(
20 | "shim-generator",
21 | "integration-tests",
22 | "elasticsearch-client-rxjava2",
23 | "elasticsearch-client-rxjava3",
24 | "elasticsearch-client-mutiny"
25 | )
26 |
--------------------------------------------------------------------------------
/src/main/java/io/reactiverse/elasticsearch/client/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | @ModuleGen(groupPackage = "io.reactiverse.elasticsearch.client", name = "client")
18 | package io.reactiverse.elasticsearch.client;
19 |
20 | import io.vertx.codegen.annotations.ModuleGen;
21 |
--------------------------------------------------------------------------------
/shim-generator/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.github/workflows/ci-cd.yml:
--------------------------------------------------------------------------------
1 | name: Continuous integration and deployment
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | jobs:
10 | build:
11 | runs-on: ubuntu-latest
12 | steps:
13 |
14 | - uses: actions/checkout@v2
15 |
16 | - name: Set up JDK 8
17 | uses: actions/setup-java@v2
18 | with:
19 | java-version: '8'
20 | distribution: 'adopt'
21 |
22 | - name: Cache Gradle packages
23 | uses: actions/cache@v2
24 | with:
25 | path: |
26 | ~/.gradle/caches
27 | ~/.gradle/wrapper
28 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
29 | restore-keys: |
30 | ${{ runner.os }}-gradle-
31 |
32 | - name: Grant execute permission for gradlew
33 | run: chmod +x gradlew
34 |
35 | - name: Build with Gradle
36 | run: ./gradlew build
37 |
38 | - name: Deploy from the master branch
39 | if: github.ref == 'refs/heads/master'
40 | run: ./gradlew publish -PossrhUsername=${{ secrets.SONATYPE_NEXUS_USERNAME }} -PossrhPassword=${{ secrets.SONATYPE_NEXUS_PASSWORD }}
41 |
42 | - name: Cleanup Gradle Cache
43 | # Remove some files from the Gradle cache, so they aren't cached by GitHub Actions.
44 | # Restoring these files from a GitHub Actions cache might cause problems for future builds.
45 | run: |
46 | rm -f ~/.gradle/caches/modules-2/modules-2.lock
47 | rm -f ~/.gradle/caches/modules-2/gc.properties
48 |
--------------------------------------------------------------------------------
/integration-tests/build.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | plugins {
18 | java
19 | }
20 |
21 | val vertxVersion = extra["vertxVersion"]
22 | val mutinyBindingsVersion = extra["mutinyBindingsVersion"]
23 | val assertjVersion = extra["assertjVersion"]
24 | val tcVersion = extra["tcVersion"]
25 | val junitVersion = extra["junitVersion"]
26 |
27 | dependencies {
28 | testImplementation(project(":elasticsearch-client-rxjava2"))
29 | testImplementation(project(":elasticsearch-client-mutiny"))
30 |
31 | testImplementation("io.vertx:vertx-junit5:${vertxVersion}")
32 | testImplementation("io.vertx:vertx-junit5-rx-java2:${vertxVersion}")
33 | testImplementation("io.smallrye.reactive:smallrye-mutiny-vertx-junit5:${mutinyBindingsVersion}")
34 |
35 | testImplementation("org.assertj:assertj-core:${assertjVersion}")
36 | testImplementation("org.testcontainers:elasticsearch:${tcVersion}")
37 | testImplementation("org.testcontainers:junit-jupiter:${tcVersion}")
38 |
39 | testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}")
40 | testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}")
41 | }
42 |
43 | tasks.test {
44 | useJUnitPlatform()
45 | }
46 |
--------------------------------------------------------------------------------
/shim-generator/src/main/java/shimgen/NestedClientFinder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package shimgen;
18 |
19 | import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
20 | import com.github.javaparser.ast.body.MethodDeclaration;
21 | import com.github.javaparser.ast.visitor.GenericListVisitorAdapter;
22 | import org.slf4j.Logger;
23 | import org.slf4j.LoggerFactory;
24 |
25 | import java.util.Collections;
26 | import java.util.List;
27 |
28 | class NestedClientFinder extends GenericListVisitorAdapter {
29 |
30 | private final Logger logger = LoggerFactory.getLogger(NestedClientFinder.class);
31 |
32 | private ClassOrInterfaceDeclaration currentClass;
33 |
34 | @Override
35 | public List visit(ClassOrInterfaceDeclaration n, Void arg) {
36 | if (n.isPublic()) {
37 | currentClass = n;
38 | logger.info("Visiting class {}", n.getName());
39 | }
40 | return super.visit(n, arg);
41 | }
42 |
43 | @Override
44 | public List visit(MethodDeclaration n, Void arg) {
45 | if (n.isPublic()) {
46 | logger.info("Looking at {} in {}", n.getName(), currentClass.getName());
47 | String type = n.getTypeAsString();
48 | if (type.endsWith("Client") && !Analyze.FILTERED_TYPES.contains(type)) {
49 | return Collections.singletonList(type);
50 | }
51 | }
52 | return super.visit(n, arg);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/shim-generator/build.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | val elastic by configurations.creating
18 |
19 | val elasticSourcesDir = "$buildDir/elastic-sources/"
20 | val elasticShimsDir = "${buildDir}/elastic-shims"
21 |
22 | val elasticClientVersion = extra["elasticClientVersion"]
23 | val javaParserVersion = extra["javaParserVersion"]
24 | val logbackVersion = extra["logbackVersion"]
25 |
26 | dependencies {
27 | implementation("ch.qos.logback:logback-classic:${logbackVersion}")
28 | implementation("com.github.javaparser:javaparser-core:${javaParserVersion}")
29 | elastic("org.elasticsearch.client:elasticsearch-rest-high-level-client:${elasticClientVersion}:sources")
30 | }
31 |
32 | tasks {
33 |
34 | create("elastic-unpack") {
35 | val sources = elastic.resolve().filter { it.name.endsWith("-sources.jar") }
36 | sources.forEach { from(zipTree(it)) }
37 | into(elasticSourcesDir)
38 | }
39 |
40 | create("elastic-process") {
41 | main = "shimgen.Analyze"
42 | classpath = sourceSets["main"].runtimeClasspath
43 | args = listOf(
44 | "$elasticSourcesDir/org/elasticsearch/client/RestHighLevelClient.java",
45 | elasticShimsDir,
46 | "io.reactiverse.elasticsearch.client"
47 | )
48 | description = "Generate the shims from the ElasticSearch source code"
49 | group = "build"
50 | dependsOn("elastic-unpack")
51 | inputs.dir(elasticSourcesDir)
52 | outputs.dir(elasticShimsDir)
53 | }
54 | }
55 |
56 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # An Elasticsearch client for Eclipse Vert.x
2 |
3 | [](https://travis-ci.org/reactiverse/elasticsearch-client)
4 |
5 | This client exposes the [Elasticsearch Java High Level REST Client](https://www.elastic.co/guide/en/elasticsearch/client/java-rest/master/java-rest-high.html) for [Eclipse Vert.x](https://vertx.io/) applications.
6 |
7 | ## Overview
8 |
9 | This client is based on automatically generated shims using a source-to-source transformation from the client source code.
10 |
11 | The generated shims ensure that asynchronous event processing respect the Vert.x threading model.
12 |
13 | ## Usage
14 |
15 | The following modules can be used:
16 |
17 | * `elasticsearch-client`: a classic Vert.x API based on callbacks and Vert.x 4.1.0
18 | * `elasticsearch-client-mutiny`: a [Mutiny](https://smallrye.io/smallrye-mutiny/) API of the client
19 | * `elasticsearch-client-rxjava2`: a RxJava 2 API of the client
20 | * `elasticsearch-client-rxjava3`: a RxJava 3 API of the client
21 |
22 | The Maven `groupId` is `io.reactiverse`.
23 |
24 | ## Sample usage
25 |
26 | Here is a sample usage of the RxJava 2 API where an index request is followed by a get request:
27 |
28 | ```java
29 | String yo = "{\"foo\": \"bar\"}";
30 | IndexRequest req = new IndexRequest("posts", "_doc", "1").source(yo, XContentType.JSON);
31 | client
32 | .rxIndexAsync(req, RequestOptions.DEFAULT)
33 | .flatMap(resp -> client.rxGetAsync(new GetRequest("posts", "_all", "1"), RequestOptions.DEFAULT))
34 | .subscribe(resp -> {
35 | // Handle the response here
36 | });
37 | ```
38 |
39 | ## Legal
40 |
41 | Originally developped by [Julien Ponge](https://julien.ponge.org/).
42 |
43 | Copyright 2018 Red Hat, Inc.
44 |
45 | Licensed under the Apache License, Version 2.0 (the "License");
46 | you may not use this file except in compliance with the License.
47 | You may obtain a copy of the License at
48 |
49 | http://www.apache.org/licenses/LICENSE-2.0
50 |
51 | Unless required by applicable law or agreed to in writing, software
52 | distributed under the License is distributed on an "AS IS" BASIS,
53 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
54 | See the License for the specific language governing permissions and
55 | limitations under the License.
56 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/integration-tests/src/test/java/integration/MutinyTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Red Hat, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package integration;
17 |
18 | import io.reactiverse.elasticsearch.client.mutiny.RestHighLevelClient;
19 | import io.vertx.junit5.VertxExtension;
20 | import io.vertx.junit5.VertxTestContext;
21 | import io.vertx.mutiny.core.Vertx;
22 | import org.apache.http.HttpHost;
23 | import org.elasticsearch.action.get.GetRequest;
24 | import org.elasticsearch.action.index.IndexRequest;
25 | import org.elasticsearch.client.RequestOptions;
26 | import org.elasticsearch.client.RestClient;
27 | import org.elasticsearch.client.RestClientBuilder;
28 | import org.elasticsearch.common.xcontent.XContentType;
29 | import org.junit.jupiter.api.AfterEach;
30 | import org.junit.jupiter.api.BeforeEach;
31 | import org.junit.jupiter.api.Test;
32 | import org.junit.jupiter.api.extension.ExtendWith;
33 | import org.testcontainers.elasticsearch.ElasticsearchContainer;
34 | import org.testcontainers.junit.jupiter.Container;
35 | import org.testcontainers.junit.jupiter.Testcontainers;
36 |
37 | import static org.assertj.core.api.Assertions.assertThat;
38 |
39 | @Testcontainers
40 | @ExtendWith(VertxExtension.class)
41 | public class MutinyTests {
42 |
43 | @Container
44 | private ElasticsearchContainer container = new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.1");
45 |
46 | private RestHighLevelClient client;
47 |
48 | @BeforeEach
49 | void prepare(Vertx vertx) {
50 | RestClientBuilder builder = RestClient.builder(
51 | new HttpHost(container.getContainerIpAddress(), container.getMappedPort(9200), "http"));
52 | client = RestHighLevelClient.create(vertx, builder);
53 | }
54 |
55 | @AfterEach
56 | void close() {
57 | client.close();
58 | }
59 |
60 | @Test
61 | void indexThenGet(Vertx vertx, VertxTestContext testContext) {
62 | String yo = "{\"foo\": \"bar\"}";
63 | IndexRequest req = new IndexRequest("posts", "_doc", "1").source(yo, XContentType.JSON);
64 | client
65 | .indexAsync(req, RequestOptions.DEFAULT)
66 | .chain(resp -> client.getAsync(new GetRequest("posts", "_all", "1"), RequestOptions.DEFAULT))
67 | .subscribe().with((resp -> testContext.verify(() -> {
68 | assertThat(Thread.currentThread().getName()).startsWith("vert.x-eventloop-thread-");
69 | assertThat(vertx.getOrCreateContext().isEventLoopContext()).isTrue();
70 | assertThat(resp.getType()).isEqualTo("_doc");
71 | assertThat(resp.getSourceAsMap()).hasEntrySatisfying("foo", "bar"::equals);
72 | testContext.completeNow();
73 | })), testContext::failNow);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/integration-tests/src/test/java/integration/RxJava2Tests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package integration;
18 |
19 | import io.reactiverse.elasticsearch.client.reactivex.RestHighLevelClient;
20 | import io.vertx.junit5.VertxExtension;
21 | import io.vertx.junit5.VertxTestContext;
22 | import io.vertx.reactivex.core.Vertx;
23 | import org.apache.http.HttpHost;
24 | import org.elasticsearch.action.get.GetRequest;
25 | import org.elasticsearch.action.index.IndexRequest;
26 | import org.elasticsearch.client.RequestOptions;
27 | import org.elasticsearch.client.RestClient;
28 | import org.elasticsearch.client.RestClientBuilder;
29 | import org.elasticsearch.common.xcontent.XContentType;
30 | import org.junit.jupiter.api.AfterEach;
31 | import org.junit.jupiter.api.BeforeEach;
32 | import org.junit.jupiter.api.Test;
33 | import org.junit.jupiter.api.extension.ExtendWith;
34 | import org.testcontainers.elasticsearch.ElasticsearchContainer;
35 | import org.testcontainers.junit.jupiter.Container;
36 | import org.testcontainers.junit.jupiter.Testcontainers;
37 |
38 | import static org.assertj.core.api.Assertions.assertThat;
39 |
40 | @Testcontainers
41 | @ExtendWith(VertxExtension.class)
42 | public class RxJava2Tests {
43 |
44 | @Container
45 | private ElasticsearchContainer container = new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.1");
46 |
47 | private RestHighLevelClient client;
48 |
49 | @BeforeEach
50 | void prepare(Vertx vertx) {
51 | RestClientBuilder builder = RestClient.builder(
52 | new HttpHost(container.getContainerIpAddress(), container.getMappedPort(9200), "http"));
53 | client = RestHighLevelClient.create(vertx, builder);
54 | }
55 |
56 | @AfterEach
57 | void close() {
58 | client.close();
59 | }
60 |
61 | @Test
62 | void indexThenGet(Vertx vertx, VertxTestContext testContext) {
63 | String yo = "{\"foo\": \"bar\"}";
64 | IndexRequest req = new IndexRequest("posts", "_doc", "1").source(yo, XContentType.JSON);
65 | client
66 | .rxIndexAsync(req, RequestOptions.DEFAULT)
67 | .flatMap(resp -> client.rxGetAsync(new GetRequest("posts", "_all", "1"), RequestOptions.DEFAULT))
68 | .subscribe(resp -> testContext.verify(() -> {
69 | assertThat(Thread.currentThread().getName()).startsWith("vert.x-eventloop-thread-");
70 | assertThat(vertx.getOrCreateContext().isEventLoopContext()).isTrue();
71 | assertThat(resp.getType()).isEqualTo("_doc");
72 | assertThat(resp.getSourceAsMap()).hasEntrySatisfying("foo", "bar"::equals);
73 | testContext.completeNow();
74 | }), testContext::failNow);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/elasticsearch-client-rxjava2/build.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | plugins {
18 | `java-library`
19 | `maven-publish`
20 | signing
21 | }
22 |
23 | val vertxVersion = extra["vertxVersion"]
24 |
25 | dependencies {
26 | api(rootProject)
27 | api("io.vertx:vertx-rx-java2:${vertxVersion}")
28 | compileOnly("io.vertx:vertx-codegen:${vertxVersion}")
29 | annotationProcessor("io.vertx:vertx-rx-java2:${vertxVersion}")
30 | annotationProcessor("io.vertx:vertx-rx-java2-gen:${vertxVersion}")
31 | annotationProcessor("io.vertx:vertx-codegen:${vertxVersion}:processor")
32 | }
33 |
34 | sourceSets {
35 | main {
36 | java {
37 | setSrcDirs(listOf("../src/main/generated", "src/main/generated"))
38 | }
39 | }
40 | }
41 |
42 | tasks {
43 | getByName("compileJava") {
44 | options.annotationProcessorGeneratedSourcesDirectory = File("$projectDir/src/main/generated")
45 | }
46 |
47 | getByName("clean") {
48 | delete.add("src/main/generated")
49 | }
50 |
51 | getByName("jar") {
52 | exclude("io/vertx/elasticsearch/client/*.class")
53 | }
54 |
55 | create("sourcesJar") {
56 | from(sourceSets.main.get().allJava)
57 | classifier = "sources"
58 | }
59 |
60 | create("javadocJar") {
61 | from(javadoc)
62 | classifier = "javadoc"
63 | }
64 |
65 | javadoc {
66 | if (JavaVersion.current().isJava9Compatible) {
67 | (options as StandardJavadocDocletOptions).addBooleanOption("html5", true)
68 | }
69 | }
70 |
71 | withType {
72 | onlyIf { project.extra["isReleaseVersion"] as Boolean }
73 | }
74 | }
75 |
76 | publishing {
77 | publications {
78 | create("mavenJava") {
79 | from(components["java"])
80 | artifact(tasks["sourcesJar"])
81 | artifact(tasks["javadocJar"])
82 | pom {
83 | name.set(project.name)
84 | description.set("Reactiverse Elasticsearch client :: RxJava2 bindings")
85 | url.set("https://github.com/reactiverse/elasticsearch-client")
86 | licenses {
87 | license {
88 | name.set("The Apache License, Version 2.0")
89 | url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
90 | }
91 | }
92 | developers {
93 | developer {
94 | id.set("jponge")
95 | name.set("Julien Ponge")
96 | email.set("julien.ponge@gmail.com")
97 | }
98 | }
99 | scm {
100 | connection.set("scm:git:git@github.com:reactiverse/elasticsearch-client.git")
101 | developerConnection.set("scm:git:git@github.com:reactiverse/elasticsearch-client.git")
102 | url.set("https://github.com/reactiverse/elasticsearch-client")
103 | }
104 | }
105 | }
106 | }
107 | repositories {
108 | // To locally check out the poms
109 | maven {
110 | val releasesRepoUrl = uri("$buildDir/repos/releases")
111 | val snapshotsRepoUrl = uri("$buildDir/repos/snapshots")
112 | name = "BuildDir"
113 | url = if (project.extra["isReleaseVersion"] as Boolean) releasesRepoUrl else snapshotsRepoUrl
114 | }
115 | maven {
116 | val releasesRepoUrl = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
117 | val snapshotsRepoUrl = uri("https://oss.sonatype.org/content/repositories/snapshots/")
118 | name = "SonatypeOSS"
119 | url = if (project.extra["isReleaseVersion"] as Boolean) releasesRepoUrl else snapshotsRepoUrl
120 | credentials {
121 | val ossrhUsername: String by project
122 | val ossrhPassword: String by project
123 | username = ossrhUsername
124 | password = ossrhPassword
125 | }
126 | }
127 | }
128 | }
129 |
130 | signing {
131 | sign(publishing.publications["mavenJava"])
132 | }
133 |
--------------------------------------------------------------------------------
/elasticsearch-client-rxjava3/build.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | plugins {
18 | `java-library`
19 | `maven-publish`
20 | signing
21 | }
22 |
23 | val vertxVersion = extra["vertxVersion"]
24 |
25 | dependencies {
26 | api(rootProject)
27 | api("io.vertx:vertx-rx-java3:${vertxVersion}")
28 | compileOnly("io.vertx:vertx-codegen:${vertxVersion}")
29 | annotationProcessor("io.vertx:vertx-rx-java3:${vertxVersion}")
30 | annotationProcessor("io.vertx:vertx-rx-java3-gen:${vertxVersion}")
31 | annotationProcessor("io.vertx:vertx-codegen:${vertxVersion}:processor")
32 | }
33 |
34 | sourceSets {
35 | main {
36 | java {
37 | setSrcDirs(listOf("../src/main/generated", "src/main/generated"))
38 | }
39 | }
40 | }
41 |
42 | tasks {
43 | getByName("compileJava") {
44 | options.annotationProcessorGeneratedSourcesDirectory = File("$projectDir/src/main/generated")
45 | }
46 |
47 | getByName("clean") {
48 | delete.add("src/main/generated")
49 | }
50 |
51 | getByName("jar") {
52 | exclude("io/vertx/elasticsearch/client/*.class")
53 | }
54 |
55 | create("sourcesJar") {
56 | from(sourceSets.main.get().allJava)
57 | classifier = "sources"
58 | }
59 |
60 | create("javadocJar") {
61 | from(javadoc)
62 | classifier = "javadoc"
63 | }
64 |
65 | javadoc {
66 | if (JavaVersion.current().isJava9Compatible) {
67 | (options as StandardJavadocDocletOptions).addBooleanOption("html5", true)
68 | }
69 | }
70 |
71 | withType {
72 | onlyIf { project.extra["isReleaseVersion"] as Boolean }
73 | }
74 | }
75 |
76 | publishing {
77 | publications {
78 | create("mavenJava") {
79 | from(components["java"])
80 | artifact(tasks["sourcesJar"])
81 | artifact(tasks["javadocJar"])
82 | pom {
83 | name.set(project.name)
84 | description.set("Reactiverse Elasticsearch client :: RxJava3 bindings")
85 | url.set("https://github.com/reactiverse/elasticsearch-client")
86 | licenses {
87 | license {
88 | name.set("The Apache License, Version 2.0")
89 | url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
90 | }
91 | }
92 | developers {
93 | developer {
94 | id.set("jponge")
95 | name.set("Julien Ponge")
96 | email.set("julien.ponge@gmail.com")
97 | }
98 | }
99 | scm {
100 | connection.set("scm:git:git@github.com:reactiverse/elasticsearch-client.git")
101 | developerConnection.set("scm:git:git@github.com:reactiverse/elasticsearch-client.git")
102 | url.set("https://github.com/reactiverse/elasticsearch-client")
103 | }
104 | }
105 | }
106 | }
107 | repositories {
108 | // To locally check out the poms
109 | maven {
110 | val releasesRepoUrl = uri("$buildDir/repos/releases")
111 | val snapshotsRepoUrl = uri("$buildDir/repos/snapshots")
112 | name = "BuildDir"
113 | url = if (project.extra["isReleaseVersion"] as Boolean) releasesRepoUrl else snapshotsRepoUrl
114 | }
115 | maven {
116 | val releasesRepoUrl = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
117 | val snapshotsRepoUrl = uri("https://oss.sonatype.org/content/repositories/snapshots/")
118 | name = "SonatypeOSS"
119 | url = if (project.extra["isReleaseVersion"] as Boolean) releasesRepoUrl else snapshotsRepoUrl
120 | credentials {
121 | val ossrhUsername: String by project
122 | val ossrhPassword: String by project
123 | username = ossrhUsername
124 | password = ossrhPassword
125 | }
126 | }
127 | }
128 | }
129 |
130 | signing {
131 | sign(publishing.publications["mavenJava"])
132 | }
133 |
--------------------------------------------------------------------------------
/elasticsearch-client-mutiny/build.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | plugins {
18 | `java-library`
19 | `maven-publish`
20 | signing
21 | }
22 |
23 | val vertxVersion = extra["vertxVersion"]
24 | val mutinyBindingsVersion = extra["mutinyBindingsVersion"]
25 |
26 | dependencies {
27 | api(rootProject)
28 | api("io.smallrye.reactive:smallrye-mutiny-vertx-core:${mutinyBindingsVersion}")
29 | compileOnly("io.vertx:vertx-codegen:${vertxVersion}")
30 | annotationProcessor("io.smallrye.reactive:vertx-mutiny-generator:${mutinyBindingsVersion}")
31 | annotationProcessor("io.vertx:vertx-codegen:${vertxVersion}:processor")
32 | }
33 |
34 | sourceSets {
35 | main {
36 | java {
37 | setSrcDirs(listOf("../src/main/generated", "src/main/generated"))
38 | }
39 | }
40 | }
41 |
42 | tasks {
43 | getByName("compileJava") {
44 | options.annotationProcessorGeneratedSourcesDirectory = File("$projectDir/src/main/generated")
45 | }
46 |
47 | getByName("clean") {
48 | delete.add("src/main/generated")
49 | }
50 |
51 | getByName("jar") {
52 | exclude("io/vertx/elasticsearch/client/*.class")
53 | }
54 |
55 | create("sourcesJar") {
56 | from(sourceSets.main.get().allJava)
57 | classifier = "sources"
58 | }
59 |
60 | create("javadocJar") {
61 | from(javadoc)
62 | classifier = "javadoc"
63 | }
64 |
65 | javadoc {
66 | if (JavaVersion.current().isJava9Compatible) {
67 | (options as StandardJavadocDocletOptions).addBooleanOption("html5", true)
68 | }
69 | }
70 |
71 | withType {
72 | onlyIf { project.extra["isReleaseVersion"] as Boolean }
73 | }
74 | }
75 |
76 | publishing {
77 | publications {
78 | create("mavenJava") {
79 | from(components["java"])
80 | artifact(tasks["sourcesJar"])
81 | artifact(tasks["javadocJar"])
82 | pom {
83 | name.set(project.name)
84 | description.set("Reactiverse Elasticsearch client :: Mutiny bindings")
85 | url.set("https://github.com/reactiverse/elasticsearch-client")
86 | licenses {
87 | license {
88 | name.set("The Apache License, Version 2.0")
89 | url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
90 | }
91 | }
92 | developers {
93 | developer {
94 | id.set("jponge")
95 | name.set("Julien Ponge")
96 | email.set("julien.ponge@gmail.com")
97 | }
98 | }
99 | scm {
100 | connection.set("scm:git:git@github.com:reactiverse/elasticsearch-client.git")
101 | developerConnection.set("scm:git:git@github.com:reactiverse/elasticsearch-client.git")
102 | url.set("https://github.com/reactiverse/elasticsearch-client")
103 | }
104 | }
105 | }
106 | }
107 | repositories {
108 | // To locally check out the poms
109 | maven {
110 | val releasesRepoUrl = uri("$buildDir/repos/releases")
111 | val snapshotsRepoUrl = uri("$buildDir/repos/snapshots")
112 | name = "BuildDir"
113 | url = if (project.extra["isReleaseVersion"] as Boolean) releasesRepoUrl else snapshotsRepoUrl
114 | }
115 | maven {
116 | val releasesRepoUrl = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
117 | val snapshotsRepoUrl = uri("https://oss.sonatype.org/content/repositories/snapshots/")
118 | name = "SonatypeOSS"
119 | url = if (project.extra["isReleaseVersion"] as Boolean) releasesRepoUrl else snapshotsRepoUrl
120 | credentials {
121 | val ossrhUsername: String by project
122 | val ossrhPassword: String by project
123 | username = ossrhUsername
124 | password = ossrhPassword
125 | }
126 | }
127 | }
128 | }
129 |
130 | signing {
131 | sign(publishing.publications["mavenJava"])
132 | }
133 |
--------------------------------------------------------------------------------
/integration-tests/src/test/java/integration/CallbackTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package integration;
18 |
19 | import io.reactiverse.elasticsearch.client.RestHighLevelClient;
20 | import io.vertx.core.Vertx;
21 | import io.vertx.junit5.VertxExtension;
22 | import io.vertx.junit5.VertxTestContext;
23 | import org.apache.http.HttpHost;
24 | import org.elasticsearch.action.DocWriteResponse;
25 | import org.elasticsearch.action.admin.cluster.settings.ClusterGetSettingsRequest;
26 | import org.elasticsearch.action.admin.cluster.settings.ClusterGetSettingsResponse;
27 | import org.elasticsearch.action.get.GetRequest;
28 | import org.elasticsearch.action.index.IndexRequest;
29 | import org.elasticsearch.action.index.IndexResponse;
30 | import org.elasticsearch.client.RequestOptions;
31 | import org.elasticsearch.client.RestClient;
32 | import org.elasticsearch.client.RestClientBuilder;
33 | import org.elasticsearch.common.xcontent.XContentType;
34 | import org.elasticsearch.rest.RestStatus;
35 | import org.junit.jupiter.api.AfterEach;
36 | import org.junit.jupiter.api.BeforeEach;
37 | import org.junit.jupiter.api.Test;
38 | import org.junit.jupiter.api.extension.ExtendWith;
39 | import org.testcontainers.elasticsearch.ElasticsearchContainer;
40 | import org.testcontainers.junit.jupiter.Container;
41 | import org.testcontainers.junit.jupiter.Testcontainers;
42 |
43 | import static org.assertj.core.api.Assertions.assertThat;
44 |
45 | @Testcontainers
46 | @ExtendWith(VertxExtension.class)
47 | class CallbackTests {
48 |
49 | @Container
50 | private ElasticsearchContainer container = new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.1");
51 |
52 | private RestHighLevelClient client;
53 |
54 | @BeforeEach
55 | void prepare(Vertx vertx) {
56 | RestClientBuilder builder = RestClient.builder(
57 | new HttpHost(container.getContainerIpAddress(), container.getMappedPort(9200), "http"));
58 | client = RestHighLevelClient.create(vertx, builder);
59 | }
60 |
61 | @AfterEach
62 | void close() {
63 | client.close();
64 | }
65 |
66 | @Test
67 | void index(VertxTestContext testContext) {
68 | String yo = "{\"foo\": \"bar\"}";
69 | IndexRequest req = new IndexRequest("posts").source(yo, XContentType.JSON);
70 | client.indexAsync(req, RequestOptions.DEFAULT, ar -> {
71 | if (ar.succeeded()) {
72 | IndexResponse response = ar.result();
73 | testContext.verify(() -> {
74 | assertThat(response.status()).isEqualByComparingTo(RestStatus.CREATED);
75 | assertThat(response.getResult()).isEqualByComparingTo(DocWriteResponse.Result.CREATED);
76 | testContext.completeNow();
77 | });
78 | } else {
79 | testContext.failNow(ar.cause());
80 | }
81 | });
82 | }
83 |
84 | @Test
85 | void getClusterSettings(VertxTestContext testContext) {
86 | ClusterGetSettingsRequest req = new ClusterGetSettingsRequest();
87 | client.cluster().getSettingsAsync(req, RequestOptions.DEFAULT, ar -> {
88 | if (ar.succeeded()) {
89 | ClusterGetSettingsResponse response = ar.result();
90 | testContext.verify(() -> {
91 | assertThat(response).isNotNull();
92 | assertThat(response.getTransientSettings().isEmpty()).isTrue();
93 | assertThat(response.getPersistentSettings().isEmpty()).isTrue();
94 | testContext.completeNow();
95 | });
96 | } else {
97 | testContext.failNow(ar.cause());
98 | }
99 | });
100 | }
101 |
102 | @Test
103 | void checkThreadingModel(Vertx vertx, VertxTestContext testContext) {
104 | client.existsAsync(new GetRequest(), RequestOptions.DEFAULT, event -> {
105 | testContext.verify(() -> {
106 | assertThat(Thread.currentThread().getName()).startsWith("vert.x-eventloop-thread-");
107 | assertThat(vertx.getOrCreateContext().isEventLoopContext()).isTrue();
108 | testContext.completeNow();
109 | });
110 | });
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/shim-generator/src/main/java/shimgen/Analyze.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package shimgen;
18 |
19 | import com.github.javaparser.JavaParser;
20 | import com.github.javaparser.ast.CompilationUnit;
21 | import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
22 | import org.slf4j.Logger;
23 | import org.slf4j.LoggerFactory;
24 |
25 | import java.io.File;
26 | import java.io.IOException;
27 | import java.nio.file.Files;
28 | import java.util.Collections;
29 | import java.util.HashSet;
30 | import java.util.List;
31 |
32 | public class Analyze {
33 |
34 | private static final Logger logger = LoggerFactory.getLogger(Analyze.class);
35 |
36 | static final HashSet FILTERED_TYPES = new HashSet() {
37 | {
38 | add("RestClient");
39 | add("MigrationClient");
40 | }
41 | };
42 |
43 | private static final String autoGeneratedComment = "\n" +
44 | "[NOTE] This is an automatically generated file.\n" +
45 | " Do not make changes to this file but to the shim code generator.\n" +
46 | "\n";
47 |
48 | private static String pathToMainFile;
49 | private static String pathToGeneration;
50 | private static String targetPackageName;
51 | private static String pathToMainPackage;
52 |
53 | public static void main(String[] args) throws IOException {
54 |
55 | if (args.length != 3) {
56 | logger.error("Expecting 3 arguments: the path to RestHighLevelClient.java, then the path to the code generation directory, then the generated code package name");
57 | System.exit(1);
58 | }
59 |
60 | pathToMainFile = args[0];
61 | pathToMainPackage = new File(pathToMainFile).getParent();
62 | pathToGeneration = args[1];
63 | targetPackageName = args[2];
64 | logger.info("Analyzing {}, generating code to {} in package {}", pathToMainFile, pathToGeneration, targetPackageName);
65 |
66 | new Analyze().run();
67 | }
68 |
69 | private void run() throws IOException {
70 | CompilationUnit unit = JavaParser.parse(new File(pathToMainFile));
71 | List nestedClients = unit.accept(new NestedClientFinder(), null);
72 | logger.info("Found the following nested clients: {}", nestedClients);
73 |
74 | generatedFilesPackageDir().mkdirs();
75 | generateCode("RestHighLevelClient");
76 | for (String nestedClient : nestedClients) {
77 | generateCode(nestedClient);
78 | }
79 | }
80 |
81 | private File generatedFilesPackageDir() {
82 | return new File(pathToGeneration, targetPackageName.replace('.', '/'));
83 | }
84 |
85 | private void generateCode(String unitName) throws IOException {
86 | File inputFile = new File(pathToMainPackage, unitName + ".java");
87 | CompilationUnit sourceUnit = JavaParser.parse(inputFile);
88 |
89 | CompilationUnit shimInterfaceUnit = new CompilationUnit();
90 | shimInterfaceUnit.setBlockComment(autoGeneratedComment);
91 | shimInterfaceUnit
92 | .setPackageDeclaration(targetPackageName)
93 | .addImport("io.vertx.core.*")
94 | .addImport("io.vertx.codegen.annotations.*")
95 | .addImport("org.elasticsearch.client.*");
96 |
97 | ClassOrInterfaceDeclaration shimInterface = shimInterfaceUnit
98 | .addInterface(unitName)
99 | .addAnnotation("VertxGen");
100 |
101 | CompilationUnit shimImplementationUnit = new CompilationUnit();
102 | shimImplementationUnit.setBlockComment(autoGeneratedComment);
103 | shimImplementationUnit
104 | .setPackageDeclaration(targetPackageName)
105 | .addImport("io.vertx.core.*")
106 | .addImport("org.elasticsearch.client.*");
107 |
108 | ClassOrInterfaceDeclaration shimImplementation = shimImplementationUnit
109 | .addClass(unitName + "Impl")
110 | .setPublic(false)
111 | .addImplementedType(unitName);
112 |
113 | sourceUnit.accept(new ShimMaker(shimInterfaceUnit, shimInterface, shimImplementationUnit, shimImplementation), null);
114 |
115 | logger.debug("Interface:\n{} ", shimInterfaceUnit.toString());
116 | logger.debug("Implementation:\n{} ", shimImplementationUnit.toString());
117 | Files.write(new File(generatedFilesPackageDir(), unitName + ".java").toPath(), Collections.singletonList(shimInterfaceUnit.toString()));
118 | Files.write(new File(generatedFilesPackageDir(), unitName + "Impl.java").toPath(), Collections.singletonList(shimImplementationUnit.toString()));
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/shim-generator/src/main/java/shimgen/ShimMaker.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Red Hat, Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package shimgen;
18 |
19 | import com.github.javaparser.JavaParser;
20 | import com.github.javaparser.ast.CompilationUnit;
21 | import com.github.javaparser.ast.ImportDeclaration;
22 | import com.github.javaparser.ast.Modifier;
23 | import com.github.javaparser.ast.NodeList;
24 | import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
25 | import com.github.javaparser.ast.body.ConstructorDeclaration;
26 | import com.github.javaparser.ast.body.MethodDeclaration;
27 | import com.github.javaparser.ast.body.Parameter;
28 | import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
29 | import com.github.javaparser.ast.stmt.BlockStmt;
30 | import com.github.javaparser.ast.type.Type;
31 | import com.github.javaparser.ast.type.TypeParameter;
32 | import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
33 | import org.slf4j.Logger;
34 | import org.slf4j.LoggerFactory;
35 |
36 | import java.util.Optional;
37 | import java.util.stream.Collectors;
38 |
39 | class ShimMaker extends VoidVisitorAdapter {
40 |
41 | private final Logger logger = LoggerFactory.getLogger(ShimMaker.class);
42 |
43 | private final CompilationUnit shimInterfaceUnit;
44 | private final ClassOrInterfaceDeclaration shimInterface;
45 | private final CompilationUnit shimImplementationUnit;
46 | private final ClassOrInterfaceDeclaration shimImplementation;
47 |
48 | ShimMaker(CompilationUnit shimInterfaceUnit, ClassOrInterfaceDeclaration shimInterface, CompilationUnit shimImplementationUnit, ClassOrInterfaceDeclaration shimImplementation) {
49 | this.shimInterfaceUnit = shimInterfaceUnit;
50 | this.shimInterface = shimInterface;
51 | this.shimImplementationUnit = shimImplementationUnit;
52 | this.shimImplementation = shimImplementation;
53 | }
54 |
55 | @Override
56 | public void visit(ImportDeclaration n, Void arg) {
57 | shimInterfaceUnit.addImport(n);
58 | shimImplementationUnit.addImport(n);
59 | super.visit(n, arg);
60 | }
61 |
62 | @Override
63 | public void visit(ClassOrInterfaceDeclaration n, Void arg) {
64 | if (n.getNameAsString().equals("RestHighLevelClient")) {
65 | super.visit(n, arg);
66 | return;
67 | }
68 | logger.info("Client class {}, generating a constructor", n.getNameAsString());
69 |
70 | String delegateType = "org.elasticsearch.client." + n.getNameAsString();
71 |
72 | shimImplementation
73 | .addField("Vertx", "vertx")
74 | .setPrivate(true)
75 | .setFinal(true);
76 |
77 | shimImplementation
78 | .addField(delegateType, "delegate")
79 | .setPrivate(true)
80 | .setFinal(true);
81 |
82 | String code = "{\n" +
83 | " this.vertx = vertx;\n" +
84 | " this.delegate = delegate;" +
85 | "}\n";
86 |
87 | shimImplementation
88 | .addConstructor()
89 | .addParameter("Vertx", "vertx")
90 | .addParameter(delegateType, "delegate")
91 | .setBody(JavaParser.parseBlock(code));
92 |
93 | super.visit(n, arg);
94 | }
95 |
96 | @Override
97 | public void visit(ConstructorDeclaration n, Void arg) {
98 | if (n.isPublic()) {
99 | NodeList parameters = NodeList.nodeList(n.getParameters());
100 | parameters.add(0, new Parameter(new TypeParameter("Vertx"), "vertx"));
101 | logger.info("Interface factory method with parameters {}", parameters);
102 |
103 | BlockStmt createBlock = new BlockStmt();
104 | shimInterface
105 | .addMethod("create", Modifier.Keyword.STATIC)
106 | .addSingleMemberAnnotation("GenIgnore", "GenIgnore.PERMITTED_TYPE")
107 | .setType(shimInterface.getNameAsString())
108 | .setParameters(parameters)
109 | .setBody(createBlock);
110 | String args = parameters
111 | .stream()
112 | .map(Parameter::getNameAsString)
113 | .collect(Collectors.joining(", "));
114 | String implCreation = "return new " + shimImplementation.getNameAsString() + "(" + args + ");";
115 | createBlock.addStatement(JavaParser.parseStatement(implCreation));
116 |
117 | BlockStmt constructorBlock = new BlockStmt();
118 | ConstructorDeclaration constructor = shimImplementation
119 | .addConstructor()
120 | .setParameters(parameters)
121 | .setBody(constructorBlock);
122 |
123 | parameters.forEach(p -> {
124 | shimImplementation
125 | .addField(p.getType(), p.getNameAsString())
126 | .setPrivate(true)
127 | .setFinal(true);
128 | constructorBlock
129 | .addStatement(JavaParser.parseStatement("this." + p.getNameAsString() + " = " + p.getNameAsString() + ";"));
130 | });
131 |
132 | String constructorArgs = parameters
133 | .stream()
134 | .map(Parameter::getNameAsString)
135 | .filter(p -> !"vertx".equals(p))
136 | .collect(Collectors.joining(", "));
137 | constructorBlock
138 | .addStatement(JavaParser.parseStatement("this.delegate = new org.elasticsearch.client." + shimInterface.getNameAsString() + "(" + constructorArgs + ");"));
139 |
140 | shimImplementation
141 | .addField("org.elasticsearch.client." + shimInterface.getNameAsString(), "delegate")
142 | .setPrivate(true)
143 | .setFinal(true);
144 | }
145 | super.visit(n, arg);
146 | }
147 |
148 | @Override
149 | public void visit(MethodDeclaration n, Void arg) {
150 | if (isAsyncMethod(n)) {
151 | generateAsyncMethod(n);
152 | } else if (isNestedClientMethod(n)) {
153 | generateNestedClientMethod(n);
154 | } else if (isPassThroughMethod(n)) {
155 | generatePassThrough(n);
156 | }
157 | super.visit(n, arg);
158 | }
159 |
160 | private static final String ASYNC_DISPATCH_TEMPLATE = "{\n" +
161 | " Context context = vertx.getOrCreateContext();\n" +
162 | " delegate.{{METHOD}}({{ARGS}} new ActionListener<{{TYPE}}>() {\n" +
163 | " @Override\n" +
164 | " public void onResponse({{TYPE}} value) {\n" +
165 | " context.runOnContext(v -> handler.handle(Future.succeededFuture(value)));\n" +
166 | " }\n" +
167 | "\n" +
168 | " @Override\n" +
169 | " public void onFailure(Exception e) {\n" +
170 | " context.runOnContext(v -> handler.handle(Future.failedFuture(e)));\n" +
171 | " }\n" +
172 | " });\n" +
173 | " }";
174 |
175 | private void generateAsyncMethod(MethodDeclaration n) {
176 | logger.info("Async method shim for {}", n.getNameAsString());
177 | NodeList parameters = NodeList.nodeList(n.getParameters());
178 | Parameter lastParameter = parameters.get(parameters.size() - 1);
179 | Optional> typeArguments = lastParameter.getType().asClassOrInterfaceType().getTypeArguments();
180 | if (!typeArguments.isPresent() || typeArguments.get().size() != 1) {
181 | logger.warn("Not processing {} as the last argument is of actual type {}", n.getNameAsString(), lastParameter.getType());
182 | return;
183 | }
184 | Type parametricType = typeArguments.get().get(0);
185 | lastParameter.setType("Handler>");
186 | lastParameter.setName("handler");
187 |
188 | shimInterface
189 | .addMethod(n.getNameAsString())
190 | .setType("void")
191 | .setParameters(parameters)
192 | .removeBody()
193 | .addSingleMemberAnnotation("GenIgnore", "GenIgnore.PERMITTED_TYPE");
194 |
195 | NodeList callParameters = NodeList.nodeList(parameters);
196 | callParameters.removeLast();
197 | String callArgs = callParameters
198 | .stream()
199 | .map(NodeWithSimpleName::getNameAsString)
200 | .collect(Collectors.joining(", "));
201 | if (!callArgs.isEmpty()) {
202 | callArgs = callArgs + ", ";
203 | }
204 |
205 | String shimCode = ASYNC_DISPATCH_TEMPLATE
206 | .replace("{{METHOD}}", n.getNameAsString())
207 | .replace("{{ARGS}}", callArgs)
208 | .replace("{{TYPE}}", parametricType.toString());
209 |
210 | logger.debug("Code -> \n{}", shimCode);
211 |
212 | shimImplementation
213 | .addMethod(n.getNameAsString())
214 | .setPublic(true)
215 | .addAnnotation("Override")
216 | .setType("void")
217 | .setParameters(parameters)
218 | .setBody(JavaParser.parseBlock(shimCode));
219 | }
220 |
221 | private void generateNestedClientMethod(MethodDeclaration n) {
222 | String methodName = n.getNameAsString();
223 | String methodType = n.getTypeAsString();
224 | if (Analyze.FILTERED_TYPES.contains(methodType)) {
225 | logger.debug("Skipping {} as the return type is being filtered", methodName);
226 | return;
227 | }
228 | logger.info("Nested client method shim for {}", methodName);
229 |
230 | shimInterface
231 | .addMethod(methodName)
232 | .setType(n.getType())
233 | .setParameters(n.getParameters())
234 | .removeBody()
235 | .addSingleMemberAnnotation("GenIgnore", "GenIgnore.PERMITTED_TYPE");
236 |
237 | String callArgs = n.getParameters()
238 | .stream()
239 | .map(NodeWithSimpleName::getNameAsString)
240 | .collect(Collectors.joining(", "));
241 |
242 | String shimCode = "{ return new " + methodType + "Impl(vertx, delegate." + methodName + "(" + callArgs + ")); }";
243 | MethodDeclaration impl = shimImplementation
244 | .addMethod(methodName)
245 | .setPublic(true)
246 | .addAnnotation("Override")
247 | .setType(n.getType())
248 | .setParameters(n.getParameters())
249 | .setBody(JavaParser.parseBlock(shimCode));
250 | }
251 |
252 | private void generatePassThrough(MethodDeclaration n) {
253 | logger.info("Passthrough method {}", n.getNameAsString());
254 | MethodDeclaration method = shimInterface
255 | .addMethod(n.getNameAsString())
256 | .setType(n.getType())
257 | .setParameters(n.getParameters())
258 | .removeBody()
259 | .addSingleMemberAnnotation("GenIgnore", "GenIgnore.PERMITTED_TYPE");
260 |
261 | String callArgs = n.getParameters()
262 | .stream()
263 | .map(NodeWithSimpleName::getNameAsString)
264 | .collect(Collectors.joining(", "));
265 |
266 | String shimCode;
267 | if ("void".equals(n.getTypeAsString())) {
268 | shimCode = "delegate." + n.getName() + "(" + callArgs + ");";
269 | } else {
270 | shimCode = "return delegate." + n.getName() + "(" + callArgs + ");";
271 | }
272 | shimCode = "{try {\n" +
273 | shimCode + "\n" +
274 | "} catch (Throwable t) {\n" +
275 | " throw new RuntimeException(t);\n" +
276 | "}}";
277 |
278 | MethodDeclaration impl = shimImplementation
279 | .addMethod(n.getNameAsString())
280 | .setPublic(true)
281 | .addAnnotation("Override")
282 | .setType(n.getType())
283 | .setParameters(n.getParameters())
284 | .setBody(JavaParser.parseBlock(shimCode));
285 | }
286 |
287 | private boolean isAsyncMethod(MethodDeclaration n) {
288 | return n.isPublic() && n.getNameAsString().endsWith("Async") && !n.isAnnotationPresent("Deprecated");
289 | }
290 |
291 | private boolean isNestedClientMethod(MethodDeclaration n) {
292 | return n.getTypeAsString().endsWith("Client");
293 | }
294 |
295 | private boolean isPassThroughMethod(MethodDeclaration n) {
296 | return n.isPublic() && !n.isAnnotationPresent("Deprecated") && n.getNameAsString().equals("close");
297 | }
298 | }
299 |
--------------------------------------------------------------------------------