Skip to content

Commit a64eefe

Browse files
joshuali925goyamegh
andcommitted
Add direct-query-core module for prometheus integration
Co-authored-by: Megha Goyal <[email protected]> Signed-off-by: Joshua Li <[email protected]>
1 parent d22680b commit a64eefe

File tree

52 files changed

+4197
-486
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+4197
-486
lines changed

async-query-core/src/main/java/org/opensearch/sql/spark/rest/model/LangType.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
/** Language type accepted in async query apis. */
99
public enum LangType {
1010
SQL("sql"),
11-
PPL("ppl");
11+
PPL("ppl"),
12+
PROMQL("promql");
1213
private final String text;
1314

1415
LangType(String text) {

direct-query-core/build.gradle

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
plugins {
7+
id 'java-library'
8+
id "io.freefair.lombok"
9+
id 'jacoco'
10+
id 'java-test-fixtures'
11+
}
12+
13+
repositories {
14+
mavenCentral()
15+
}
16+
17+
dependencies {
18+
api project(':core')
19+
implementation project(':datasources')
20+
implementation project(':async-query-core')
21+
22+
// Common dependencies
23+
implementation group: 'org.opensearch', name: 'opensearch', version: "${opensearch_version}"
24+
implementation group: 'org.json', name: 'json', version: '20231013'
25+
implementation group: 'commons-io', name: 'commons-io', version: "${commons_io_version}"
26+
27+
// Test dependencies
28+
testImplementation(platform("org.junit:junit-bom:5.9.3"))
29+
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.3'
30+
testImplementation group: 'org.mockito', name: 'mockito-core', version: "${mockito_version}"
31+
testImplementation group: 'org.mockito', name: 'mockito-junit-jupiter', version: "${mockito_version}"
32+
testImplementation group: 'com.squareup.okhttp3', name: 'mockwebserver', version: '4.12.0'
33+
34+
testCompileOnly('junit:junit:4.13.1') {
35+
exclude group: 'org.hamcrest', module: 'hamcrest-core'
36+
}
37+
testRuntimeOnly("org.junit.vintage:junit-vintage-engine") {
38+
exclude group: 'org.hamcrest', module: 'hamcrest-core'
39+
}
40+
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") {
41+
exclude group: 'org.hamcrest', module: 'hamcrest-core'
42+
}
43+
testImplementation("org.opensearch.test:framework:${opensearch_version}")
44+
}
45+
46+
test {
47+
useJUnitPlatform()
48+
testLogging {
49+
events "failed"
50+
exceptionFormat "full"
51+
}
52+
}
53+
task junit4(type: Test) {
54+
useJUnitPlatform {
55+
includeEngines("junit-vintage")
56+
}
57+
systemProperty 'tests.security.manager', 'false'
58+
testLogging {
59+
events "failed"
60+
exceptionFormat "full"
61+
}
62+
}
63+
64+
jacocoTestReport {
65+
dependsOn test, junit4
66+
executionData test, junit4
67+
reports {
68+
html.required = true
69+
xml.required = true
70+
}
71+
afterEvaluate {
72+
classDirectories.setFrom(files(classDirectories.files.collect {
73+
fileTree(dir: it)
74+
}))
75+
}
76+
}
77+
78+
jacocoTestCoverageVerification {
79+
dependsOn test, junit4
80+
executionData test, junit4
81+
violationRules {
82+
rule {
83+
element = 'CLASS'
84+
excludes = [
85+
'org.opensearch.sql.prometheus.model.*',
86+
'org.opensearch.sql.directquery.rest.model.*'
87+
]
88+
limit {
89+
counter = 'LINE'
90+
minimum = 1.0
91+
}
92+
limit {
93+
counter = 'BRANCH'
94+
minimum = 1.0
95+
}
96+
}
97+
}
98+
afterEvaluate {
99+
classDirectories.setFrom(files(classDirectories.files.collect {
100+
fileTree(dir: it)
101+
}))
102+
}
103+
}
104+
check.dependsOn jacocoTestCoverageVerification
105+
jacocoTestCoverageVerification.dependsOn jacocoTestReport
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.opensearch.sql.datasource.client;
7+
8+
/**
9+
* Base interface for all data source clients. This interface serves as a marker interface for all
10+
* client implementations.
11+
*/
12+
public interface DataSourceClient {}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.opensearch.sql.datasource.client;
7+
8+
import org.apache.logging.log4j.LogManager;
9+
import org.apache.logging.log4j.Logger;
10+
import org.opensearch.common.inject.Inject;
11+
import org.opensearch.sql.common.setting.Settings;
12+
import org.opensearch.sql.datasource.DataSourceService;
13+
import org.opensearch.sql.datasource.client.exceptions.DataSourceClientException;
14+
import org.opensearch.sql.datasource.model.DataSourceMetadata;
15+
import org.opensearch.sql.datasource.model.DataSourceType;
16+
import org.opensearch.sql.prometheus.utils.PrometheusClientUtils;
17+
18+
/** Factory for creating data source clients based on the data source type. */
19+
public class DataSourceClientFactory {
20+
21+
private static final Logger LOG = LogManager.getLogger();
22+
23+
private final Settings settings;
24+
private final DataSourceService dataSourceService;
25+
26+
@Inject
27+
public DataSourceClientFactory(DataSourceService dataSourceService, Settings settings) {
28+
this.settings = settings;
29+
this.dataSourceService = dataSourceService;
30+
}
31+
32+
/**
33+
* Creates a client for the specified data source with appropriate type.
34+
*
35+
* @param <T> The type of client to create, must implement DataSourceClient
36+
* @param dataSourceName The name of the data source
37+
* @return The appropriate client for the data source type
38+
* @throws DataSourceClientException If client creation fails
39+
*/
40+
@SuppressWarnings("unchecked")
41+
public <T extends DataSourceClient> T createClient(String dataSourceName)
42+
throws DataSourceClientException {
43+
try {
44+
if (!dataSourceService.dataSourceExists(dataSourceName)) {
45+
throw new DataSourceClientException("Data source does not exist: " + dataSourceName);
46+
}
47+
48+
DataSourceMetadata metadata =
49+
dataSourceService.verifyDataSourceAccessAndGetRawMetadata(dataSourceName, null);
50+
DataSourceType dataSourceType = metadata.getConnector();
51+
52+
return (T) createClientForType(dataSourceType.name(), metadata);
53+
} catch (Exception e) {
54+
if (e instanceof DataSourceClientException) {
55+
throw e;
56+
}
57+
LOG.error("Failed to create client for data source: " + dataSourceName, e);
58+
throw new DataSourceClientException(
59+
"Failed to create client for data source: " + dataSourceName, e);
60+
}
61+
}
62+
63+
/**
64+
* Gets the data source type for a given data source name.
65+
*
66+
* @param dataSourceName The name of the data source
67+
* @return The type of the data source
68+
* @throws DataSourceClientException If the data source doesn't exist
69+
*/
70+
public DataSourceType getDataSourceType(String dataSourceName) throws DataSourceClientException {
71+
if (!dataSourceService.dataSourceExists(dataSourceName)) {
72+
throw new DataSourceClientException("Data source does not exist: " + dataSourceName);
73+
}
74+
75+
return dataSourceService.getDataSourceMetadata(dataSourceName).getConnector();
76+
}
77+
78+
private DataSourceClient createClientForType(String dataSourceType, DataSourceMetadata metadata)
79+
throws DataSourceClientException {
80+
switch (dataSourceType) {
81+
case "PROMETHEUS":
82+
return PrometheusClientUtils.createPrometheusClient(metadata, settings);
83+
default:
84+
throw new DataSourceClientException("Unsupported data source type: " + dataSourceType);
85+
}
86+
}
87+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.opensearch.sql.datasource.client.exceptions;
7+
8+
/** Exception thrown when there are issues with data source client operations. */
9+
public class DataSourceClientException extends RuntimeException {
10+
11+
public DataSourceClientException(String message) {
12+
super(message);
13+
}
14+
15+
public DataSourceClientException(String message, Throwable cause) {
16+
super(message, cause);
17+
}
18+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.opensearch.sql.datasource.query;
7+
8+
import java.io.IOException;
9+
import org.opensearch.sql.datasource.client.DataSourceClient;
10+
import org.opensearch.sql.datasource.model.DataSourceType;
11+
import org.opensearch.sql.directquery.rest.model.ExecuteDirectQueryRequest;
12+
import org.opensearch.sql.directquery.rest.model.GetDirectQueryResourcesRequest;
13+
import org.opensearch.sql.directquery.rest.model.GetDirectQueryResourcesResponse;
14+
15+
/**
16+
* Interface for handling queries for specific data source types.
17+
*
18+
* @param <T> The client type this handler works with, extending DataSourceClient
19+
*/
20+
public interface QueryHandler<T extends DataSourceClient> {
21+
22+
/**
23+
* Returns the data source type this handler supports.
24+
*
25+
* @return The supported data source type
26+
*/
27+
DataSourceType getSupportedDataSourceType();
28+
29+
/**
30+
* Executes a query for the supported data source type.
31+
*
32+
* @param client The client instance to use
33+
* @param request The query request
34+
* @return JSON string result of the query
35+
* @throws IOException If query execution fails
36+
*/
37+
String executeQuery(T client, ExecuteDirectQueryRequest request) throws IOException;
38+
39+
/**
40+
* Gets resources from the data source.
41+
*
42+
* @param client The client instance to use
43+
* @param request The resources request
44+
* @return Response containing the requested resources
45+
* @throws IOException If resource retrieval fails
46+
*/
47+
GetDirectQueryResourcesResponse<?> getResources(T client, GetDirectQueryResourcesRequest request)
48+
throws IOException;
49+
50+
/**
51+
* Checks if this handler can handle the given client type.
52+
*
53+
* @param client The client to check
54+
* @return true if this handler can handle the client
55+
*/
56+
boolean canHandle(DataSourceClient client);
57+
58+
/**
59+
* Gets the client class this handler supports.
60+
*
61+
* @return The class of client this handler supports
62+
*/
63+
Class<T> getClientClass();
64+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.opensearch.sql.datasource.query;
7+
8+
import java.util.List;
9+
import java.util.Optional;
10+
import org.opensearch.common.inject.Inject;
11+
import org.opensearch.sql.datasource.client.DataSourceClient;
12+
13+
/** Registry for all query handlers. */
14+
public class QueryHandlerRegistry {
15+
16+
private final List<QueryHandler<?>> handlers;
17+
18+
@Inject
19+
public QueryHandlerRegistry(List<QueryHandler<?>> handlers) {
20+
this.handlers = handlers;
21+
}
22+
23+
/**
24+
* Finds a handler that can process the given client.
25+
*
26+
* @param client The client to find a handler for
27+
* @param <T> The type of client, extending DataSourceClient
28+
* @return An optional containing the handler if found
29+
*/
30+
@SuppressWarnings("unchecked")
31+
public <T extends DataSourceClient> Optional<QueryHandler<T>> getQueryHandler(T client) {
32+
return handlers.stream()
33+
.filter(
34+
handler -> {
35+
try {
36+
// Get the handler's client class and check if it's compatible with our client
37+
Class<?> handlerClientClass = handler.getClientClass();
38+
return handlerClientClass.isInstance(client)
39+
&& ((QueryHandler<T>) handler).canHandle(client);
40+
} catch (ClassCastException e) {
41+
return false;
42+
}
43+
})
44+
.map(handler -> (QueryHandler<T>) handler)
45+
.findFirst();
46+
}
47+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.opensearch.sql.directquery;
7+
8+
import org.opensearch.sql.directquery.rest.model.ExecuteDirectQueryRequest;
9+
import org.opensearch.sql.directquery.rest.model.ExecuteDirectQueryResponse;
10+
import org.opensearch.sql.directquery.rest.model.GetDirectQueryResourcesRequest;
11+
import org.opensearch.sql.directquery.rest.model.GetDirectQueryResourcesResponse;
12+
13+
public interface DirectQueryExecutorService {
14+
15+
/**
16+
* Execute a direct query request.
17+
*
18+
* @param request The direct query request
19+
* @return A response containing the result
20+
*/
21+
ExecuteDirectQueryResponse executeDirectQuery(ExecuteDirectQueryRequest request);
22+
23+
/**
24+
* Get resources from a data source.
25+
*
26+
* @param request The resources request
27+
* @return A response containing the requested resources
28+
*/
29+
GetDirectQueryResourcesResponse<?> getDirectQueryResources(
30+
GetDirectQueryResourcesRequest request);
31+
}

0 commit comments

Comments
 (0)