Skip to content

Commit 9932077

Browse files
committed
Create datasource API (#1458)
Signed-off-by: vamsi-amazon <reddyvam@amazon.com> (cherry picked from commit 12bc2b4)
1 parent 11d0d6d commit 9932077

File tree

51 files changed

+1879
-379
lines changed

Some content is hidden

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

51 files changed

+1879
-379
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,5 @@ gen
4646
/.prom.pid.lock
4747

4848
.java-version
49-
.worktrees
49+
.worktrees
50+
http-client.env.json

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ buildscript {
1212
version_tokens = opensearch_version.tokenize('-')
1313
opensearch_build = version_tokens[0] + '.0'
1414
prometheus_binary_version = "2.37.2"
15+
common_utils_version = System.getProperty("common_utils.version", opensearch_build)
1516
if (buildVersionQualifier) {
1617
opensearch_build += "-${buildVersionQualifier}"
1718
}

common/build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ dependencies {
3535
api "org.antlr:antlr4-runtime:4.7.1"
3636
api group: 'com.google.guava', name: 'guava', version: '31.0.1-jre'
3737
api group: 'org.apache.logging.log4j', name: 'log4j-core', version:'2.17.1'
38-
api group: 'org.apache.commons', name: 'commons-lang3', version: '3.10'
38+
api group: 'org.apache.commons', name: 'commons-lang3', version: '3.12.0'
39+
api 'com.amazonaws:aws-encryption-sdk-java:2.4.0'
3940

4041
testImplementation group: 'junit', name: 'junit', version: '4.13.2'
4142
testImplementation group: 'org.assertj', name: 'assertj-core', version: '3.9.1'
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
*
3+
* * Copyright OpenSearch Contributors
4+
* * SPDX-License-Identifier: Apache-2.0
5+
*
6+
*/
7+
8+
package org.opensearch.sql.common.encryptor;
9+
10+
public interface Encryptor {
11+
12+
/**
13+
* Takes plaintext and returns encrypted text.
14+
*
15+
* @param plainText plainText.
16+
* @return String encryptedText.
17+
*/
18+
String encrypt(String plainText);
19+
20+
/**
21+
* Takes encryptedText and returns plain text.
22+
*
23+
* @param encryptedText encryptedText.
24+
* @return String plainText.
25+
*/
26+
String decrypt(String encryptedText);
27+
28+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
*
3+
* * Copyright OpenSearch Contributors
4+
* * SPDX-License-Identifier: Apache-2.0
5+
*
6+
*/
7+
8+
package org.opensearch.sql.common.encryptor;
9+
10+
import com.amazonaws.encryptionsdk.AwsCrypto;
11+
import com.amazonaws.encryptionsdk.CommitmentPolicy;
12+
import com.amazonaws.encryptionsdk.CryptoResult;
13+
import com.amazonaws.encryptionsdk.jce.JceMasterKey;
14+
import java.nio.charset.StandardCharsets;
15+
import java.util.Base64;
16+
import javax.crypto.spec.SecretKeySpec;
17+
import lombok.RequiredArgsConstructor;
18+
19+
@RequiredArgsConstructor
20+
public class EncryptorImpl implements Encryptor {
21+
22+
private final String masterKey;
23+
24+
@Override
25+
public String encrypt(String plainText) {
26+
27+
final AwsCrypto crypto = AwsCrypto.builder()
28+
.withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt)
29+
.build();
30+
31+
JceMasterKey jceMasterKey
32+
= JceMasterKey.getInstance(new SecretKeySpec(masterKey.getBytes(), "AES"), "Custom", "",
33+
"AES/GCM/NoPadding");
34+
35+
final CryptoResult<byte[], JceMasterKey> encryptResult = crypto.encryptData(jceMasterKey,
36+
plainText.getBytes(StandardCharsets.UTF_8));
37+
return Base64.getEncoder().encodeToString(encryptResult.getResult());
38+
}
39+
40+
@Override
41+
public String decrypt(String encryptedText) {
42+
final AwsCrypto crypto = AwsCrypto.builder()
43+
.withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt)
44+
.build();
45+
46+
JceMasterKey jceMasterKey
47+
= JceMasterKey.getInstance(new SecretKeySpec(masterKey.getBytes(), "AES"), "Custom", "",
48+
"AES/GCM/NoPadding");
49+
50+
final CryptoResult<byte[], JceMasterKey> decryptedResult
51+
= crypto.decryptData(jceMasterKey, Base64.getDecoder().decode(encryptedText));
52+
return new String(decryptedResult.getResult());
53+
}
54+
55+
}

core/build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,13 @@ repositories {
3535

3636
dependencies {
3737
api group: 'com.google.guava', name: 'guava', version: '31.0.1-jre'
38-
api group: 'org.apache.commons', name: 'commons-lang3', version: '3.10'
38+
api group: 'org.apache.commons', name: 'commons-lang3', version: '3.12.0'
3939
api group: 'com.facebook.presto', name: 'presto-matching', version: '0.240'
4040
api group: 'org.apache.commons', name: 'commons-math3', version: '3.6.1'
4141
api "com.fasterxml.jackson.core:jackson-core:${versions.jackson}"
4242
api "com.fasterxml.jackson.core:jackson-databind:${versions.jackson_databind}"
4343
api "com.fasterxml.jackson.core:jackson-annotations:${versions.jackson}"
44+
api group: 'com.google.code.gson', name: 'gson', version: '2.8.9'
4445
api project(':common')
4546

4647
testImplementation('org.junit.jupiter:junit-jupiter:5.6.2')

core/src/main/java/org/opensearch/sql/analysis/Analyzer.java

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import java.util.List;
2626
import java.util.Objects;
2727
import java.util.Optional;
28-
import java.util.Set;
2928
import java.util.stream.Collectors;
3029
import org.apache.commons.lang3.tuple.ImmutablePair;
3130
import org.apache.commons.lang3.tuple.Pair;
@@ -64,7 +63,6 @@
6463
import org.opensearch.sql.data.model.ExprMissingValue;
6564
import org.opensearch.sql.data.type.ExprCoreType;
6665
import org.opensearch.sql.datasource.DataSourceService;
67-
import org.opensearch.sql.datasource.model.DataSourceMetadata;
6866
import org.opensearch.sql.exception.SemanticCheckException;
6967
import org.opensearch.sql.expression.DSL;
7068
import org.opensearch.sql.expression.Expression;
@@ -134,13 +132,8 @@ public LogicalPlan analyze(UnresolvedPlan unresolved, AnalysisContext context) {
134132
@Override
135133
public LogicalPlan visitRelation(Relation node, AnalysisContext context) {
136134
QualifiedName qualifiedName = node.getTableQualifiedName();
137-
Set<String> allowedDataSourceNames = dataSourceService.getDataSourceMetadataSet()
138-
.stream()
139-
.map(DataSourceMetadata::getName)
140-
.collect(Collectors.toSet());
141135
DataSourceSchemaIdentifierNameResolver dataSourceSchemaIdentifierNameResolver
142-
= new DataSourceSchemaIdentifierNameResolver(qualifiedName.getParts(),
143-
allowedDataSourceNames);
136+
= new DataSourceSchemaIdentifierNameResolver(dataSourceService, qualifiedName.getParts());
144137
String tableName = dataSourceSchemaIdentifierNameResolver.getIdentifierName();
145138
context.push();
146139
TypeEnvironment curEnv = context.peek();
@@ -182,13 +175,9 @@ public LogicalPlan visitRelationSubquery(RelationSubquery node, AnalysisContext
182175
@Override
183176
public LogicalPlan visitTableFunction(TableFunction node, AnalysisContext context) {
184177
QualifiedName qualifiedName = node.getFunctionName();
185-
Set<String> allowedDataSourceNames = dataSourceService.getDataSourceMetadataSet()
186-
.stream()
187-
.map(DataSourceMetadata::getName)
188-
.collect(Collectors.toSet());
189178
DataSourceSchemaIdentifierNameResolver dataSourceSchemaIdentifierNameResolver
190-
= new DataSourceSchemaIdentifierNameResolver(qualifiedName.getParts(),
191-
allowedDataSourceNames);
179+
= new DataSourceSchemaIdentifierNameResolver(this.dataSourceService,
180+
qualifiedName.getParts());
192181

193182
FunctionName functionName
194183
= FunctionName.of(dataSourceSchemaIdentifierNameResolver.getIdentifierName());

core/src/main/java/org/opensearch/sql/analysis/DataSourceSchemaIdentifierNameResolver.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@
77

88
package org.opensearch.sql.analysis;
99

10+
import com.google.common.collect.ImmutableSet;
1011
import java.util.List;
1112
import java.util.Set;
13+
import java.util.stream.Collectors;
14+
import org.opensearch.sql.ast.expression.QualifiedName;
15+
import org.opensearch.sql.datasource.DataSourceService;
16+
import org.opensearch.sql.datasource.model.DataSourceMetadata;
1217

1318
public class DataSourceSchemaIdentifierNameResolver {
1419

@@ -19,6 +24,7 @@ public class DataSourceSchemaIdentifierNameResolver {
1924
private String dataSourceName = DEFAULT_DATASOURCE_NAME;
2025
private String schemaName = DEFAULT_SCHEMA_NAME;
2126
private String identifierName;
27+
private DataSourceService dataSourceService;
2228

2329
private static final String DOT = ".";
2430

@@ -28,13 +34,14 @@ public class DataSourceSchemaIdentifierNameResolver {
2834
* DataSourceSchemaTable name and DataSourceSchemaFunction in case of table
2935
* functions.
3036
*
37+
* @param dataSourceService {@link DataSourceService}.
3138
* @param parts parts of qualifiedName.
32-
* @param allowedDataSources allowedDataSources.
3339
*/
34-
public DataSourceSchemaIdentifierNameResolver(List<String> parts,
35-
Set<String> allowedDataSources) {
40+
public DataSourceSchemaIdentifierNameResolver(DataSourceService dataSourceService,
41+
List<String> parts) {
42+
this.dataSourceService = dataSourceService;
3643
List<String> remainingParts
37-
= captureSchemaName(captureDataSourceName(parts, allowedDataSources));
44+
= captureSchemaName(captureDataSourceName(parts));
3845
identifierName = String.join(DOT, remainingParts);
3946
}
4047

@@ -53,9 +60,8 @@ public String getSchemaName() {
5360

5461
// Capture datasource name and return remaining parts(schema name and table name)
5562
// from the fully qualified name.
56-
private List<String> captureDataSourceName(List<String> parts, Set<String> allowedDataSources) {
57-
if (parts.size() > 1 && allowedDataSources.contains(parts.get(0))
58-
|| DEFAULT_DATASOURCE_NAME.equals(parts.get(0))) {
63+
private List<String> captureDataSourceName(List<String> parts) {
64+
if (parts.size() > 1 && dataSourceService.dataSourceExists(parts.get(0))) {
5965
dataSourceName = parts.get(0);
6066
return parts.subList(1, parts.size());
6167
} else {
@@ -76,5 +82,4 @@ private List<String> captureSchemaName(List<String> parts) {
7682
}
7783
}
7884

79-
8085
}

core/src/main/java/org/opensearch/sql/datasource/DataSourceService.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ public interface DataSourceService {
3434
/**
3535
* Register {@link DataSource} defined by {@link DataSourceMetadata}.
3636
*
37-
* @param metadatas list of {@link DataSourceMetadata}.
37+
* @param metadata {@link DataSourceMetadata}.
3838
*/
39-
void createDataSource(DataSourceMetadata... metadatas);
39+
void createDataSource(DataSourceMetadata metadata);
4040

4141
/**
4242
* Updates {@link DataSource} corresponding to dataSourceMetadata.
@@ -54,13 +54,10 @@ public interface DataSourceService {
5454
void deleteDataSource(String dataSourceName);
5555

5656
/**
57-
* This method is to bootstrap
58-
* datasources during the startup of the plugin.
59-
*/
60-
void bootstrapDataSources();
61-
62-
/**
63-
* remove all the registered {@link DataSource}.
57+
* Returns true {@link Boolean} if datasource with dataSourceName exists
58+
* or else false {@link Boolean}.
59+
*
60+
* @param dataSourceName name of the {@link DataSource}.
6461
*/
65-
void clear();
62+
Boolean dataSourceExists(String dataSourceName);
6663
}

0 commit comments

Comments
 (0)