Skip to content

Commit

Permalink
Simplify and synchronized the way config is updated or checked
Browse files Browse the repository at this point in the history
  • Loading branch information
myronkscott committed Oct 17, 2024
1 parent 0786582 commit 5f8c103
Showing 1 changed file with 147 additions and 41 deletions.
188 changes: 147 additions & 41 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,39 @@
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.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;

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 +74,24 @@ 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");
}
Lock lock = this.configurationProvider.lockAndInitialize(this.startUpArgs);

this.serverConfiguration = this.configuration.getServerConfiguration();
if (this.serverConfiguration == null) {
throw new ConfigurationException("unable to determine server configuration");
try {
Configuration configuration = configurationProvider.getConfiguration();
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);

processTcProperties(configuration.getTcProperties());
} finally {
lock.unlock();
}
processTcProperties(configuration.getTcProperties());
}

public void close() {
Expand All @@ -93,69 +103,165 @@ 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 = getConfiguration().getServerConfigurations().stream().map(StableServerConfiguration::new).collect(Collectors.toList());
return new GroupConfiguration(serverConfigurationMap, getServerConfiguration().getName());
}

public InputStream rawConfigFile() {
String text = configuration.getRawConfiguration();
String text = getConfiguration().getRawConfiguration();
return new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));
}

public String rawConfigString() {
return configuration.getRawConfiguration();
return getConfiguration().getRawConfiguration();
}

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

public boolean isPartialConfiguration() {
return this.configuration.isPartialConfiguration();
return getConfiguration().isPartialConfiguration();
}

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

public Configuration getConfiguration() {
return configuration;
return configurationProvider.getConfiguration();
}

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();
Configuration config = getConfiguration();
if (config instanceof PrettyPrintable) {
return ((PrettyPrintable) config).getStateMap();
} else {
return Collections.emptyMap();
}
}

private static final class CachingConfigurationProvider implements ConfigurationProvider {

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

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

Lock lockAndInitialize(List<String> configurationParams) throws ConfigurationException {
lock.lock();
initialize(configurationParams);
return lock;
}

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

@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;
}
}
}

0 comments on commit 5f8c103

Please sign in to comment.