Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,8 @@
import co.elastic.clients.elasticsearch.indices.IndexSettings;
import co.elastic.clients.elasticsearch.indices.PutIndicesSettingsRequest;
import co.elastic.clients.elasticsearch.indices.PutIndicesSettingsResponse;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import jakarta.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
Expand All @@ -42,10 +37,9 @@
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.phoebus.channelfinder.common.TextUtil;
import org.phoebus.channelfinder.entity.Property;
import org.phoebus.channelfinder.entity.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
Expand All @@ -55,15 +49,16 @@
* @author Kunal Shroff {@literal <shroffk@bnl.gov>}
*/
@Configuration
@ConfigurationProperties(prefix = "elasticsearch")
@ComponentScan(basePackages = {"org.phoebus.channelfinder"})
@PropertySource(value = "classpath:application.properties")
public class ElasticConfig implements ServletContextListener {
public class ElasticConfig {

private static final Logger logger = Logger.getLogger(ElasticConfig.class.getName());

private ElasticsearchClient searchClient;
private ElasticsearchClient indexClient;
// Used to retrieve the auto-configured ElasticsearchClient lazily in @PostConstruct,
// avoiding a circular dependency (this bean provides RestClient → auto-config builds
// ElasticsearchClient from it).
@Autowired private ApplicationContext applicationContext;

Check warning on line 61 in src/main/java/org/phoebus/channelfinder/configuration/ElasticConfig.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this field injection and use constructor injection instead.

See more on https://sonarcloud.io/project/issues?id=ChannelFinder_ChannelFinderService&issues=AZz8hRIN5Wlikxcaaoar&open=AZz8hRIN5Wlikxcaaoar&pullRequest=205

@Value("${elasticsearch.network.host:localhost}")
private String host;
Expand Down Expand Up @@ -118,51 +113,37 @@
return ES_QUERY_SIZE;
}

ObjectMapper objectMapper =
new ObjectMapper()
.addMixIn(Tag.class, Tag.OnlyTag.class)
.addMixIn(Property.class, Property.OnlyProperty.class);
public ElasticsearchClient getElasticsearchClient() {
return applicationContext.getBean(ElasticsearchClient.class);
}

private static ElasticsearchClient createClient(
ElasticsearchClient currentClient,
ObjectMapper objectMapper,
HttpHost[] httpHosts,
String createIndices,
ElasticConfig config) {
ElasticsearchClient client;
if (currentClient == null) {
// Create the low-level client
RestClientBuilder clientBuilder = RestClient.builder(httpHosts);
// Configure authentication
if (!config.authorizationHeader.isEmpty()) {
clientBuilder.setDefaultHeaders(
new Header[] {new BasicHeader("Authorization", config.authorizationHeader)});
if (!config.username.isEmpty() || !config.password.isEmpty()) {
logger.warning(
"elasticsearch.authorization_header is set, ignoring elasticsearch.username and elasticsearch.password.");
}
} else if (!config.username.isEmpty() || !config.password.isEmpty()) {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
AuthScope.ANY, new UsernamePasswordCredentials(config.username, config.password));
clientBuilder.setHttpClientConfigCallback(
httpClientBuilder ->
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
/**
* Provides the low-level Elasticsearch {@link RestClient} built from the {@code elasticsearch.*}
* connection properties. Spring Boot's {@code ElasticsearchClientAutoConfiguration} detects this
* bean and uses it to auto-configure {@code ElasticsearchTransport} and {@code
* ElasticsearchClient}, which in turn activates the {@code /actuator/health} Elasticsearch
* indicator.
*/
@Bean
public RestClient restClient() {
RestClientBuilder clientBuilder = RestClient.builder(getHttpHosts());
if (!authorizationHeader.isEmpty()) {
clientBuilder.setDefaultHeaders(
new Header[] {new BasicHeader("Authorization", authorizationHeader)});
if (!username.isEmpty() || !password.isEmpty()) {
logger.warning(
"elasticsearch.authorization.header is set, ignoring"
+ " elasticsearch.authorization.username and elasticsearch.authorization.password.");
}
RestClient httpClient = clientBuilder.build();

// Create the Java API Client with the same low level client
ElasticsearchTransport transport =
new RestClientTransport(httpClient, new JacksonJsonpMapper(objectMapper));

client = new ElasticsearchClient(transport);
} else {
client = currentClient;
}
if (Boolean.parseBoolean(createIndices)) {
config.elasticIndexValidation(client);
} else if (!username.isEmpty() || !password.isEmpty()) {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
AuthScope.ANY, new UsernamePasswordCredentials(username, password));
clientBuilder.setHttpClientConfigCallback(
httpClientBuilder ->
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
}
return client;
return clientBuilder.build();
}

private HttpHost[] getHttpHosts() {
Expand All @@ -172,47 +153,33 @@
boolean portIsDefault = (port == 9200);
if (hostUrlsIsDefault && (!hostIsDefault || !portIsDefault)) {
logger.warning(
"Specifying elasticsearch.network.host and elasticsearch.http.port is deprecated, please consider using elasticsearch.host_urls instead.");
"Specifying elasticsearch.network.host and elasticsearch.http.port is deprecated,"
+ " please consider using elasticsearch.host_urls instead.");
return new HttpHost[] {new HttpHost(host, port)};
} else {
if (!hostIsDefault) {
logger.warning(
"Only one of elasticsearch.host_urls and elasticsearch.network.host can be set, ignoring elasticsearch.network.host.");
"Only one of elasticsearch.host_urls and elasticsearch.network.host can be set,"
+ " ignoring elasticsearch.network.host.");
}
if (!portIsDefault) {
logger.warning(
"Only one of elasticsearch.host_urls and elasticsearch.http.port can be set, ignoring elasticsearch.http.port.");
"Only one of elasticsearch.host_urls and elasticsearch.http.port can be set,"
+ " ignoring elasticsearch.http.port.");
}
return Arrays.stream(httpHostUrls).map(HttpHost::create).toArray(HttpHost[]::new);
}
}

@Bean({"searchClient"})
public ElasticsearchClient getSearchClient() {
searchClient = createClient(searchClient, objectMapper, getHttpHosts(), createIndices, this);
return searchClient;
}

@Bean({"indexClient"})
public ElasticsearchClient getIndexClient() {
indexClient = createClient(indexClient, objectMapper, getHttpHosts(), createIndices, this);
return indexClient;
}

@Override
public void contextInitialized(ServletContextEvent sce) {
logger.log(Level.INFO, "Initializing a new Transport clients.");
}

@Override
public void contextDestroyed(ServletContextEvent sce) {
logger.log(Level.INFO, "Closing the default Transport clients.");
if (searchClient != null) searchClient.shutdown();
if (indexClient != null) indexClient.shutdown();
@PostConstruct
public void init() {
if (Boolean.parseBoolean(createIndices)) {
elasticIndexValidation(applicationContext.getBean(ElasticsearchClient.class));
}
}

/**
* Create the olog indices and templates if they don't exist
* Create the ChannelFinder indices and templates if they don't exist
*
* @param client client connected to elasticsearch
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import org.phoebus.channelfinder.entity.Property;
import org.phoebus.channelfinder.entity.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;

/**
Expand Down Expand Up @@ -113,9 +112,7 @@

@Autowired ElasticConfig esService;

@Autowired
@Qualifier("indexClient")
ElasticsearchClient client;
@Autowired ElasticsearchClient client;

Check warning on line 115 in src/main/java/org/phoebus/channelfinder/configuration/PopulateDBConfiguration.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this field injection and use constructor injection instead.

See more on https://sonarcloud.io/project/issues?id=ChannelFinder_ChannelFinderService&issues=AZz8hRLm5Wlikxcaaoas&open=AZz8hRLm5Wlikxcaaoas&pullRequest=205

public static final ObjectMapper mapper = new ObjectMapper();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
import org.phoebus.channelfinder.entity.SearchResult;
import org.phoebus.channelfinder.entity.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.repository.CrudRepository;
Expand All @@ -75,9 +74,7 @@

@Autowired ElasticConfig esService;

@Autowired
@Qualifier("indexClient")
ElasticsearchClient client;
@Autowired ElasticsearchClient client;

Check warning on line 77 in src/main/java/org/phoebus/channelfinder/repository/ChannelRepository.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this field injection and use constructor injection instead.

See more on https://sonarcloud.io/project/issues?id=ChannelFinder_ChannelFinderService&issues=AZz8hRM65Wlikxcaaoav&open=AZz8hRM65Wlikxcaaoav&pullRequest=205

@Value("${repository.chunk.size:10000}")
private int chunkSize;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import org.phoebus.channelfinder.entity.Property;
import org.phoebus.channelfinder.entity.Property.OnlyNameOwnerProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.repository.CrudRepository;
import org.springframework.http.HttpStatus;
Expand All @@ -52,9 +51,7 @@

private static final Logger logger = Logger.getLogger(PropertyRepository.class.getName());

@Autowired
@Qualifier("indexClient")
ElasticsearchClient client;
@Autowired ElasticsearchClient client;

Check warning on line 54 in src/main/java/org/phoebus/channelfinder/repository/PropertyRepository.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this field injection and use constructor injection instead.

See more on https://sonarcloud.io/project/issues?id=ChannelFinder_ChannelFinderService&issues=AZz8hRNf5Wlikxcaaoax&open=AZz8hRNf5Wlikxcaaoax&pullRequest=205

@Autowired ElasticConfig esService;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import org.phoebus.channelfinder.entity.Tag;
import org.phoebus.channelfinder.entity.Tag.OnlyTag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.repository.CrudRepository;
import org.springframework.http.HttpStatus;
Expand All @@ -55,9 +54,7 @@

@Autowired ElasticConfig esService;

@Autowired
@Qualifier("indexClient")
ElasticsearchClient client;
@Autowired ElasticsearchClient client;

Check warning on line 57 in src/main/java/org/phoebus/channelfinder/repository/TagRepository.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this field injection and use constructor injection instead.

See more on https://sonarcloud.io/project/issues?id=ChannelFinder_ChannelFinderService&issues=AZz8hRNK5Wlikxcaaoaw&open=AZz8hRNK5Wlikxcaaoaw&pullRequest=205

@Autowired ChannelRepository channelRepository;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import org.phoebus.channelfinder.entity.Channel;
import org.phoebus.channelfinder.entity.Scroll;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.http.HttpStatus;
import org.springframework.util.MultiValueMap;
Expand All @@ -38,9 +37,7 @@

@Autowired ElasticConfig esService;

@Autowired
@Qualifier("indexClient")
ElasticsearchClient client;
@Autowired ElasticsearchClient client;

Check warning on line 40 in src/main/java/org/phoebus/channelfinder/rest/controller/ChannelScrollController.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this field injection and use constructor injection instead.

See more on https://sonarcloud.io/project/issues?id=ChannelFinder_ChannelFinderService&issues=AZz8hRMe5Wlikxcaaoau&open=AZz8hRMe5Wlikxcaaoau&pullRequest=205

@Override
public Scroll query(MultiValueMap<String, String> allRequestParams) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.phoebus.channelfinder.configuration.ElasticConfig;
import org.phoebus.channelfinder.rest.api.IInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -29,7 +28,7 @@
@Value("${channelfinder.version:4.7.0}")
private String version;

@Autowired private ElasticConfig esService;
@Autowired private ElasticsearchClient elasticsearchClient;

Check warning on line 31 in src/main/java/org/phoebus/channelfinder/rest/controller/InfoController.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this field injection and use constructor injection instead.

See more on https://sonarcloud.io/project/issues?id=ChannelFinder_ChannelFinderService&issues=AZz8hRMA5Wlikxcaaoat&open=AZz8hRMA5Wlikxcaaoat&pullRequest=205

private static final ObjectMapper objectMapper =
new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
Expand All @@ -44,8 +43,7 @@
Map<String, String> elasticInfo = new LinkedHashMap<>();
try {

ElasticsearchClient client = esService.getSearchClient();
InfoResponse response = client.info();
InfoResponse response = elasticsearchClient.info();

elasticInfo.put("status", "Connected");
elasticInfo.put("clusterName", response.clusterName());
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ elasticsearch.http.port=9200
# Elasticsearch sever. This can be used for authentication using tokens or API
# keys.
#
# For example, for token authentication, set this to ?Bearer abcd1234?, where
# ?abcd1234? is the token. For API key authentication, set this to the Base64
# For example, for token authentication, set this to "Bearer abcd1234", where
# "abcd1234" is the token. For API key authentication, set this to the Base64
# encoded version of the concatenation of the API key ID and the API key
# secret, separated by a colon. See
# https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/8.12/_other_authentication_methods.html
Expand Down
6 changes: 3 additions & 3 deletions src/test/java/org/phoebus/channelfinder/ElasticConfigIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ static void teardown(ElasticConfig elasticConfig) throws IOException {
elasticConfig.getES_TAG_INDEX()
};
for (String index : indexes) {
if (elasticConfig.getSearchClient().indices().exists(b -> b.index(index)).value()) {
elasticConfig.getSearchClient().indices().delete(b -> b.index(index));
if (elasticConfig.getElasticsearchClient().indices().exists(b -> b.index(index)).value()) {
elasticConfig.getElasticsearchClient().indices().delete(b -> b.index(index));
}
}
}
Expand All @@ -35,6 +35,6 @@ static void teardown(ElasticConfig elasticConfig) throws IOException {
* @param elasticConfig Bean with configuration
*/
static void setUp(ElasticConfig elasticConfig) {
elasticConfig.elasticIndexValidation(elasticConfig.getSearchClient());
elasticConfig.elasticIndexValidation(elasticConfig.getElasticsearchClient());
}
}
Loading