Skip to content

Commit

Permalink
Add sample to create the client via dynamic proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
Hadi Eskandari committed Feb 15, 2024
1 parent 61f51a7 commit 1c6d1b5
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 4 deletions.
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);
}
}
}

0 comments on commit 1c6d1b5

Please sign in to comment.