使用 Java 客戶端透過 HTTPS 連線到 Easysearch

infinilabs發表於2023-11-26

Easysearch 一直致力於提高易用性,這也是我們的核心宗旨,然而之前一直沒有官方的 Java 客戶端,也對使用者使用造成了一些困擾,現在,我們正式釋出了第一個 Java 客戶端  Easysearch-client:1.0.1

這一里程碑式的更新為開發人員帶來了前所未有的便利性,使得與 Easysearch 叢集的互動變得更加簡潔和直觀。透過 Easysearch-client,開發者可以直接使用 Java 方法和資料結構來進行互動,而不再需要依賴於傳統的 HTTP 方法和 JSON。
這一變化大大簡化了操作流程,使得資料管理和索引更加高效。Java 客戶端的功能範圍包括處理資料操作,管理叢集,包括檢視和維護叢集的健康狀態,並對 Security 模組全面相容。它提供了一系列 API,用於管理角色、使用者、許可權、角色對映和賬戶。
這意味著安全性和訪問控制現在可以更加細粒度地管理,確保了資料的安全性和合規性。

在這篇部落格中,你將學習如何配置 Easysearch-client 客戶端以透過 HTTPS 連線到 Easysearch。為了演示目的,我將首先設定一個帶有 SSL 證照的 Easysearch 伺服器。如果你已經有一個在執行,你可以跳過這一步。
接下來,我將引導你完成在 Java 應用程式中配置和使用 Java 客戶端的步驟。

設定 Easysearch 伺服器

首先從極限科技官網下載最新的 Mac 版本。我使用的是 1.6.1 版本,這是我寫這篇文章時的最新版本。

wget 

確保您的系統已經安裝並設定了 java 環境變數,版本在 11 以上。

解壓下載檔案。

unzip easysearch-1.6.1-214-mac-amd64.zip -d easysearch-1.6.1

cd 到 easysearch-1.6.1 執行初始化指令碼來生成證照並自動下載外掛。

 bin/initialize.sh

指令碼執行後會自動輸出隨機生成的 admin 使用者密碼。

啟動 Easysearch

bin/easysearch

此時,您的伺服器已經準備就緒。您可以檢視 logs/initialize.log 裡顯示的 curl 命令來進行驗證。

curl -ku admin:xxxxxxxxx 

顯示類似的輸出響應

{
  "name" : "MacBook-Pro.local",
  "cluster_name" : "easysearch",
  "cluster_uuid" : "1gRYQ6ssTiKGqcyuEN0Dbg",
  "version" : {
    "distribution" : "easysearch",
    "number" : "1.6.1",
    "distributor" : "INFINI Labs",
    "build_hash" : "14846e460e9976ba6d68c80bb9eca52af1179dcf",
    "build_date" : "2023-10-19T14:43:02.636639Z",
    "build_snapshot" : false,
    "lucene_version" : "8.11.2",
    "minimum_wire_lucene_version" : "7.7.0",
    "minimum_lucene_index_compatibility_version" : "7.7.0"
  },
  "tagline" : "You Know, For Easy Search!"
}

下面我們來看如何設定和使用客戶端。

設定 Java 客戶端

Easysearch 的 Java 客戶端可在 中央倉庫:  上獲得。將其作為依賴項新增到你的 Java 應用程式中。
對於 Gradle 構建系統,在專案的 build.gradle 檔案中包含以下依賴項:

dependencies {
    implementation 'com.infinilabs:easysearch-client:1.0.1'
    implementation "org.apache.logging.log4j:log4j-api:2.19.0"
    implementation "org.apache.logging.log4j:log4j-core:2.19.0"
    implementation 'org.apache.httpcomponents:httpclient:4.5.10'
    implementation 'org.apache.httpcomponents:httpcore-nio:4.4.12'
    implementation 'org.apache.httpcomponents:httpasyncclient:4.1.4'
    implementation 'joda-time:joda-time:2.10.4'
    implementation ('org.apache.lucene:lucene-core:8.11.2') {
        exclude group: '*', module: '*'
    }
    implementation ('org.apache.lucene:lucene-analyzers-common:8.11.2') {
        exclude group: '*', module: '*'
    }
    implementation ('org.apache.lucene:lucene-backward-codecs:8.11.2') {
        exclude group: '*', module: '*'
    }
    implementation ('org.apache.lucene:lucene-grouping:8.11.2') {
        exclude group: '*', module: '*'
    }
    implementation ('org.apache.lucene:lucene-highlighter:8.11.2') {
        exclude group: '*', module: '*'
    }
    implementation ('org.apache.lucene:lucene-join:8.11.2') {
        exclude group: '*', module: '*'
    }
    implementation ('org.apache.lucene:lucene-memory:8.11.2') {
        exclude group: '*', module: '*'
    }
    implementation ('org.apache.lucene:lucene-misc:8.11.2') {
        exclude group: '*', module: '*'
    }
    implementation ('org.apache.lucene:lucene-queries:8.11.2') {
        exclude group: '*', module: '*'
    }
    implementation ('org.apache.lucene:lucene-queryparser:8.11.2') {
        exclude group: '*', module: '*'
    }
    implementation ('org.apache.lucene:lucene-sandbox:8.11.2') {
        exclude group: '*', module: '*'
    }
    implementation ('org.apache.lucene:lucene-spatial3d:8.11.2') {
        exclude group: '*', module: '*'
    }
    implementation ('org.apache.lucene:lucene-suggest:8.11.2') {
        exclude group: '*', module: '*'
    }
  ......
}

對於 Maven 構建系統,在專案的 pom.xml 檔案中包含以下依賴項:

<dependencies>
    <dependency>
        <groupId>com.infinilabs</groupId>
        <artifactId>easysearch-client</artifactId>
        <version>1.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.10</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpcore-nio</artifactId>
        <version>4.4.12</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpasyncclient</artifactId>
        <version>4.1.4</version>
    </dependency>
    <dependency>
        <groupId>joda-time</groupId>
        <artifactId>joda-time</artifactId>
        <version>2.10.4</version>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-core</artifactId>
        <version>8.11.2</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <artifactId>*</artifactId>
                <groupId>*</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-analyzers-common</artifactId>
        <version>8.11.2</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <artifactId>*</artifactId>
                <groupId>*</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-backward-codecs</artifactId>
        <version>8.11.2</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <artifactId>*</artifactId>
                <groupId>*</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-grouping</artifactId>
        <version>8.11.2</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <artifactId>*</artifactId>
                <groupId>*</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-highlighter</artifactId>
        <version>8.11.2</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <artifactId>*</artifactId>
                <groupId>*</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-join</artifactId>
        <version>8.11.2</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <artifactId>*</artifactId>
                <groupId>*</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-memory</artifactId>
        <version>8.11.2</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <artifactId>*</artifactId>
                <groupId>*</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-misc</artifactId>
        <version>8.11.2</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <artifactId>*</artifactId>
                <groupId>*</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-queries</artifactId>
        <version>8.11.2</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <artifactId>*</artifactId>
                <groupId>*</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-queryparser</artifactId>
        <version>8.11.2</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <artifactId>*</artifactId>
                <groupId>*</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-sandbox</artifactId>
        <version>8.11.2</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <artifactId>*</artifactId>
                <groupId>*</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-spatial3d</artifactId>
        <version>8.11.2</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <artifactId>*</artifactId>
                <groupId>*</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-suggest</artifactId>
        <version>8.11.2</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <artifactId>*</artifactId>
                <groupId>*</groupId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

接下來,在你的 Java 應用程式中建立一個 client 例項,並使用它在 Easysearch 中建立索引並插入一些資料。但在此之前,為了使其工作,你需要將簽署伺服器證照的根機構證照新增到你的應用程式信任庫中。讓我們看看如何配置 Java 應用程式的信任庫。

為了使用 java client,你需要將根 CA 證照 ca.crt 新增到應用程式信任庫中。這告訴你的 Java 應用程式信任由此根機構簽署的任何證照。easysearch-1.6.1/config/ 目錄下已經生成了 ca.crt 檔案。你可以將其新增到自定義信任庫中,並在 Java 應用程式中使用該自定義信任庫。

使用 Java keytool 建立一個自定義信任庫並匯入證照。keytool 不理解 .pem 格式,所以你需要首先使用 openssl 加密庫將證照轉換為 .der 格式,然後使用 Java keytool 將其新增到自定義信任庫中。假設您的作業系統已經預裝了 openssl。

第 1 步:將 CA 證照從 .pem 格式轉換為 .der 格式。

openssl x509 -in easysearch-1.6.1/config/ca.crt -inform pem -out ca.der --outform der

第 2 步:建立自定義信任庫並新增 ca.der 證照。
將 ca 證照新增到應用程式信任庫中,表示應用程式信任由此 CA 簽署的任何證照。

keytool -import -file ca.der -alias easysearch -keystore myTrustStore

過程中會提示您輸入金鑰庫口令: 我為了測試用輸入的 123456。

透過列出信任庫中的證照來確認操作成功,這裡的 123456 是我上面設定的密碼,會顯示出 easysearch 證照。

keytool -keystore myTrustStore -storepass 123456 -list

第 3 步:在 Java 應用程式程式碼中設定指向自定義信任庫的系統屬性,並連線叢集,建立索引,插入資料。
可以透過設定系統屬性,以指定 SSL/TLS 通訊時使用的信任庫:

 System.setProperty("javax.net.ssl.trustStore", "/full/path/to/myTrustStore");
System.setProperty("javax.net.ssl.trustStorePassword", "123456");
HttpHost[] httpHostArray = new HttpHost[1];
// infini.cloud 和 CN=infini.cloud 保持一致
httpHostArray[0] = new HttpHost("infini.cloud", 9200, "https");
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("admin", "1933791fb2b9f6c6146d"));
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(httpHostArray)
    .setHttpClientConfigCallback((HttpAsyncClientBuilder httpAsyncClientBuilder) -> {
      httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
      return httpAsyncClientBuilder;
    }));
CreateIndexRequest createIndexRequest = new CreateIndexRequest("test-index");
createIndexRequest.settings(Settings.builder()
    .put("index.number_of_shards", 1)
    .put("index.number_of_replicas", 1)
);
//Create index
client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
// Bulk
BulkRequest bulkRequest = new BulkRequest();
for (int i = 0; i < 10; i++) {
  IndexRequest indexRequest = new IndexRequest("test-index")
      .id(Integer.toString(i))
      .source("{\"field1\":\"value" + i + "\"}", XContentType.JSON);
  bulkRequest.add(indexRequest);
}
BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(Strings.toString(bulkResponse));

信任已簽署 Easysearch 正在使用的證照的 CA 的示例,當 CA 證照以 PEM 編碼檔案的形式可用時:

Path caCertificatePath = Paths.get("/easysearch-test/easysearch-1.6.1/config/ca.crt");
CertificateFactory factory = CertificateFactory.getInstance("X.509");
Certificate trustedCa;
try (InputStream is = Files.newInputStream(caCertificatePath)) {
  trustedCa = factory.generateCertificate(is);
}
KeyStore trustStore = KeyStore.getInstance("pkcs12");
trustStore.load(null, null);
trustStore.setCertificateEntry("ca", trustedCa);
SSLContextBuilder sslContextBuilder = SSLContexts.custom()
    .loadTrustMaterial(trustStore, null);
final SSLContext sslContext = sslContextBuilder.build();
HttpHost[] httpHostArray = new HttpHost[1];
httpHostArray[0] = new HttpHost("infini.cloud", 9200, "https");
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("admin", "1933791fb2b9f6c6146d"));
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(httpHostArray)
    .setHttpClientConfigCallback((HttpAsyncClientBuilder httpAsyncClientBuilder) -> {
      httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
      httpAsyncClientBuilder.setSSLContext(sslContext);
      return httpAsyncClientBuilder;
    }));

現在,您已經成功設定了 Java 客戶端,並以安全的 HTTPS 通道連線到了 Easysearch 叢集。除此之外,Java 客戶端還具備強大的許可權控制管理 API,具體請參考我們的官網文件: https://www.infinilabs.com/docs/latest/easysearch/references/client/security/

關於 Easysearch

about easysearch

INFINI Easysearch 是一個分散式的近實時搜尋與分析引擎,核心引擎基於開源的 Apache Lucene。Easysearch 的目標是提供一個輕量級的 Elasticsearch 可替代版本,並繼續完善和支援更多的企業級功能。 與 Elasticsearch 相比,Easysearch 更關注在搜尋業務場景的最佳化和繼續保持其產品的簡潔與易用性。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70029458/viewspace-2997283/,如需轉載,請註明出處,否則將追究法律責任。

相關文章