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

Add sample to create the client via dynamic proxy #847

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This section is for maintaining a changelog for all breaking changes for the cli
- Document HTTP/2 support ([#330](https://github.com/opensearch-project/opensearch-java/pull/330))
- Expose HTTP status code through `ResponseException#status` ([#756](https://github.com/opensearch-project/opensearch-java/pull/756))
- Added missing WrapperQuery accessors and builder methods ([#806](https://github.com/opensearch-project/opensearch-java/pull/806))

- Added a sample for creating OpenSearchClient via dynamic proxy ([#847](https://github.com/opensearch-project/opensearch-java/pull/847))

### Dependencies

Expand Down
1 change: 1 addition & 0 deletions samples/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ dependencies {
implementation("org.apache.logging.log4j", "log4j-slf4j2-impl","[2.17.1,3.0)")
implementation("commons-logging", "commons-logging", "1.2")
implementation("com.fasterxml.jackson.core", "jackson-databind", "2.15.2")
implementation("cglib", "cglib", "3.3.0")
}

spotless {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.client.samples;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.opensearch.client.opensearch.OpenSearchClient;
import org.opensearch.client.transport.OpenSearchTransport;

public class OpenSearchClientProxy implements MethodInterceptor {

private static final Logger LOGGER = LogManager.getLogger(OpenSearchClientProxy.class);

public static OpenSearchClient create(OpenSearchTransport transport) throws Exception {
if (transport == null) {
throw new Exception("Cannot build OpenSearchClient without a transport.");
}

LOGGER.info("Using {} transport", transport.getClass().getName());

final var interceptor = new OpenSearchClientProxy();
final var enhancer = new Enhancer();

enhancer.setSuperclass(OpenSearchClient.class);
enhancer.setCallback(interceptor);

final var argTypes = new Class[] { OpenSearchTransport.class };
final var args = new Object[] { transport };
return (OpenSearchClient) enhancer.create(argTypes, args);
}

@Override
public Object intercept(final Object obj, final Method method, final Object[] args, final MethodProxy proxy) throws Throwable {
LOGGER.info("Invoking method: {}", method.getName());
final Object result;

try {
LOGGER.info("Entering method: {}", method.getName());
result = proxy.invokeSuper(obj, args);
} catch (final InvocationTargetException e) {
throw e.getTargetException();
} finally {
LOGGER.info("Exiting method: {}", method.getName());
}
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@
import org.apache.hc.core5.ssl.SSLContextBuilder;
import org.opensearch.client.json.jackson.JacksonJsonpMapper;
import org.opensearch.client.opensearch.OpenSearchClient;
import org.opensearch.client.transport.OpenSearchTransport;
import org.opensearch.client.transport.httpclient5.ApacheHttpClient5TransportBuilder;

public class SampleClient {
public static OpenSearchClient create() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {

public static OpenSearchTransport createTransport() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
var env = System.getenv();
var https = Boolean.parseBoolean(env.getOrDefault("HTTPS", "true"));
var hostname = env.getOrDefault("HOST", "localhost");
Expand All @@ -36,7 +38,7 @@ public static OpenSearchClient create() throws NoSuchAlgorithmException, KeyStor

final var sslContext = SSLContextBuilder.create().loadTrustMaterial(null, (chains, authType) -> true).build();

final var transport = ApacheHttpClient5TransportBuilder.builder(hosts)
return ApacheHttpClient5TransportBuilder.builder(hosts)
.setMapper(new JacksonJsonpMapper())
.setHttpClientConfigCallback(httpClientBuilder -> {
final var credentialsProvider = new BasicCredentialsProvider();
Expand All @@ -55,6 +57,9 @@ public static OpenSearchClient create() throws NoSuchAlgorithmException, KeyStor
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider).setConnectionManager(connectionManager);
})
.build();
return new OpenSearchClient(transport);
}

public static OpenSearchClient create() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
return new OpenSearchClient(createTransport());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.opensearch.client.samples;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.opensearch.client.opensearch._types.mapping.IntegerNumberProperty;
import org.opensearch.client.opensearch._types.mapping.Property;
import org.opensearch.client.opensearch._types.mapping.TypeMapping;
import org.opensearch.client.opensearch.core.IndexRequest;
import org.opensearch.client.opensearch.core.SearchResponse;
import org.opensearch.client.opensearch.indices.CreateIndexRequest;
import org.opensearch.client.opensearch.indices.DeleteIndexRequest;
import org.opensearch.client.opensearch.indices.IndexSettings;
import org.opensearch.client.samples.util.IndexData;

/**
* Run with: <c>./gradlew :samples:run -Dsamples.mainClass=SampleProxyClient</c>
*/
public class SampleProxyClient {

private static final Logger LOGGER = LogManager.getLogger(SampleProxyClient.class);

public static void main(String[] args) {
try {
var transport = SampleClient.createTransport();
var client = OpenSearchClientProxy.create(transport);

final var indexName = "my-index";

if (!client.indices().exists(r -> r.index(indexName)).value()) {
LOGGER.info("Creating index {}", indexName);
IndexSettings settings = new IndexSettings.Builder().numberOfShards("2").numberOfReplicas("1").build();
TypeMapping mapping = new TypeMapping.Builder().properties(
"age",
new Property.Builder().integer(new IntegerNumberProperty.Builder().build()).build()
).build();
CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index(indexName)
.settings(settings)
.mappings(mapping)
.build();
client.indices().create(createIndexRequest);
}

LOGGER.info("Indexing documents");
IndexData indexData = new IndexData("Document 1", "Text for document 1");
IndexRequest<IndexData> indexRequest = new IndexRequest.Builder<IndexData>().index(indexName)
.id("1")
.document(indexData)
.build();
client.index(indexRequest);

indexData = new IndexData("Document 2", "Text for document 2");
indexRequest = new IndexRequest.Builder<IndexData>().index(indexName).id("2").document(indexData).build();
client.index(indexRequest);

// wait for the document to index
Thread.sleep(3000);

SearchResponse<IndexData> searchResponse = client.search(s -> s.index(indexName), IndexData.class);
for (var hit : searchResponse.hits().hits()) {
LOGGER.info("Found {} with score {}", hit.source(), hit.score());
}

LOGGER.info("Deleting document with id 1");
client.delete(d -> d.index(indexName).id("1"));

LOGGER.info("Deleting index {}", indexName);
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest.Builder().index(indexName).build();
client.indices().delete(deleteIndexRequest);
} catch (Exception e) {
LOGGER.error("Unexpected exception", e);
}
}
}
Loading