/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.core.instancemanagement.internal;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
*
* Provide configuration segments of the configuration.json file for easier configuration handling.
*
* @author David Scholz
*/
public final class ConfigurationSegmentFactory {
private static final String PORT = "port";
private static final String HOST = "host";
private static final String IP = "ip";
private static final String ENABLED = "enabled";
private ConfigurationSegmentFactory() {
}
public static SegmentBuilder getSegmentBuilder() {
return new ConfigurationSegmentFactory().new SegmentBuilder();
}
/**
*
* Represents a config attribute.
*
* @author David Scholz
*/
public interface ConfigurationKey {
/**
*
* Get a string representation of a key mapped to a value in the configuration.json.
*
* @return the key a configuration.json mapping.
*/
String getConfigurationKey();
}
/**
*
* Represents a config segment.
*
* @author David Scholz
*/
public interface Segment {
/**
*
* Get a string representation of a name of segment in the configuration.json. A {@link Segment} can have other {@link Segment}s or
* {@link ConfigurationKey}s.
*
* @return name of a segment.
*/
String getPath();
}
/**
*
* Container for concrete {@link Segment}s to avoid object recreation (immutable).
*
* @author David Scholz
*/
private final class SegmentContainer {
private final GeneralSegment generalSegment;
private final BackgroundMonitoringSegment backgroundMonitoringSegment;
private final NetworkSegment network;
private final SshRemoteAccessSegment remoteAccess;
private final PublishingSegment publishing;
private final ComponentSettingsSegment componentSettings;
private final SshServerSegment sshServer;
SegmentContainer() {
generalSegment = new GeneralSegment();
backgroundMonitoringSegment = new BackgroundMonitoringSegment();
network = new NetworkSegment();
publishing = new PublishingSegment();
remoteAccess = new SshRemoteAccessSegment();
componentSettings = new ComponentSettingsSegment();
sshServer = new SshServerSegment();
}
public GeneralSegment getGeneralSegment() {
return generalSegment;
}
public BackgroundMonitoringSegment getBackgroundMonitoringSegment() {
return backgroundMonitoringSegment;
}
public NetworkSegment getNetworkSegment() {
return network;
}
public PublishingSegment getPublishingSegment() {
return publishing;
}
public SshRemoteAccessSegment getRemoteAccess() {
return remoteAccess;
}
public ComponentSettingsSegment getComponentSettings() {
return componentSettings;
}
public SshServerSegment getSshServer() {
return sshServer;
}
}
/**
*
* According to the builder-pattern and a fluent interface mechanism (builds {@link ConfigurationStringSegment}). Getting the correct
* implementation of {@link Segment} is done by the visitor pattern.
*
* @author David Scholz
*/
public class SegmentBuilder {
private final SegmentContainer container = new SegmentContainer();
public SegmentBuilder() {
}
/**
*
* Get general segment.
*
* @return general segment.
*/
public GeneralSegment general() {
return container.getGeneralSegment();
}
/**
*
* Get background monitoring segment.
*
* @return background monitoring segment.
*/
public BackgroundMonitoringSegment backgroundMonitoring() {
return container.getBackgroundMonitoringSegment();
}
/**
*
* Get network monitoring segment.
*
* @return network monitoring segment.
*/
public NetworkSegment network() {
return container.getNetworkSegment();
}
/**
*
* Get ssh remote access segment.
*
* @return ssh remote access segment.
*/
public SshRemoteAccessSegment sshRemoteAccess() {
return container.getRemoteAccess();
}
/**
*
* Get publishing segment.
*
* @return publishing segment.
*/
public PublishingSegment publishing() {
return container.getPublishingSegment();
}
/**
*
* Get component settings segment.
*
* @return component settings segment.
*/
public ComponentSettingsSegment componentSettings() {
return container.getComponentSettings();
}
/**
*
* Get ssh server segment.
*
* @return ssh server segment.
*/
public SshServerSegment sshServer() {
return container.getSshServer();
}
}
/**
*
* Represents the general config {@link Segment}.
*
* @author David Scholz
*/
public class GeneralSegment implements Segment {
/**
*
* Get comment {@link ConfigurationKey}.
*
* @return comment key.
*/
public ConfigurationKey comment() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "comment";
}
};
}
/**
*
* Get instance name {@link ConfigurationKey}.
*
* @return instance key.
*/
public ConfigurationKey instanceName() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "instanceName";
}
};
}
/**
*
* Get workflow host flag {@link ConfigurationKey}.
*
* @return workflow host flag key.
*/
public ConfigurationKey isWorkflowHost() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "isWorkflowHost";
}
};
}
/**
*
* Get relay flag {@link ConfigurationKey}.
*
* @return relay flag key.
*/
public ConfigurationKey isRelay() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "isRelay";
}
};
}
/**
*
* Get temp directory {@link ConfigurationKey}.
*
* @return temp directory key.
*/
public ConfigurationKey tempDirectory() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "tempDirectory";
}
};
}
/**
*
* Get deprecated input tab flag {@link ConfigurationKey}.
*
* @return deprecated input tab flag key.
*/
public ConfigurationKey enableDeprecatedInputTab() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "enableDeprecatedInputTab";
}
};
}
@Override
public String getPath() {
return "general/";
}
}
/**
*
* Represents the background monitoring config {@link Segment}.
*
* @author David Scholz
*/
public class BackgroundMonitoringSegment implements Segment {
@Override
public String getPath() {
return "backgroundMonitoring/";
}
/**
*
* Get enabled ids {@link ConfigurationKey}.
*
* @return enabled ids key.
*/
public ConfigurationKey enableIds() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "enableIds";
}
};
}
/**
*
* Get interval seconds {@link ConfigurationKey}.
*
* @return interval seconds key.
*/
public ConfigurationKey intervalSeconds() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "intervalSeconds";
}
};
}
}
/**
*
* Represents the network config {@link Segment}.
*
* @author David Scholz
*/
public class NetworkSegment implements Segment {
private final NetworkConnectionListSegment connections = new NetworkConnectionListSegment();
private final ServerPortListSegment ports = new ServerPortListSegment();
private final IpFilterSegment ipFilter = new IpFilterSegment();
@Override
public String getPath() {
return "network/";
}
/**
*
* Get connection segments.
*
* @return connection segments.
*/
public NetworkConnectionListSegment connections() {
return connections;
}
/**
*
* Get server port segments.
*
* @return server port segments.
*/
public ServerPortListSegment ports() {
return ports;
}
/**
*
* Get ip filter segment.
*
* @return ip filter segment.
*/
public IpFilterSegment ipFilter() {
return ipFilter;
}
/**
*
* Get request timeout {@link ConfigurationKey}.
*
* @return request timeout key.
*/
public ConfigurationKey requestTimeoutMsec() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "requestTimeoutMsec";
}
};
}
/**
*
* Get forwarding timeout {@link ConfigurationKey}.
*
* @return forwarding timeout key.
*/
public ConfigurationKey forwardingTimeoutMsec() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "forwardingTimeoutMsec";
}
};
}
}
/**
*
* Basis class for {@link NetworkConnectionSegment} and {@link SshConnectionSegment}.
*
* @author David Scholz
*/
private abstract class ConnectionSegment implements Segment {
private final String name;
ConnectionSegment(String name) {
this.name = name;
}
@Override
public String getPath() {
return "network/connections/" + name;
}
abstract ConfigurationKey host();
abstract ConfigurationKey port();
}
/**
*
* Represents the connections config {@link Segment}.
*
* @author David Scholz
*/
public class NetworkConnectionListSegment implements Segment {
private Map<String, NetworkConnectionSegment> connectionNameToConnectionSegmentMap = new ConcurrentHashMap<>();
@Override
public String getPath() {
return "network/connections";
}
/**
*
* Gets existing or create a new {@link NetworkConnectionSegment}.
*
* @param name the connection name.
* @return the desired {@link NetworkConnectionSegment}.
*/
public NetworkConnectionSegment getOrCreateConnection(String name) {
synchronized (connectionNameToConnectionSegmentMap) {
if (connectionNameToConnectionSegmentMap.containsKey(name)) {
return connectionNameToConnectionSegmentMap.get(name);
} else {
NetworkConnectionSegment segment = new NetworkConnectionSegment(name);
connectionNameToConnectionSegmentMap.put(name, segment);
return segment;
}
}
}
/**
*
* Checks wether desired connection is already present in the current configuration.
*
* @param name the connection name.
* @return <code>true</code> if connection is already present in the config file, <code>false</code> else.
*/
public boolean isConnectionPresent(String name) {
synchronized (connectionNameToConnectionSegmentMap) {
return connectionNameToConnectionSegmentMap.containsKey(name);
}
}
}
/**
*
* Represents a new connection {@link Segment} in the config file.
*
* @author David Scholz
*/
public class NetworkConnectionSegment extends ConnectionSegment {
public NetworkConnectionSegment(String name) {
super(name);
}
@Override
public ConfigurationKey host() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return HOST;
}
};
}
@Override
public ConfigurationKey port() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return PORT;
}
};
}
/**
*
* Get connectOnStartup {@link ConfigurationKey}.
*
* @return connectonOnStartup key.
*/
public ConfigurationKey connectOnStartup() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "connectOnStartup";
}
};
}
/**
*
* Get autoRetryInitialDelay {@link ConfigurationKey}.
*
* @return autoRetryInitialDelay key.
*/
public ConfigurationKey autoRetryInitialDelay() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "autoRetryInitialDelay";
}
};
}
/**
*
* Get autoRetryDelayMutliplier {@link ConfigurationKey}.
*
* @return autoRetryDelayMutliplier key.
*/
public ConfigurationKey autoRetryDelayMultiplier() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "autoRetryDelayMultiplier";
}
};
}
/**
*
* Get the autoRetryMaximumDelay {@link ConfigurationKey}.
*
* @return autoRetryMaximumDelay key.
*/
public ConfigurationKey autoRetryMaximumDelay() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "autoRetryMaximumDelay";
}
};
}
}
/**
*
* Represents the defined ports (ip + port).
*
* @author David Scholz
*/
public class ServerPortListSegment implements Segment {
private Map<String, ServerPortSegment> portSegmentNameToServerPortSegmentMap = new HashMap<>();
public ServerPortListSegment() {
}
@Override
public String getPath() {
return "network/serverPorts";
}
/**
*
* Gets existing or create a new {@link ServerPortSegment}.
*
* @param name the port name.
* @return the desired {@link ServerPortSegment}.
*/
public ServerPortSegment getOrCreateServerPort(String name) {
synchronized (portSegmentNameToServerPortSegmentMap) {
if (portSegmentNameToServerPortSegmentMap.containsKey(name)) {
return portSegmentNameToServerPortSegmentMap.get(name);
} else {
ServerPortSegment segment = new ServerPortSegment(name);
portSegmentNameToServerPortSegmentMap.put(name, segment);
return segment;
}
}
}
}
/**
*
* Represents one port in the {@link ServerPortListSegment}.
*
* @author David Scholz
*/
public class ServerPortSegment implements Segment {
private final String name;
public ServerPortSegment(String name) {
this.name = name;
}
@Override
public String getPath() {
return "network/serverPorts/" + name;
}
/**
*
* Get port {@link ConfigurationKey}.
*
* @return port key.
*/
public ConfigurationKey port() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return PORT;
}
};
}
/**
*
* Get ip {@link ConfigurationKey}.
*
* @return ip key.
*/
public ConfigurationKey ip() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return IP;
}
};
}
}
/**
*
* Represents the ip filter segment.
*
* @author David Scholz
*/
public class IpFilterSegment implements Segment {
@Override
public String getPath() {
return "network/ipFilter";
}
/**
*
* Get enabled {@link ConfigurationKey}.
*
* @return enabled key.
*/
public ConfigurationKey enabled() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return ENABLED;
}
};
}
/**
*
* Get allowedIps {@link ConfigurationKey}.
*
* @return allowedIps key.
*/
public ConfigurationKey allowedIps() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "allowedIPs";
}
};
}
}
/**
*
* SshRemoteAccess field in the config.
*
* @author David Scholz
*/
public class SshRemoteAccessSegment implements Segment {
private final SshConnectionListSegment sshConnections = new SshConnectionListSegment();
@Override
public String getPath() {
return "sshRemoteAccess/";
}
/**
*
* Get exisiting {@link SshConnectionSegment}s.
*
* @return all existing {@link SshConnectionSegment}s.
*/
public SshConnectionListSegment sshConnections() {
return sshConnections;
}
}
/**
*
* Ssh connection list in the config.
*
* @author David Scholz
*/
public class SshConnectionListSegment implements Segment {
private Map<String, SshConnectionSegment> sshConnectionNameToSegmentMap = new HashMap<>();
@Override
public String getPath() {
return "sshRemoteAccess/sshConnections";
}
/**
*
* Gets existing or create a new {@link SshConnectionSegment}.
*
* @param connectionName the connection name.
* @return the desired {@link SshConnectionSegment}.
*/
public SshConnectionSegment getOrCreateSshConnection(String connectionName) {
synchronized (sshConnectionNameToSegmentMap) {
if (sshConnectionNameToSegmentMap.containsKey(connectionName)) {
return sshConnectionNameToSegmentMap.get(connectionName);
} else {
SshConnectionSegment segment = new SshConnectionSegment(connectionName);
sshConnectionNameToSegmentMap.put(connectionName, segment);
return segment;
}
}
}
}
/**
*
* Represents a ssh connection in the {@link SshConnectionListSegment}.
*
* @author David Scholz
*/
public class SshConnectionSegment implements Segment {
private final String name;
public SshConnectionSegment(String name) {
this.name = name;
}
@Override
public String getPath() {
return "sshRemoteAccess/sshConnections/" + name;
}
/**
*
* Get the display name {@link ConfigurationKey}.
*
* @return display name key.
*/
public ConfigurationKey displayName() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "displayName";
}
};
}
/**
*
* Get the host {@link ConfigurationKey}.
*
* @return host key.
*/
public ConfigurationKey host() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return HOST;
}
};
}
/**
*
* Get the port {@link ConfigurationKey}.
*
* @return port key.
*/
public ConfigurationKey port() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return PORT;
}
};
}
/**
*
* Get the login name {@link ConfigurationKey}.
*
* @return login name key.
*/
public ConfigurationKey loginName() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "loginName";
}
};
}
}
/**
*
* The published components of the instance.
*
* @author David Scholz
*/
public class PublishingSegment implements Segment {
@Override
public String getPath() {
return "publishing/";
}
/**
*
* Get the components {@link ConfigurationKey}.
*
* @return components key.
*/
public ConfigurationKey components() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "components";
}
};
}
}
/**
*
* The component settings.
*
* @author David Scholz
*/
public class ComponentSettingsSegment implements Segment {
private final ClusterComponentSettingsSegment clusterComponent = new ClusterComponentSettingsSegment();
@Override
public String getPath() {
return "componentSettings/";
}
public ClusterComponentSettingsSegment getClusterComponentSettings() {
return clusterComponent;
}
}
/**
*
* Settings of the cluster component.
*
* @author David Scholz
*/
public class ClusterComponentSettingsSegment implements Segment {
@Override
public String getPath() {
return "componentSettings/de.rcenvironment.cluster";
}
/**
*
* Get the maxChannels {@link ConfigurationKey}.
*
* @return maxChannels key.
*/
public ConfigurationKey maxChannels() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "maxChannels";
}
};
}
}
/**
*
* The ssh server segment.
*
* @author David Scholz
*/
public class SshServerSegment implements Segment {
private final SshAccountListSegment accounts = new SshAccountListSegment();
private final SshAccountRoleListSegment roles = new SshAccountRoleListSegment();
@Override
public String getPath() {
return "sshServer/";
}
public SshAccountListSegment getSshAccounts() {
return accounts;
}
public SshAccountRoleListSegment getSshAccountRoles() {
return roles;
}
/**
*
* Get the enabled {@link ConfigurationKey}.
*
* @return enabled key.
*/
public ConfigurationKey enabled() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return ENABLED;
}
};
}
/**
*
* Get the ip {@link ConfigurationKey}.
*
* @return ip key.
*/
public ConfigurationKey ip() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return IP;
}
};
}
/**
*
* Get the port {@link ConfigurationKey}.
*
* @return port key.
*/
public ConfigurationKey port() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return PORT;
}
};
}
}
/**
*
* All ssh accounts in {@link SshServerSegment}.
*
* @author David Scholz
*/
public class SshAccountListSegment implements Segment {
private final Map<String, SshAccountSegment> sshAccountNameToSshAccountSegmentMap = new HashMap<>();
@Override
public String getPath() {
return "sshServer/accounts";
}
/**
*
* Gets existing or create a new {@link SshAccountSegment}.
*
* @param name the account name.
* @return the desired {@link SshAccountSegment}.
*/
public SshAccountSegment getOrCreateSshAccount(String name) {
synchronized (sshAccountNameToSshAccountSegmentMap) {
if (sshAccountNameToSshAccountSegmentMap.containsKey(name)) {
return sshAccountNameToSshAccountSegmentMap.get(name);
} else {
SshAccountSegment segment = new SshAccountSegment(name);
sshAccountNameToSshAccountSegmentMap.put(name, segment);
return segment;
}
}
}
}
/**
*
* Represents a ssh account.
*
* @author David Scholz
*/
public class SshAccountSegment implements Segment {
private final String name;
public SshAccountSegment(String name) {
this.name = name;
}
@Override
public String getPath() {
return "sshServer/accounts/" + name;
}
/**
*
* Get the role {@link ConfigurationKey}.
*
* @return role key.
*/
public ConfigurationKey role() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "role";
}
};
}
/**
*
* Get the password hash {@link ConfigurationKey}.
*
* @return password hash key.
*/
public ConfigurationKey passwordHash() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "passwordHash";
}
};
}
/**
*
* Get the enabled {@link ConfigurationKey}.
*
* @return enabled key.
*/
public ConfigurationKey enabled() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "enabled";
}
};
}
}
/**
*
* All ssh roles.
*
* @author David Scholz
*/
public class SshAccountRoleListSegment implements Segment {
private final Map<String, SshAccountRoleSegment> sshRoleNameToSegmentMap = new HashMap<>();
@Override
public String getPath() {
return "sshServer/roles";
}
/**
*
* Gets existing or create a new {@link SshAccountRoleSegment}.
*
* @param name the account name.
* @return the desired {@link SshAccountRoleSegment}.
*/
public SshAccountRoleSegment getOrCreateSshRole(String name) {
synchronized (sshRoleNameToSegmentMap) {
if (sshRoleNameToSegmentMap.containsKey(name)) {
return sshRoleNameToSegmentMap.get(name);
} else {
SshAccountRoleSegment segment = new SshAccountRoleSegment(name);
sshRoleNameToSegmentMap.put(name, segment);
return segment;
}
}
}
}
/**
*
* A ssh role.
*
* @author David Scholz
*/
public class SshAccountRoleSegment implements Segment {
private final String name;
public SshAccountRoleSegment(String name) {
this.name = name;
}
@Override
public String getPath() {
return "sshServer/roles/" + name;
}
public ConfigurationKey getAllowedCommandPatterns() {
return new ConfigurationKey() {
@Override
public String getConfigurationKey() {
return "allowedCommandPatterns";
}
};
}
}
}