/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.search.elasticsearch.internal.connection;
import com.liferay.portal.configuration.metatype.bnd.util.ConfigurableUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.Props;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.SetUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.SystemProperties;
import com.liferay.portal.search.elasticsearch.configuration.ElasticsearchConfiguration;
import com.liferay.portal.search.elasticsearch.connection.ElasticsearchConnection;
import com.liferay.portal.search.elasticsearch.connection.OperationMode;
import com.liferay.portal.search.elasticsearch.index.IndexFactory;
import com.liferay.portal.search.elasticsearch.settings.SettingsContributor;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.plugins.Plugin;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.component.annotations.ReferencePolicyOption;
/**
* @author Michael C. Han
*/
@Component(
configurationPid = "com.liferay.portal.search.elasticsearch.configuration.ElasticsearchConfiguration",
immediate = true, property = {"operation.mode=REMOTE"},
service = ElasticsearchConnection.class
)
public class RemoteElasticsearchConnection extends BaseElasticsearchConnection {
@Override
public OperationMode getOperationMode() {
return OperationMode.REMOTE;
}
@Override
@Reference(unbind = "-")
public void setIndexFactory(IndexFactory indexFactory) {
super.setIndexFactory(indexFactory);
}
public void setTransportAddresses(Set<String> transportAddresses) {
_transportAddresses = transportAddresses;
}
@Activate
protected void activate(Map<String, Object> properties) {
replaceElasticsearchConfiguration(properties);
}
@Override
@Reference(
cardinality = ReferenceCardinality.MULTIPLE,
policy = ReferencePolicy.DYNAMIC,
policyOption = ReferencePolicyOption.GREEDY,
target = "(operation.mode=REMOTE)"
)
protected void addSettingsContributor(
SettingsContributor settingsContributor) {
super.addSettingsContributor(settingsContributor);
}
protected void addTransportAddress(
TransportClient transportClient, String transportAddress)
throws UnknownHostException {
String[] transportAddressParts = StringUtil.split(
transportAddress, StringPool.COLON);
String host = transportAddressParts[0];
int port = GetterUtil.getInteger(transportAddressParts[1]);
InetAddress inetAddress = InetAddress.getByName(host);
transportClient.addTransportAddress(
new InetSocketTransportAddress(inetAddress, port));
}
@Override
protected Client createClient() {
if (_transportAddresses.isEmpty()) {
throw new IllegalStateException(
"There must be at least one transport address");
}
TransportClient transportClient = createTransportClient();
for (String transportAddress : _transportAddresses) {
try {
addTransportAddress(transportClient, transportAddress);
}
catch (Exception e) {
if (_log.isWarnEnabled()) {
_log.warn(
"Unable to add transport address " + transportAddress,
e);
}
}
}
return transportClient;
}
protected TransportClient createTransportClient() {
TransportClient.Builder transportClientBuilder =
TransportClient.builder();
transportClientBuilder.settings(settingsBuilder);
for (String plugin : transportClientPlugins) {
transportClientBuilder.addPlugin(getPluginClass(plugin));
}
return transportClientBuilder.build();
}
@Deactivate
protected void deactivate(Map<String, Object> properties) {
close();
}
@SuppressWarnings("unchecked")
protected Class<? extends Plugin> getPluginClass(String plugin) {
try {
return (Class<? extends Plugin>)Class.forName(plugin);
}
catch (ClassNotFoundException cnfe) {
throw new IllegalArgumentException(
"Elasticsearch plugin class not found: " + plugin, cnfe);
}
}
@Override
protected void loadRequiredDefaultConfigurations() {
settingsBuilder.put(
"client.transport.ignore_cluster_name",
elasticsearchConfiguration.clientTransportIgnoreClusterName());
settingsBuilder.put(
"client.transport.nodes_sampler_interval",
elasticsearchConfiguration.clientTransportNodesSamplerInterval());
settingsBuilder.put(
"client.transport.sniff",
elasticsearchConfiguration.clientTransportSniff());
settingsBuilder.put(
"cluster.name", elasticsearchConfiguration.clusterName());
settingsBuilder.put("http.enabled", false);
settingsBuilder.put("node.client", true);
settingsBuilder.put("node.data", false);
settingsBuilder.put(
"path.logs", props.get(PropsKeys.LIFERAY_HOME) + "/logs");
settingsBuilder.put(
"path.work", SystemProperties.get(SystemProperties.TMP_DIR));
}
@Modified
protected synchronized void modified(Map<String, Object> properties) {
replaceElasticsearchConfiguration(properties);
if (isConnected()) {
close();
connect();
}
}
@Override
protected void removeSettingsContributor(
SettingsContributor settingsContributor) {
super.removeSettingsContributor(settingsContributor);
}
protected void replaceElasticsearchConfiguration(
Map<String, Object> properties) {
elasticsearchConfiguration = ConfigurableUtil.createConfigurable(
ElasticsearchConfiguration.class, properties);
String[] transportAddresses =
elasticsearchConfiguration.transportAddresses();
setTransportAddresses(SetUtil.fromArray(transportAddresses));
}
@Reference
protected Props props;
private static final Log _log = LogFactoryUtil.getLog(
RemoteElasticsearchConnection.class);
private Set<String> _transportAddresses = new HashSet<>();
}