Skip to content
Open
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
300 changes: 252 additions & 48 deletions tc-server/src/main/java/com/tc/config/ServerConfigurationManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
*/
package com.tc.config;


import com.tc.classloader.ServiceLocator;
import com.tc.productinfo.ProductInfo;
import com.tc.properties.TCPropertiesImpl;
Expand All @@ -28,34 +27,42 @@
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import org.terracotta.configuration.ConfigurationException;
import com.tc.text.PrettyPrintable;
import java.io.Closeable;
import java.io.File;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terracotta.configuration.FailoverBehavior;
import org.terracotta.entity.ServiceProviderConfiguration;

public class ServerConfigurationManager implements PrettyPrintable {

private final ConfigurationProvider configurationProvider;
private final Logger LOGGER = LoggerFactory.getLogger(ServerConfigurationManager.class);
private final CachingConfigurationProvider configurationProvider;
private ServerConfiguration thisServer;
private final ServiceLocator serviceLocator;
private final List<String> startUpArgs;
private final ProductInfo productInfo;

private Configuration configuration;
private ServerConfiguration serverConfiguration;

public ServerConfigurationManager(ConfigurationProvider configurationProvider,
ServiceLocator classLoader,
List<String> startUpArgs) {
ServiceLocator classLoader,
List<String> startUpArgs) {
Objects.requireNonNull(configurationProvider);
Objects.requireNonNull(classLoader);
Objects.requireNonNull(startUpArgs);

this.configurationProvider = configurationProvider;
this.configurationProvider = new CachingConfigurationProvider(configurationProvider);
this.serviceLocator = classLoader;
this.startUpArgs = startUpArgs;
this.productInfo = generateProductInfo(serviceLocator);
Expand All @@ -70,18 +77,19 @@ public ProductInfo getProductInfo() {
}

public void initialize() throws ConfigurationException {
this.configurationProvider.initialize(this.startUpArgs);

this.configuration = configurationProvider.getConfiguration();
if (this.configuration == null) {
throw new ConfigurationException("unable to determine server configuration");
}
try (LockedConfiguration configuration = this.configurationProvider.lockAndInitialize(this.startUpArgs)) {
if (configuration == null) {
throw new ConfigurationException("unable to determine server configuration");
}

ServerConfiguration base = configuration.getServerConfiguration();
if (base == null) {
throw new ConfigurationException("unable to determine server configuration");
}
thisServer = new StableServerConfiguration(base);

this.serverConfiguration = this.configuration.getServerConfiguration();
if (this.serverConfiguration == null) {
throw new ConfigurationException("unable to determine server configuration");
processTcProperties(configuration.getTcProperties());
}
processTcProperties(configuration.getTcProperties());
}

public void close() {
Expand All @@ -93,69 +101,265 @@ public String[] getProcessArguments() {
}

public ServerConfiguration getServerConfiguration() {
return this.serverConfiguration;
return thisServer;
}

public GroupConfiguration getGroupConfiguration() {
List<ServerConfiguration> serverConfigurationMap = configuration.getServerConfigurations();
return new GroupConfiguration(serverConfigurationMap, this.serverConfiguration.getName());
List<ServerConfiguration> serverConfigurationMap = configurationProvider.getStableServerConfigurations();
return new GroupConfiguration(serverConfigurationMap, getServerConfiguration().getName());
}

public InputStream rawConfigFile() {
String text = configuration.getRawConfiguration();
return new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));
try (LockedConfiguration config = configurationProvider.getLockedConfiguration()) {
String text = config.getRawConfiguration();
return new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));
}
}

public String rawConfigString() {
return configuration.getRawConfiguration();
try (LockedConfiguration config = configurationProvider.getLockedConfiguration()) {
return config.getRawConfiguration();
}
}

public String[] allCurrentlyKnownServers() {
return getGroupConfiguration().getMembers();
}


public boolean isConsistentStartup() {
try (LockedConfiguration config = configurationProvider.getLockedConfiguration()) {
return config.isConsistentStartup();
}
}

public boolean isPartialConfiguration() {
return this.configuration.isPartialConfiguration();
try (LockedConfiguration config = configurationProvider.getLockedConfiguration()) {
return config.isPartialConfiguration();
}
}

public FailoverBehavior getFailoverPriority() {
try (LockedConfiguration config = configurationProvider.getLockedConfiguration()) {
return config.getFailoverPriority();
}
}

public <T> List<T> getExtendedConfiguration(Class<T> type) {
try (LockedConfiguration config = configurationProvider.getLockedConfiguration()) {
return config.getExtendedConfiguration(type);
}
}

public List<ServiceProviderConfiguration> getServiceConfigurations() {
try (LockedConfiguration config = configurationProvider.getLockedConfiguration()) {
return config.getServiceConfigurations();
}
}

public ServiceLocator getServiceLocator() {
return this.serviceLocator;
}

public Configuration getConfiguration() {
return configuration;
}

public ConfigurationProvider getConfigurationProvider() {
return configurationProvider;
}

private Map<String, ServerConfiguration> getServerConfigurationMap(Collection<ServerConfiguration> servers) {
Map<String, ServerConfiguration> serverConfigurationMap = new HashMap<>();
for (ServerConfiguration server : servers) {
if (server.getName() != null) {
serverConfigurationMap.put(server.getName(), server);
}
}
return serverConfigurationMap;
return configurationProvider.delegateProvider;
}

private static void processTcProperties(Properties tcProperties) {
Map<String, String> propMap = new HashMap<>();

if (tcProperties != null) {
tcProperties.forEach((k, v)->propMap.put(k.toString().trim(), v.toString().trim()));
tcProperties.forEach((k, v) -> propMap.put(k.toString().trim(), v.toString().trim()));
}

TCPropertiesImpl.getProperties().overwriteTcPropertiesFromConfig(propMap);
}

@Override
public Map<String, ?> getStateMap() {
if (configuration instanceof PrettyPrintable) {
return ((PrettyPrintable)configuration).getStateMap();
} else {
return Collections.emptyMap();
try (LockedConfiguration config = configurationProvider.getLockedConfiguration()) {
if (config instanceof PrettyPrintable) {
return ((PrettyPrintable) config).getStateMap();
} else {
return Collections.emptyMap();
}
}
}

private static class LockedConfiguration implements Configuration, Closeable {
private final Configuration delegate;
private final Lock close;

public LockedConfiguration(Configuration delegate, Lock close) {
this.delegate = delegate;
this.close = close;
}

public void close() {
close.unlock();
}

@Override
public ServerConfiguration getServerConfiguration() throws ConfigurationException {
return delegate.getServerConfiguration();
}

@Override
public List<ServerConfiguration> getServerConfigurations() {
return delegate.getServerConfigurations();
}

@Override
public List<ServiceProviderConfiguration> getServiceConfigurations() {
return delegate.getServiceConfigurations();
}

@Override
public <T> List<T> getExtendedConfiguration(Class<T> type) {
return delegate.getExtendedConfiguration(type);
}

@Override
public String getRawConfiguration() {
return delegate.getRawConfiguration();
}

@Override
public Properties getTcProperties() {
return delegate.getTcProperties();
}

@Override
public FailoverBehavior getFailoverPriority() {
return delegate.getFailoverPriority();
}

@Override
public boolean isConsistentStartup() {
return delegate.isConsistentStartup();
}

@Override
public boolean isPartialConfiguration() {
return delegate.isPartialConfiguration();
}
}

private static final class CachingConfigurationProvider implements ConfigurationProvider {

private final ConfigurationProvider delegateProvider;
private final Lock lock = new ReentrantLock();

public CachingConfigurationProvider(ConfigurationProvider delegateProvider) {
this.delegateProvider = delegateProvider;
}

List<ServerConfiguration> getStableServerConfigurations() {
lock.lock();
try {
return delegateProvider.getConfiguration().getServerConfigurations().stream().map(StableServerConfiguration::new).collect(Collectors.toList());
} finally {
lock.unlock();
}
}

LockedConfiguration lockAndInitialize(List<String> configurationParams) throws ConfigurationException {
lock.lock();
initialize(configurationParams);
return new LockedConfiguration(delegateProvider.getConfiguration(), lock);
}

@Override
public void initialize(List<String> configurationParams) throws ConfigurationException {
delegateProvider.initialize(configurationParams);
}

public LockedConfiguration getLockedConfiguration() {
lock.lock();
return new LockedConfiguration(delegateProvider.getConfiguration(), lock);
}

@Override
public Configuration getConfiguration() {
lock.lock();
try {
return delegateProvider.getConfiguration();
} finally {
lock.unlock();
}
}

@Override
public String getConfigurationParamsDescription() {
return delegateProvider.getConfigurationParamsDescription();
}

@Override
public void close() {
delegateProvider.close();
}

@Override
public byte[] getSyncData() {
return delegateProvider.getSyncData();
}

@Override
public void sync(byte[] syncData) {
lock.lock();
try {
delegateProvider.sync(syncData);
} finally {
lock.unlock();
}
}
}

private static class StableServerConfiguration implements ServerConfiguration {

private final InetSocketAddress tsaPort;
private final InetSocketAddress groupPort;
private final String host;
private final String name;
private final int reconnectWindow;
private final File logDir;

public StableServerConfiguration(ServerConfiguration base) {
tsaPort = base.getTsaPort();
groupPort = base.getGroupPort();
host = base.getHost();
name = base.getName();
reconnectWindow = base.getClientReconnectWindow();
logDir = base.getLogsLocation();
}

@Override
public InetSocketAddress getTsaPort() {
return tsaPort;
}

@Override
public InetSocketAddress getGroupPort() {
return groupPort;
}

@Override
public String getHost() {
return host;
}

@Override
public String getName() {
return name;
}

@Override
public int getClientReconnectWindow() {
return reconnectWindow;
}

@Override
public File getLogsLocation() {
return logDir;
}
}
}
Loading