package org.elasticsearch;
import com.obs.services.*;
import com.obs.services.internal.security.BasicSecurityKey;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.cluster.metadata.RepositoryMetaData;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.settings.Settings;
import java.io.Closeable;
import java.util.Map;
import static java.util.Collections.emptyMap;
* ObsService
*/
public class ObsService implements Closeable {
private static final Logger logger = LogManager.getLogger(ObsService.class);
private volatile Map<ObsClientSettings, ObsReference> clientsCache = emptyMap();
* Client settings calculated from static configuration and settings in the keystore.
*/
private volatile Map<String, ObsClientSettings> staticClientSettings = MapBuilder.<String, ObsClientSettings>newMapBuilder().put("default", ObsClientSettings.getClientSettings(Settings.EMPTY, "default")).immutableMap();
* Client settings derived from those in {@link #} by combining them with settings
* in the {@link RepositoryMetaData}.
*/
private volatile Map<Settings, ObsClientSettings> derivedClientSettings = emptyMap();
* Attempts to retrieve a client by its repository metadata and settings from the cache.
* If the client does not exist it will be created.
*/
* Refreshes the settings for the Huawei OBS clients and clears the cache of
* existing clients. New clients will be build using these new settings. Old
* clients are usable until released. On release they will be destroyed instead
* of being returned to the cache.
*/
public synchronized void refreshAndClearCache(Map<String, ObsClientSettings> clientsSettings) {
releaseCachedClients();
this.staticClientSettings = MapBuilder.newMapBuilder(clientsSettings).immutableMap();
derivedClientSettings = emptyMap();
assert this.staticClientSettings.containsKey("default") : "always at least have 'default'";
}
public ObsReference client(RepositoryMetaData metadata) {
final ObsClientSettings clientSettings = settings(metadata);
{
final ObsReference clientReference = clientsCache.get(clientSettings);
if (clientReference != null && clientReference.tryIncRef()) {
return clientReference;
}
}
synchronized (this) {
final ObsReference existing = clientsCache.get(clientSettings);
if (existing != null && existing.tryIncRef()) {
return existing;
}
final ObsReference clientReference = new ObsReference(buildClient(clientSettings));
clientReference.incRef();
clientsCache = MapBuilder.newMapBuilder(clientsCache).put(clientSettings, clientReference).immutableMap();
return clientReference;
}
}
ObsClientSettings settings(RepositoryMetaData repositoryMetadata) {
final Settings settings = repositoryMetadata.settings();
{
final ObsClientSettings existing = derivedClientSettings.get(settings);
if (existing != null) {
return existing;
}
}
final String clientName = ObsRepository.CLIENT_NAME.get(settings);
final ObsClientSettings staticSettings = staticClientSettings.get(clientName);
if (staticSettings != null) {
synchronized (this) {
final ObsClientSettings existing = derivedClientSettings.get(settings);
if (existing != null) {
return existing;
}
final ObsClientSettings newSettings = staticSettings.getClientSettings(settings, clientName);
derivedClientSettings = MapBuilder.newMapBuilder(derivedClientSettings).put(settings, newSettings).immutableMap();
return newSettings;
}
}
throw new IllegalArgumentException("Unknown OBS client name [" + clientName + "]. Existing client configs: "
+ Strings.collectionToDelimitedString(staticClientSettings.keySet(), ","));
}
ObsClient buildClient(final ObsClientSettings clientSettings) {
final BasicSecurityKey credentials = clientSettings.basicSecurityKey;
if (credentials == null) {
return new ObsClient(new EcsObsCredentialsProvider(), buildConfiguration(clientSettings));
} else {
return new ObsClient(new BasicObsCredentialsProvider(credentials), buildConfiguration(clientSettings));
}
}
static ObsConfiguration buildConfiguration(ObsClientSettings clientSettings) {
final ObsConfiguration clientConfiguration = new ObsConfiguration();
if (Strings.hasText(clientSettings.proxyHost)) {
clientConfiguration.setHttpProxy(clientSettings.proxyHost, clientSettings.proxyPort, clientSettings.proxyUsername, clientSettings.proxyPassword);
}
if (Strings.hasLength(clientSettings.endpoint)) {
clientConfiguration.setEndPoint(clientSettings.endpoint);
}
if (Strings.hasLength(clientSettings.region)) {
clientConfiguration.setEndPoint(clientSettings.region);
}
return clientConfiguration;
}
private synchronized void releaseCachedClients() {
for (final ObsReference clientReference : clientsCache.values()) {
clientReference.decRef();
}
clientsCache = emptyMap();
derivedClientSettings = emptyMap();
}
@Override
public void close() {
releaseCachedClients();
}
}