You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by pd...@apache.org on 2022/01/26 15:07:56 UTC

[zeppelin] branch master updated: [ZEPPELIN-5626] Allow to use https for Elasticsearch Interpreter

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 <ba...@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 <ba...@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));
+  }
+}