Skip to content
This repository was archived by the owner on Aug 2, 2022. It is now read-only.

Commit 1a1c209

Browse files
weicongs-amazonpenghuo
authored andcommitted
Support Integration Tests for Security enabled ODFE cluster (#473)
(cherry picked from commit 668bd24)
1 parent 6ecff74 commit 1a1c209

File tree

3 files changed

+131
-3
lines changed

3 files changed

+131
-3
lines changed

build.gradle

+4
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ integTest.runner {
153153
// allows integration test classes to access test resource from project root path
154154
systemProperty('project.root', project.rootDir.absolutePath)
155155

156+
systemProperty "https", System.getProperty("https")
157+
systemProperty "user", System.getProperty("user")
158+
systemProperty "password", System.getProperty("password")
159+
156160
// Tell the test JVM if the cluster JVM is running under a debugger so that tests can use longer timeouts for
157161
// requests. The 'doFirst' delays reading the debug setting on the cluster till execution time.
158162
doFirst { systemProperty 'cluster.debug', getDebug()}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package com.amazon.opendistroforelasticsearch.sql.esintgtest;
17+
18+
import org.apache.http.Header;
19+
import org.apache.http.HttpHost;
20+
import org.apache.http.auth.AuthScope;
21+
import org.apache.http.auth.UsernamePasswordCredentials;
22+
import org.apache.http.client.CredentialsProvider;
23+
import org.apache.http.conn.ssl.NoopHostnameVerifier;
24+
import org.apache.http.impl.client.BasicCredentialsProvider;
25+
import org.apache.http.message.BasicHeader;
26+
import org.apache.http.ssl.SSLContextBuilder;
27+
import org.apache.http.util.EntityUtils;
28+
import org.elasticsearch.client.Request;
29+
import org.elasticsearch.client.Response;
30+
import org.elasticsearch.client.RestClient;
31+
import org.elasticsearch.client.RestClientBuilder;
32+
import org.elasticsearch.common.settings.Settings;
33+
import org.elasticsearch.common.unit.TimeValue;
34+
import org.elasticsearch.common.util.concurrent.ThreadContext;
35+
import org.elasticsearch.test.rest.ESRestTestCase;
36+
import org.json.JSONArray;
37+
import org.json.JSONObject;
38+
39+
import java.io.IOException;
40+
import java.util.Map;
41+
import java.util.Optional;
42+
43+
/**
44+
* ODFE integration test base class to support both security disabled and enabled ODFE cluster.
45+
*/
46+
public abstract class ODFERestTestCase extends ESRestTestCase {
47+
48+
protected boolean isHttps() {
49+
boolean isHttps = Optional.ofNullable(System.getProperty("https"))
50+
.map("true"::equalsIgnoreCase).orElse(false);
51+
if (isHttps) {
52+
//currently only external cluster is supported for security enabled testing
53+
if (!Optional.ofNullable(System.getProperty("tests.rest.cluster")).isPresent()) {
54+
throw new RuntimeException("external cluster url should be provided for security enabled testing");
55+
}
56+
}
57+
58+
return isHttps;
59+
}
60+
61+
protected String getProtocol() {
62+
return isHttps() ? "https" : "http";
63+
}
64+
65+
protected RestClient buildClient(Settings settings, HttpHost[] hosts) throws IOException {
66+
RestClientBuilder builder = RestClient.builder(hosts);
67+
if (isHttps()) {
68+
configureHttpsClient(builder, settings);
69+
} else {
70+
configureClient(builder, settings);
71+
}
72+
73+
builder.setStrictDeprecationMode(true);
74+
return builder.build();
75+
}
76+
77+
protected static void wipeAllODFEIndices() throws IOException {
78+
Response response = client().performRequest(new Request("GET", "/_cat/indices?format=json"));
79+
JSONArray jsonArray = new JSONArray(EntityUtils.toString(response.getEntity(), "UTF-8"));
80+
for (Object object : jsonArray) {
81+
JSONObject jsonObject = (JSONObject)object;
82+
String indexName = jsonObject.getString("index");
83+
//.opendistro_security isn't allowed to delete from cluster
84+
if (!".opendistro_security".equals(indexName)) {
85+
client().performRequest(new Request("DELETE", "/" + indexName));
86+
}
87+
}
88+
}
89+
90+
protected static void configureHttpsClient(RestClientBuilder builder, Settings settings) throws IOException {
91+
Map<String, String> headers = ThreadContext.buildDefaultHeaders(settings);
92+
Header[] defaultHeaders = new Header[headers.size()];
93+
int i = 0;
94+
for (Map.Entry<String, String> entry : headers.entrySet()) {
95+
defaultHeaders[i++] = new BasicHeader(entry.getKey(), entry.getValue());
96+
}
97+
builder.setDefaultHeaders(defaultHeaders);
98+
builder.setHttpClientConfigCallback(httpClientBuilder -> {
99+
String userName = Optional.ofNullable(System.getProperty("user"))
100+
.orElseThrow(() -> new RuntimeException("user name is missing"));
101+
String password = Optional.ofNullable(System.getProperty("password"))
102+
.orElseThrow(() -> new RuntimeException("password is missing"));
103+
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
104+
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
105+
try {
106+
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)
107+
//disable the certificate since our testing cluster just uses the default security configuration
108+
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
109+
.setSSLContext(SSLContextBuilder.create()
110+
.loadTrustMaterial(null, (chains, authType) -> true)
111+
.build());
112+
} catch (Exception e) {
113+
throw new RuntimeException(e);
114+
}
115+
});
116+
117+
final String socketTimeoutString = settings.get(CLIENT_SOCKET_TIMEOUT);
118+
final TimeValue socketTimeout =
119+
TimeValue.parseTimeValue(socketTimeoutString == null ? "60s" : socketTimeoutString, CLIENT_SOCKET_TIMEOUT);
120+
builder.setRequestConfigCallback(conf -> conf.setSocketTimeout(Math.toIntExact(socketTimeout.getMillis())));
121+
if (settings.hasValue(CLIENT_PATH_PREFIX)) {
122+
builder.setPathPrefix(settings.get(CLIENT_PATH_PREFIX));
123+
}
124+
}
125+
}

src/test/java/com/amazon/opendistroforelasticsearch/sql/esintgtest/SQLIntegTestCase.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import org.elasticsearch.client.Request;
2020
import org.elasticsearch.client.RequestOptions;
2121
import org.elasticsearch.client.Response;
22-
import org.elasticsearch.test.rest.ESRestTestCase;
2322
import org.json.JSONArray;
2423
import org.json.JSONObject;
2524
import org.junit.AfterClass;
@@ -78,7 +77,7 @@
7877
* \ \
7978
* XXXTIT: 3) init() 5) init()
8079
*/
81-
public abstract class SQLIntegTestCase extends ESRestTestCase {
80+
public abstract class SQLIntegTestCase extends ODFERestTestCase {
8281

8382
public static final String PERSISTENT = "persistent";
8483
public static final String TRANSIENT = "transient";
@@ -141,7 +140,7 @@ public static void dumpCoverage() {
141140
*/
142141
@AfterClass
143142
public static void cleanUpIndices() throws IOException {
144-
wipeAllIndices();
143+
wipeAllODFEIndices();
145144
wipeAllClusterSettings();
146145
}
147146

0 commit comments

Comments
 (0)