This is an automated email from the ASF dual-hosted git repository. pdallig pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/zeppelin.git
The following commit(s) were added to refs/heads/master by this push: new 47d8902 [ZEPPELIN-5626] Allow to use https for Elasticsearch Interpreter 47d8902 is described below commit 47d8902ef4a49cbe26d165319896fd9f851a023e Author: BaptisteMeynier <baptiste.meyn...@gmail.com> AuthorDate: Mon Jan 10 12:28:29 2022 +0100 [ZEPPELIN-5626] Allow to use https for Elasticsearch Interpreter ### Allow to use https for Elasticsearch Interpreter ### Jira issue * [ZEPPELIN-5626] Author: BaptisteMeynier <baptiste.meyn...@gmail.com> Closes #4283 from BaptisteMeynier/ZEPPELIN-5626 and squashes the following commits: d4360e3b0 [BaptisteMeynier] ZEPPELIN-5626: correct checkstyle issue 2fbb592d3 [BaptisteMeynier] ZEPPELIN-5626: correct licence issues 2efa3d18a [BaptisteMeynier] ZEPPELIN-5626: correct checkstyle requirements 29feaf091 [BaptisteMeynier] ZEPPELIN-5626: Correct checkstyle rules 382c4ea78 [BaptisteMeynier] ZEPPELIN-5626: Correct checkstyle rules c72361c17 [BaptisteMeynier] ZEPPELIN-5626: Correct checkstyle rules 3fed1f9c5 [BaptisteMeynier] ZEPPELIN-5626: Correct style ab52fdf10 [BaptisteMeynier] ZEPPELIN-5626: add compatibility with https protocol for Elastic protocol f521565e4 [BaptisteMeynier] ZEPPELIN-5626: add compatibility with https protocol for Elastic protocol b64613c38 [BaptisteMeynier] ZEPPELIN-5626: add compatibility with https protocol for Elastic protocol 050ce9525 [BaptisteMeynier] ZEPPELIN-5626: add compatibility with https protocol for Elastic protocol f493a380d [BaptisteMeynier] ZEPPELIN-5626: Adding https support for Elasticsearch interpreter --- .../elasticsearch/ElasticsearchInterpreter.java | 20 +++-- .../client/ElasticsearchClientType.java | 32 ++++++++ .../client/ElasticsearchClientTypeBuilder.java | 64 ++++++++++++++++ .../elasticsearch/client/HttpBasedClient.java | 12 ++- .../src/main/resources/interpreter-setting.json | 2 +- .../client/ElasticsearchClientTypeBuilderTest.java | 85 ++++++++++++++++++++++ .../client/ElasticsearchClientTypeTest.java | 43 +++++++++++ 7 files changed, 249 insertions(+), 9 deletions(-) diff --git a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreter.java b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreter.java index 45b37c4..4066674 100644 --- a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreter.java +++ b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreter.java @@ -22,6 +22,11 @@ import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import org.apache.commons.lang3.StringUtils; +import org.apache.zeppelin.elasticsearch.client.ElasticsearchClient; +import org.apache.zeppelin.elasticsearch.client.ElasticsearchClientType; +import org.apache.zeppelin.elasticsearch.client.ElasticsearchClientTypeBuilder; +import org.apache.zeppelin.elasticsearch.client.HttpBasedClient; +import org.apache.zeppelin.elasticsearch.client.TransportBasedClient; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentHelper; @@ -55,14 +60,13 @@ import org.apache.zeppelin.completer.CompletionType; import org.apache.zeppelin.elasticsearch.action.ActionResponse; import org.apache.zeppelin.elasticsearch.action.AggWrapper; import org.apache.zeppelin.elasticsearch.action.HitWrapper; -import org.apache.zeppelin.elasticsearch.client.ElasticsearchClient; -import org.apache.zeppelin.elasticsearch.client.HttpBasedClient; -import org.apache.zeppelin.elasticsearch.client.TransportBasedClient; import org.apache.zeppelin.interpreter.Interpreter; import org.apache.zeppelin.interpreter.InterpreterContext; import org.apache.zeppelin.interpreter.InterpreterResult; import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion; +import static org.apache.zeppelin.elasticsearch.client.ElasticsearchClientType.TRANSPORT; + /** * Elasticsearch Interpreter for Zeppelin. */ @@ -112,8 +116,10 @@ public class ElasticsearchInterpreter extends Interpreter { public void open() { logger.info("Properties: {}", getProperties()); - String clientType = getProperty(ELASTICSEARCH_CLIENT_TYPE); - clientType = clientType == null ? null : clientType.toLowerCase(); + ElasticsearchClientType clientType = + ElasticsearchClientTypeBuilder + .withPropertyValue(getProperty(ELASTICSEARCH_CLIENT_TYPE)) + .build(); try { this.resultSize = Integer.parseInt(getProperty(ELASTICSEARCH_RESULT_SIZE)); @@ -124,9 +130,9 @@ public class ElasticsearchInterpreter extends Interpreter { } try { - if (StringUtils.isEmpty(clientType) || "transport".equals(clientType)) { + if (TRANSPORT.equals(clientType)) { elsClient = new TransportBasedClient(getProperties()); - } else if ("http".equals(clientType)) { + } else if (clientType.isHttp()) { elsClient = new HttpBasedClient(getProperties()); } else { logger.error("Unknown type of Elasticsearch client: " + clientType); diff --git a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/ElasticsearchClientType.java b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/ElasticsearchClientType.java new file mode 100644 index 0000000..753e7d9 --- /dev/null +++ b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/ElasticsearchClientType.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.zeppelin.elasticsearch.client; + +public enum ElasticsearchClientType { + HTTP(true), HTTPS(true), TRANSPORT(false), UNKNOWN(false); + + private final boolean isHttp; + + ElasticsearchClientType(boolean isHttp) { + this.isHttp = isHttp; + } + + public boolean isHttp() { + return isHttp; + } +} diff --git a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/ElasticsearchClientTypeBuilder.java b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/ElasticsearchClientTypeBuilder.java new file mode 100644 index 0000000..619cb4a --- /dev/null +++ b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/ElasticsearchClientTypeBuilder.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.zeppelin.elasticsearch.client; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Arrays; + +import static org.apache.zeppelin.elasticsearch.client.ElasticsearchClientType.TRANSPORT; +import static org.apache.zeppelin.elasticsearch.client.ElasticsearchClientType.UNKNOWN; +import static org.apache.zeppelin.elasticsearch.client.ElasticsearchClientType.valueOf; +import static org.apache.zeppelin.elasticsearch.client.ElasticsearchClientType.values; + +public class ElasticsearchClientTypeBuilder { + + private static final ElasticsearchClientType DEFAULT_ELASTICSEARCH_CLIENT_TYPE = TRANSPORT; + + public static Build withPropertyValue(String propertyValue) { + return new Builder(propertyValue); + } + + public interface Build { + ElasticsearchClientType build(); + } + + private static class Builder implements Build { + private final String propertyValue; + + private Builder(String propertyValue) { + this.propertyValue = propertyValue; + } + + @Override + public ElasticsearchClientType build() { + boolean isEmpty = StringUtils.isEmpty(propertyValue); + return isEmpty ? + DEFAULT_ELASTICSEARCH_CLIENT_TYPE : + getElasticsearchClientType(propertyValue); + } + + private ElasticsearchClientType getElasticsearchClientType(String propertyValue){ + boolean isExistingValue = + Arrays + .stream(values()) + .anyMatch(clientType -> clientType.toString().equalsIgnoreCase(propertyValue)); + return isExistingValue ? valueOf(propertyValue.toUpperCase()) : UNKNOWN; + } + } +} diff --git a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/HttpBasedClient.java b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/HttpBasedClient.java index 0bb9aa1..94f9282 100644 --- a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/HttpBasedClient.java +++ b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/HttpBasedClient.java @@ -53,6 +53,7 @@ public class HttpBasedClient implements ElasticsearchClient { private static final String QUERY_STRING_TEMPLATE = "{ \"query\": { \"query_string\": { \"query\": \"_Q_\", \"analyze_wildcard\": \"true\" } } }"; + private final String protocol; private final String host; private final int port; private final String username; @@ -61,12 +62,21 @@ public class HttpBasedClient implements ElasticsearchClient { private final Gson gson = new GsonBuilder().setPrettyPrinting().create(); public HttpBasedClient(Properties props) { + this.protocol = loadProtocol(props); this.host = props.getProperty(ElasticsearchInterpreter.ELASTICSEARCH_HOST); this.port = Integer.parseInt(props.getProperty(ElasticsearchInterpreter.ELASTICSEARCH_PORT)); this.username = props.getProperty(ElasticsearchInterpreter.ELASTICSEARCH_BASIC_AUTH_USERNAME); this.password = props.getProperty(ElasticsearchInterpreter.ELASTICSEARCH_BASIC_AUTH_PASSWORD); } + private String loadProtocol(Properties props){ + String proto = props.getProperty(ElasticsearchInterpreter.ELASTICSEARCH_CLIENT_TYPE); + if (StringUtils.isNotEmpty(proto)) { + proto = proto.toLowerCase(); + } + return proto; + } + private boolean isSucceeded(HttpResponse<?> response) { return response.getStatus() >= 200 && response.getStatus() < 300; } @@ -102,7 +112,7 @@ public class HttpBasedClient implements ElasticsearchClient { private String getUrl(String index, String type, String id, boolean useSearch) { try { final StringBuilder buffer = new StringBuilder(); - buffer.append("http://").append(host).append(":").append(port).append("/"); + buffer.append(protocol).append("://").append(host).append(":").append(port).append("/"); if (StringUtils.isNotEmpty(index)) { buffer.append(index); diff --git a/elasticsearch/src/main/resources/interpreter-setting.json b/elasticsearch/src/main/resources/interpreter-setting.json index 3e132f2..d2c9db0 100644 --- a/elasticsearch/src/main/resources/interpreter-setting.json +++ b/elasticsearch/src/main/resources/interpreter-setting.json @@ -22,7 +22,7 @@ "envName": "ELASTICSEARCH_CLIENT_TYPE", "propertyName": "elasticsearch.client.type", "defaultValue": "transport", - "description": "The type of client for Elasticsearch (transport or http)", + "description": "The type of client for Elasticsearch (transport or http or https)", "type": "string" }, "elasticsearch.cluster.name": { diff --git a/elasticsearch/src/test/java/org/apache/zeppelin/elasticsearch/client/ElasticsearchClientTypeBuilderTest.java b/elasticsearch/src/test/java/org/apache/zeppelin/elasticsearch/client/ElasticsearchClientTypeBuilderTest.java new file mode 100644 index 0000000..fdb614c --- /dev/null +++ b/elasticsearch/src/test/java/org/apache/zeppelin/elasticsearch/client/ElasticsearchClientTypeBuilderTest.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.zeppelin.elasticsearch.client; + +import org.junit.Test; + +import static org.apache.zeppelin.elasticsearch.client.ElasticsearchClientType.HTTP; +import static org.apache.zeppelin.elasticsearch.client.ElasticsearchClientType.HTTPS; +import static org.apache.zeppelin.elasticsearch.client.ElasticsearchClientType.TRANSPORT; +import static org.apache.zeppelin.elasticsearch.client.ElasticsearchClientType.UNKNOWN; +import static org.junit.Assert.assertThat; +import static org.hamcrest.Matchers.is; + +public class ElasticsearchClientTypeBuilderTest { + + @Test + public void it_should_return_transport_as_default_value_when_property_is_empty() { + //GIVEN + String empty = ""; + //WHEN + ElasticsearchClientType clientType = + ElasticsearchClientTypeBuilder.withPropertyValue(empty).build(); + //THEN + assertThat(clientType, is(TRANSPORT)); + } + + @Test + public void it_should_return_transport_as_default_value_when_property_is_null() { + //GIVEN + String nullValue = null; + //WHEN + ElasticsearchClientType clientType = + ElasticsearchClientTypeBuilder.withPropertyValue(nullValue).build(); + //THEN + assertThat(clientType, is(TRANSPORT)); + } + + @Test + public void it_should_return_client_type_when_property_value_exists() { + //GIVEN + String clientType = "https"; + //WHEN + ElasticsearchClientType esClientType = + ElasticsearchClientTypeBuilder.withPropertyValue(clientType).build(); + //THEN + assertThat(esClientType, is(HTTPS)); + } + + @Test + public void it_should_return_client_type_and_ignore_case_when_property_value_exists() { + //GIVEN + String clientType = "hTtP"; + //WHEN + ElasticsearchClientType esClientType = + ElasticsearchClientTypeBuilder.withPropertyValue(clientType).build(); + //THEN + assertThat(esClientType, is(HTTP)); + } + + @Test + public void it_should_return_unknown_when_property_value_does_not_exist() { + //GIVEN + String unknownValue = "an_unknown_value"; + //WHEN + ElasticsearchClientType esClientType = + ElasticsearchClientTypeBuilder.withPropertyValue(unknownValue).build(); + //THEN + assertThat(esClientType, is(UNKNOWN)); + } +} diff --git a/elasticsearch/src/test/java/org/apache/zeppelin/elasticsearch/client/ElasticsearchClientTypeTest.java b/elasticsearch/src/test/java/org/apache/zeppelin/elasticsearch/client/ElasticsearchClientTypeTest.java new file mode 100644 index 0000000..21deb4c --- /dev/null +++ b/elasticsearch/src/test/java/org/apache/zeppelin/elasticsearch/client/ElasticsearchClientTypeTest.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.zeppelin.elasticsearch.client; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public class ElasticsearchClientTypeTest { + + @Test + public void it_should_return_http_when_reducing_on_http_types() { + //GIVEN + List<ElasticsearchClientType> httpTypes = + new ArrayList<>(Arrays.asList(ElasticsearchClientType.HTTP, ElasticsearchClientType.HTTPS)); + //WHEN + Boolean httpTypesReduced = httpTypes.stream() + .map(ElasticsearchClientType::isHttp) + .reduce(true, (ident, elasticsearchClientType) -> ident && elasticsearchClientType); + //THEN + assertThat(httpTypesReduced, is(true)); + } +}