Skip to content

Commit 7e806e5

Browse files
feature: added getDocuments base logic to obtain already inserted documents
1 parent 8f5bfc4 commit 7e806e5

File tree

8 files changed

+187
-10
lines changed

8 files changed

+187
-10
lines changed

client-java/controller/src/main/java/org/evomaster/client/java/controller/SutHandler.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ default void extractRPCSchema(){}
179179

180180
default Object getMongoConnection() {return null;}
181181

182+
default Object getOpenSearchConnection() {return null;}
182183

183184
/**
184185
* <p>

client-java/controller/src/main/java/org/evomaster/client/java/controller/internal/EMController.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ public Response runSut(SutRunDto dto, @Context HttpServletRequest httpServletReq
387387
noKillSwitch(() -> sutController.initSqlHandler());
388388
noKillSwitch(() -> sutController.registerOrExecuteInitSqlCommandsIfNeeded(true));
389389
noKillSwitch(() -> sutController.initMongoHandler());
390+
noKillSwitch(() -> sutController.initOpenSearchHandler());
390391
} else {
391392
//TODO as starting should be blocking, need to check
392393
//if initialized, and wait if not

client-java/controller/src/main/java/org/evomaster/client/java/controller/internal/SutController.java

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import org.evomaster.client.java.controller.api.dto.problem.RPCProblemDto;
2828
import org.evomaster.client.java.controller.api.dto.problem.rpc.*;
2929
import org.evomaster.client.java.controller.api.dto.problem.rpc.RPCTestDto;
30+
import org.evomaster.client.java.controller.internal.db.OpenSearchHandler;
31+
import org.evomaster.client.java.instrumentation.OpenSearchCommand;
3032
import org.evomaster.client.java.sql.DbCleaner;
3133
import org.evomaster.client.java.sql.SqlScriptRunner;
3234
import org.evomaster.client.java.sql.SqlScriptRunnerCached;
@@ -86,6 +88,8 @@ public abstract class SutController implements SutHandler, CustomizationHandler
8688

8789
private final MongoHandler mongoHandler = new MongoHandler();
8890

91+
private final OpenSearchHandler openSearchHandler = new OpenSearchHandler();
92+
8993
private Server controllerServer;
9094

9195
/**
@@ -323,6 +327,17 @@ public final void initMongoHandler() {
323327
}
324328
}
325329

330+
public final void initOpenSearchHandler() {
331+
// This is needed because the replacement use to get this info occurs during the start of the SUT.
332+
Object connection = getOpenSearchConnection();
333+
openSearchHandler.setOpenSearchClient(connection);
334+
335+
List<AdditionalInfo> list = getAdditionalInfoList();
336+
if (!list.isEmpty()) {
337+
AdditionalInfo last = list.get(list.size() - 1);
338+
last.getOpenSearchInfoData().forEach(openSearchHandler::handle);
339+
}
340+
}
326341

327342
/**
328343
* TODO further handle multiple connections
@@ -366,7 +381,7 @@ public final ExtraHeuristicsDto computeExtraHeuristics(boolean queryFromDatabase
366381

367382
ExtraHeuristicsDto dto = new ExtraHeuristicsDto();
368383

369-
if (isSQLHeuristicsComputationAllowed() || isMongoHeuristicsComputationAllowed()) {
384+
if (isSQLHeuristicsComputationAllowed() || isMongoHeuristicsComputationAllowed() || isOpenSearchHeuristicsComputationAllowed()) {
370385
List<AdditionalInfo> additionalInfoList = getAdditionalInfoList();
371386

372387
if (isSQLHeuristicsComputationAllowed()) {
@@ -375,6 +390,10 @@ public final ExtraHeuristicsDto computeExtraHeuristics(boolean queryFromDatabase
375390
if (isMongoHeuristicsComputationAllowed()) {
376391
computeMongoHeuristics(dto, additionalInfoList);
377392
}
393+
394+
if (isOpenSearchHeuristicsComputationAllowed()) {
395+
computeOpenSearchHeuristics(dto, additionalInfoList);
396+
}
378397
}
379398
return dto;
380399
}
@@ -387,6 +406,11 @@ private boolean isMongoHeuristicsComputationAllowed() {
387406
return mongoHandler.isCalculateHeuristics() || mongoHandler.isExtractMongoExecution();
388407
}
389408

409+
private boolean isOpenSearchHeuristicsComputationAllowed() {
410+
return openSearchHandler.isCalculateHeuristics();
411+
// return openSearchHandler.isCalculateHeuristics() || openSearchHandler.isExtractMongoExecution();
412+
}
413+
390414
private void computeSQLHeuristics(ExtraHeuristicsDto dto, List<AdditionalInfo> additionalInfoList, boolean queryFromDatabase) {
391415
/*
392416
TODO refactor, once we move SQL analysis into Core
@@ -467,6 +491,24 @@ public final void computeMongoHeuristics(ExtraHeuristicsDto dto, List<Additional
467491
}
468492
}
469493

494+
public final void computeOpenSearchHeuristics(ExtraHeuristicsDto dto, List<AdditionalInfo> additionalInfoList) {
495+
if (openSearchHandler.isCalculateHeuristics()) {
496+
if (!additionalInfoList.isEmpty()) {
497+
AdditionalInfo last = additionalInfoList.get(additionalInfoList.size() - 1);
498+
last.getOpenSearchInfoData().forEach(it -> {
499+
try {
500+
openSearchHandler.handle(it);
501+
} catch (Exception e){
502+
SimpleLogger.error("FAILED TO HANDLE OPENSEARCH COMMAND");
503+
assert false;
504+
}
505+
});
506+
}
507+
508+
List<Integer> oscd = openSearchHandler.getEvaluatedOpenSearchCommands();
509+
}
510+
511+
}
470512

471513
/**
472514
* handle specified init sql script after SUT is started.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package org.evomaster.client.java.controller.internal.db;
2+
3+
import java.lang.reflect.Method;
4+
import java.util.ArrayList;
5+
import java.util.List;
6+
import java.util.Map;
7+
import org.evomaster.client.java.instrumentation.MongoFindCommand;
8+
import org.evomaster.client.java.instrumentation.OpenSearchCommand;
9+
10+
public class OpenSearchHandler {
11+
12+
public static final String OPENSEARCH_CLIENT_CLASS_NAME = "org.opensearch.client.opensearch.OpenSearchClient";
13+
public static final String OPENSEARCH_CLIENT_INDEX_METHOD_NAME = "index";
14+
public static final String OPENSEARCH_CLIENT_SIZE_METHOD_NAME = "size";
15+
public static final String OPENSEARCH_CLIENT_BUILD_METHOD_NAME = "build";
16+
public static final String OPENSEARCH_CLIENT_SEARCH_METHOD_NAME = "search";
17+
public static final String OPENSEARCH_CLIENT_HITS_METHOD_NAME = "hits";
18+
19+
public static final String OPENSEARCH_CLIENT_SEARCH_REQUEST_CLASS_NAME = "org.opensearch.client.opensearch.core.SearchRequest";
20+
public static final String OPENSEARCH_CLIENT_SEARCH_REQUEST_BUILDER_CLASS_NAME = "org.opensearch.client.opensearch.core.SearchRequest$Builder";
21+
22+
private final List<OpenSearchCommand> commands;
23+
24+
private final boolean calculateHeuristics;
25+
26+
private Object openSearchClient = null;
27+
28+
public OpenSearchHandler() {
29+
this.commands = new ArrayList<>();;
30+
this.calculateHeuristics = true;
31+
}
32+
33+
public boolean isCalculateHeuristics() {
34+
return calculateHeuristics;
35+
}
36+
37+
public void handle(OpenSearchCommand command) {
38+
commands.add(command);
39+
}
40+
41+
public List<Integer> getEvaluatedOpenSearchCommands() {
42+
List<Integer> r = new ArrayList<>();
43+
44+
commands.stream()
45+
.filter(command -> command.getQuery() != null)
46+
.forEach(openSearchCommand -> {
47+
Integer distance = computeCommandDistance(openSearchCommand);
48+
r.add(distance);
49+
});
50+
51+
commands.clear();
52+
53+
return r;
54+
}
55+
56+
private Integer computeCommandDistance(OpenSearchCommand command) {
57+
List<String> indexName = command.getIndex();
58+
String methodName = command.getMethod();
59+
60+
Object documents = getDocuments(indexName);
61+
62+
return command.getQuery().toString().length();
63+
}
64+
65+
private Object getDocuments(List<String> indexNames) {
66+
try {
67+
// Get the OpenSearchClient class
68+
Class<?> openSearchClientClass = openSearchClient.getClass();
69+
70+
// Get SearchRequest.Builder class
71+
Class<?> searchRequestBuilderClass = Class.forName(OPENSEARCH_CLIENT_SEARCH_REQUEST_BUILDER_CLASS_NAME);
72+
Object searchRequestBuilder = searchRequestBuilderClass.getDeclaredConstructor().newInstance();
73+
74+
// Set the index/indices on the builder
75+
Method indexMethod = searchRequestBuilderClass.getMethod(OPENSEARCH_CLIENT_INDEX_METHOD_NAME, List.class);
76+
indexMethod.invoke(searchRequestBuilder, indexNames);
77+
78+
// Set a large size to get all documents (could use scroll for large datasets)
79+
Method sizeMethod = searchRequestBuilderClass.getMethod(OPENSEARCH_CLIENT_SIZE_METHOD_NAME, Integer.class);
80+
sizeMethod.invoke(searchRequestBuilder, 10000); // Max 10k documents
81+
82+
// Build the SearchRequest
83+
Method buildMethod = searchRequestBuilderClass.getMethod(OPENSEARCH_CLIENT_BUILD_METHOD_NAME);
84+
Object searchRequest = buildMethod.invoke(searchRequestBuilder);
85+
86+
// Execute the search: openSearchClient.search(searchRequest, Object.class)
87+
Method searchMethod = openSearchClientClass.getMethod(OPENSEARCH_CLIENT_SEARCH_METHOD_NAME,
88+
Class.forName(OPENSEARCH_CLIENT_SEARCH_REQUEST_CLASS_NAME),
89+
Class.class);
90+
Object searchResponse = searchMethod.invoke(openSearchClient, searchRequest, Object.class);
91+
92+
Method hitsMethod = searchResponse.getClass().getMethod(OPENSEARCH_CLIENT_HITS_METHOD_NAME);
93+
Object hitsContainer = hitsMethod.invoke(searchResponse);
94+
95+
Method hitsListMethod = hitsContainer.getClass().getMethod(OPENSEARCH_CLIENT_HITS_METHOD_NAME);
96+
Object hitsList = hitsListMethod.invoke(hitsContainer);
97+
98+
return hitsList; // Returns List<Hit<Object>>
99+
100+
} catch (Exception e) {
101+
throw new RuntimeException("Failed to retrieve documents from OpenSearch indices: " + indexNames, e);
102+
}
103+
}
104+
105+
private Object getDocuments() {
106+
// Default implementation - this method should be called with specific index names
107+
return null;
108+
}
109+
110+
public void setOpenSearchClient(Object openSearchClient) {
111+
this.openSearchClient = openSearchClient;
112+
}
113+
}

client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/OpenSearchCommand.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package org.evomaster.client.java.instrumentation;
22

33
import java.io.Serializable;
4+
import java.util.List;
45

56
public class OpenSearchCommand implements Serializable {
67
/**
78
* Name of the index that the operation was applied to
89
*/
9-
private final Object index;
10+
private final List<String> index;
1011

1112
/**
1213
* Name of the operation that was executed
@@ -23,7 +24,7 @@ public class OpenSearchCommand implements Serializable {
2324
*/
2425
private final long executionTime;
2526

26-
public OpenSearchCommand(Object index, String method, Object query, long executionTime) {
27+
public OpenSearchCommand(List<String> index, String method, Object query, long executionTime) {
2728
this.index = index;
2829
this.method = method;
2930
this.query = query;
@@ -38,7 +39,7 @@ public Object getQuery() {
3839
return query;
3940
}
4041

41-
public Object getIndex() {
42+
public List<String> getIndex() {
4243
return index;
4344
}
4445

client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/thirdpartyclasses/OpenSearchClientClassReplacement.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.lang.reflect.InvocationTargetException;
44
import java.lang.reflect.Method;
55
import java.util.Arrays;
6+
import java.util.Collections;
67
import java.util.List;
78
import org.evomaster.client.java.instrumentation.OpenSearchCommand;
89
import org.evomaster.client.java.instrumentation.coverage.methodreplacement.Replacement;
@@ -75,9 +76,21 @@ private static void addOpenSearchInfo(String method, Object query, long executio
7576
ExecutionTracer.addOpenSearchInfo(info);
7677
}
7778

78-
private static Object getIndex(Object query) {
79+
private static List<String> getIndex(Object query) {
7980
try {
80-
return query.getClass().getMethod(INDEX_METHOD).invoke(query);
81+
Object result = query.getClass().getMethod(INDEX_METHOD).invoke(query);
82+
if (result == null) {
83+
return null;
84+
}
85+
86+
if (result instanceof List) {
87+
List<String> indexList = (List<String>) result;
88+
return indexList;
89+
} else if (result instanceof String) {
90+
return Collections.singletonList((String) result);
91+
} else {
92+
return Collections.singletonList(result.toString());
93+
}
8194
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
8295
return null;
8396
}

e2e-tests/spring-rest-opensearch/src/main/java/com/opensearch/config/OpenSearchRepository.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.util.List;
44
import org.opensearch.client.opensearch.OpenSearchClient;
5+
import org.opensearch.client.opensearch._types.query_dsl.Query;
56
import org.opensearch.client.opensearch.core.GetRequest;
67
import org.opensearch.client.opensearch.core.GetResponse;
78
import org.opensearch.client.opensearch.core.SearchRequest;
@@ -34,6 +35,11 @@ public <T> List<T> search(String q, Class<T> clazz) throws IOException {
3435
SearchRequest searchRequest = new SearchRequest.Builder()
3536
.index(openSearchProperties.getIndexName())
3637
.q(wrapIntoDoubleQuotes(q))
38+
// query example which matches 2 random field names with query string random
39+
.query(
40+
query -> query
41+
.match(matcher -> matcher.field("title").query(value -> value.stringValue(q)))
42+
)
3743
.build();
3844

3945
SearchResponse<T> response = openSearchClient.search(searchRequest, clazz);

e2e-tests/spring-rest-opensearch/src/test/java/com/foo/spring/rest/opensearch/OpenSearchController.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ protected int getSutPort() {
112112
.get("local.server.port");
113113
}
114114

115-
// @Override
116-
// public OpenSearchClient getOpenSearchConnection() {
117-
// return openSearchClient;
118-
// }
115+
@Override
116+
public OpenSearchClient getOpenSearchConnection() {
117+
return openSearchClient;
118+
}
119119
}

0 commit comments

Comments
 (0)