001/*- 002 * #%L 003 * HAPI FHIR JPA Server 004 * %% 005 * Copyright (C) 2014 - 2023 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.jpa.search.lastn; 021 022import ca.uhn.fhir.context.ConfigurationException; 023import ca.uhn.fhir.i18n.Msg; 024import org.apache.commons.lang3.StringUtils; 025import org.apache.http.Header; 026import org.apache.http.HttpHost; 027import org.apache.http.auth.AuthScope; 028import org.apache.http.auth.UsernamePasswordCredentials; 029import org.apache.http.client.CredentialsProvider; 030import org.apache.http.impl.client.BasicCredentialsProvider; 031import org.apache.http.message.BasicHeader; 032import org.elasticsearch.client.Node; 033import org.elasticsearch.client.RestClient; 034import org.elasticsearch.client.RestClientBuilder; 035import org.elasticsearch.client.RestHighLevelClient; 036 037import java.util.Arrays; 038import java.util.List; 039import java.util.stream.Collectors; 040import javax.annotation.Nullable; 041 042public class ElasticsearchRestClientFactory { 043 044 public static RestHighLevelClient createElasticsearchHighLevelRestClient( 045 String protocol, String hosts, @Nullable String theUsername, @Nullable String thePassword) { 046 047 if (hosts.contains("://")) { 048 throw new ConfigurationException( 049 Msg.code(1173) 050 + "Elasticsearch URLs cannot include a protocol, that is a separate property. Remove http:// or https:// from this URL."); 051 } 052 String[] hostArray = hosts.split(","); 053 List<Node> clientNodes = Arrays.stream(hostArray) 054 .map(String::trim) 055 .filter(s -> s.contains(":")) 056 .map(h -> { 057 int colonIndex = h.indexOf(":"); 058 String host = h.substring(0, colonIndex); 059 int port = Integer.parseInt(h.substring(colonIndex + 1)); 060 return new Node(new HttpHost(host, port, protocol)); 061 }) 062 .collect(Collectors.toList()); 063 if (hostArray.length != clientNodes.size()) { 064 throw new ConfigurationException( 065 Msg.code(1174) 066 + "Elasticsearch URLs have to contain ':' as a host:port separator. Example: localhost:9200,localhost:9201,localhost:9202"); 067 } 068 069 RestClientBuilder clientBuilder = RestClient.builder(clientNodes.toArray(new Node[0])); 070 if (StringUtils.isNotBlank(theUsername) && StringUtils.isNotBlank(thePassword)) { 071 final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); 072 credentialsProvider.setCredentials( 073 AuthScope.ANY, new UsernamePasswordCredentials(theUsername, thePassword)); 074 clientBuilder.setHttpClientConfigCallback( 075 httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)); 076 } 077 078 Header[] defaultHeaders = new Header[] {new BasicHeader("Content-Type", "application/json")}; 079 clientBuilder.setDefaultHeaders(defaultHeaders); 080 081 return new RestHighLevelClient(clientBuilder); 082 } 083}