Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Factorize code of ServerEvaluationStrategy classes, to use the Custom strategy as the basis of other strategies #5366

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
7750516
Pull-up the local docker port management (use exposed ports)
davidfestal Jun 12, 2017
c9a2c42
Make all the strategies extend `CustomEvaluationStrategy`
davidfestal Jun 12, 2017
9d67488
Add a `workspaceIdWithoutPrefix` macro and use it for `single-port`
davidfestal Jun 13, 2017
6efc793
Add the `isDevMachine` to allow conditions in the ST template.
davidfestal Jun 13, 2017
4c2b5cc
Small fixes after comments from @fbenoit
davidfestal Jun 13, 2017
58c5609
Fix unnecessary space pointed out by @sunix
davidfestal Jun 13, 2017
c5a99e6
Remove unnecessary `else` as suggested by @sunix
davidfestal Jun 13, 2017
8addae5
Keep the method signatures compatible with the `condenvy` strategy
davidfestal Jun 13, 2017
0e87138
Align names of parameters of constructors (requested by @garagatyi)
davidfestal Jun 14, 2017
97cc631
Add a default implementation to avoid breaking the Codenvy build
davidfestal Jun 14, 2017
d2c538a
Also rename the attributes
davidfestal Jun 14, 2017
0644a37
Use a constant for the `workspace` prefix string
davidfestal Jun 14, 2017
1325df8
Fix formatting as requested by @sunix
davidfestal Jun 14, 2017
82ed118
Use a constant for the `isDevMachine` macro name
davidfestal Jun 14, 2017
bd07aa8
Add unit tests for `workspaceIdWithoutPrefixè and `isDevMachine` macros
davidfestal Jun 14, 2017
385a108
Another requested formatting fix
davidfestal Jun 14, 2017
5bf33e1
Make new tests clearer
davidfestal Jun 14, 2017
ad629e3
yet another formatting request
davidfestal Jun 14, 2017
1154f57
Respect the original order of imports
davidfestal Jun 14, 2017
b350718
remove unnecessary `toString()`
davidfestal Jun 14, 2017
769ef86
use a lowercase `S` in the `server-` prefix
davidfestal Jun 15, 2017
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
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
* @author Florent Benoit
* @see ServerEvaluationStrategy
*/
public class CustomServerEvaluationStrategy extends DefaultServerEvaluationStrategy {
public class CustomServerEvaluationStrategy extends ServerEvaluationStrategy {

/**
* Regexp to extract port (under the form 22/tcp or 4401/tcp, etc.) from label references
Expand All @@ -57,6 +57,32 @@ public class CustomServerEvaluationStrategy extends DefaultServerEvaluationStrat
*/
public static final String CHE_MACHINE_NAME_PROPERTY = "CHE_MACHINE_NAME=";

/**
* Name of the property to get the property that indicates if the machine is the dev machine
*/
public static final String CHE_IS_DEV_MACHINE_PROPERTY = "CHE_IS_DEV_MACHINE=";

/**
* Prefix added in front of the generated name to build the workspaceId
*/
public static final String CHE_WORKSPACE_ID_PREFIX = "workspace";


/**
* name of the macro that indicates if the machine is the dev machine
*/
public static final String IS_DEV_MACHINE_MACRO = "isDevMachine";

/**
* Used to store the address set by property {@code che.docker.ip}, if applicable.
*/
protected String cheDockerIp;

/**
* Used to store the address set by property {@code che.docker.ip.external}. if applicable.
*/
protected String cheDockerIpExternal;

/**
* The current port of che.
*/
Expand All @@ -72,7 +98,18 @@ public class CustomServerEvaluationStrategy extends DefaultServerEvaluationStrat
*/
private String cheDockerCustomExternalTemplate;


/**
* Option to enable the use of the container address, when searching for addresses.
*/
private boolean useContainerAddress;


/**
* Option to tell if an exception should be thrown when the host defined in the `externalAddress` isn't known
* and cannot be converted into a valid IP.
*/
private boolean throwOnUnknownHost = true;

/**
* Default constructor
*/
Expand All @@ -82,12 +119,49 @@ public CustomServerEvaluationStrategy(@Nullable @Named("che.docker.ip") String c
@Nullable @Named("che.docker.server_evaluation_strategy.custom.template") String cheDockerCustomExternalTemplate,
@Nullable @Named("che.docker.server_evaluation_strategy.custom.external.protocol") String cheDockerCustomExternalProtocol,
@Named("che.port") String chePort) {
super(cheDockerIp, cheDockerIpExternal);
this(cheDockerIp, cheDockerIpExternal, cheDockerCustomExternalTemplate, cheDockerCustomExternalProtocol, chePort, false);
}

/**
* Constructor to be called by derived strategies
*/
public CustomServerEvaluationStrategy(@Nullable @Named("che.docker.ip") String cheDockerIp,
@Nullable @Named("che.docker.ip.external") String cheDockerIpExternal,
@Nullable @Named("che.docker.server_evaluation_strategy.custom.template") String cheDockerCustomExternalTemplate,
@Nullable @Named("che.docker.server_evaluation_strategy.custom.external.protocol") String cheDockerCustomExternalProtocol,
@Named("che.port") String chePort,
boolean useContainerAddress) {
this.cheDockerIp = cheDockerIp;
this.cheDockerIpExternal = cheDockerIpExternal;
this.chePort = chePort;
this.cheDockerCustomExternalTemplate = cheDockerCustomExternalTemplate;
this.cheDockerCustomExternalProtocol = cheDockerCustomExternalProtocol;
this.useContainerAddress = useContainerAddress;
}

@Override
protected Map<String, String> getInternalAddressesAndPorts(ContainerInfo containerInfo, String internalHost) {
final String internalAddressContainer = containerInfo.getNetworkSettings().getIpAddress();

final String internalAddress;

if (useContainerAddress) {
internalAddress = !isNullOrEmpty(internalAddressContainer) ?
internalAddressContainer :
internalHost;
} else {
internalAddress =
cheDockerIp != null ?
cheDockerIp :
internalHost;
}

boolean useExposedPorts = useContainerAddress && internalAddress != internalHost;

return getExposedPortsToAddressPorts(internalAddress, containerInfo.getNetworkSettings().getPorts(), useExposedPorts);
}


/**
* Override the host for all ports by using the external template.
*/
Expand All @@ -100,6 +174,10 @@ protected Map<String, String> getExternalAddressesAndPorts(ContainerInfo contain
// get current ports
Map<String, List<PortBinding>> ports = containerInfo.getNetworkSettings().getPorts();

if (isNullOrEmpty(cheDockerCustomExternalTemplate)) {
return getExposedPortsToAddressPorts(renderingEvaluation.getExternalAddress(), ports, false);
}

return ports.keySet().stream()
.collect(Collectors.toMap(portKey -> portKey,
portKey -> renderingEvaluation.render(cheDockerCustomExternalTemplate, portKey)));
Expand Down Expand Up @@ -180,6 +258,11 @@ public interface RenderingEvaluation {
* @return the rendering of the template
*/
String render(String template, String port);

/**
* Gets default external address.
*/
String getExternalAddress();
}

/**
Expand All @@ -202,12 +285,20 @@ protected OnlineRenderingEvaluation withInternalHost(String internalHost) {
}

@Override
protected String getExternalAddress() {
return externalAddressProperty != null ?
externalAddressProperty :
!isNullOrEmpty(gatewayAddressContainer) ?
gatewayAddressContainer :
this.internalHost;
public String getExternalAddress() {
if (useContainerAddress) {
return cheDockerIpExternal != null ?
cheDockerIpExternal :
!isNullOrEmpty(gatewayAddressContainer) ?
gatewayAddressContainer :
this.internalHost;
}

return cheDockerIpExternal != null ?
cheDockerIpExternal :
cheDockerIp != null ?
cheDockerIp :
this.internalHost;
}
}

Expand Down Expand Up @@ -292,7 +383,7 @@ protected void initPortMapping() {
// add to this map only port without a known ref name
Map<String, String> portsToUnkownRefName =
exposedPorts.stream().filter((port) -> !portsToKnownRefName.containsKey(port))
.collect(Collectors.toMap(p -> p, p -> "Server-" + p.replace('/', '-')));
.collect(Collectors.toMap(p -> p, p -> "server-" + p.replace('/', '-')));

// list of all ports with refName (known/unknown)
this.portsToRefName = new HashMap(portsToKnownRefName);
Expand All @@ -302,9 +393,9 @@ protected void initPortMapping() {
/**
* Gets default external address.
*/
protected String getExternalAddress() {
return externalAddressProperty != null ?
externalAddressProperty : internalAddressProperty;
public String getExternalAddress() {
return cheDockerIpExternal != null ?
cheDockerIpExternal : cheDockerIp;
}

/**
Expand All @@ -313,14 +404,16 @@ protected String getExternalAddress() {
protected void populateGlobalProperties() {
String externalAddress = getExternalAddress();
String externalIP = getExternalIp(externalAddress);
globalPropertiesMap.put("internalIp", internalAddressProperty);
globalPropertiesMap.put("internalIp", cheDockerIp);
globalPropertiesMap.put("externalAddress", externalAddress);
globalPropertiesMap.put("externalIP", externalIP);
globalPropertiesMap.put("workspaceId", getWorkspaceId());
globalPropertiesMap.put("workspaceIdWithoutPrefix", getWorkspaceId().replaceFirst(CHE_WORKSPACE_ID_PREFIX,""));
globalPropertiesMap.put("machineName", getMachineName());
globalPropertiesMap.put("wildcardNipDomain", getWildcardNipDomain(externalAddress));
globalPropertiesMap.put("wildcardXipDomain", getWildcardXipDomain(externalAddress));
globalPropertiesMap.put("chePort", chePort);
globalPropertiesMap.put(IS_DEV_MACHINE_MACRO, getIsDevMachine());
}

/**
Expand All @@ -333,11 +426,25 @@ public String render(String template, String port) {
this.initialized = true;
}
ST stringTemplate = new ST(template);
globalPropertiesMap.forEach((key, value) -> stringTemplate.add(key, value));
globalPropertiesMap.forEach((key, value) -> stringTemplate.add(key,
IS_DEV_MACHINE_MACRO.equals(key) ?
Boolean.parseBoolean(value)
: value));
stringTemplate.add("serverName", portsToRefName.get(port));
return stringTemplate.render();
}

/**
* returns if the current machine is the dev machine
*
* @return true if the curent machine is the dev machine
*/
protected String getIsDevMachine() {
return Arrays.stream(env).filter(env -> env.startsWith(CHE_IS_DEV_MACHINE_PROPERTY))
.map(s -> s.substring(CHE_IS_DEV_MACHINE_PROPERTY.length()))
.findFirst().get();
}

/**
* Gets the workspace ID from the config of the given container
*
Expand Down Expand Up @@ -369,8 +476,11 @@ protected String getExternalIp(String externalAddress) {
try {
return InetAddress.getByName(externalAddress).getHostAddress();
} catch (UnknownHostException e) {
throw new UnsupportedOperationException("Unable to find the IP for the address '" + externalAddress + "'", e);
if (throwOnUnknownHost) {
throw new UnsupportedOperationException("Unable to find the IP for the address '" + externalAddress + "'", e);
}
}
return null;
}

/**
Expand All @@ -393,4 +503,13 @@ protected String getWildcardXipDomain(String externalAddress) {

}

@Override
protected boolean useHttpsForExternalUrls() {
return "https".equals(cheDockerCustomExternalProtocol);
}

public CustomServerEvaluationStrategy withThrowOnUnknownHost(boolean throwOnUnknownHost) {
this.throwOnUnknownHost = throwOnUnknownHost;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,48 +31,11 @@
* @author Alexander Garagatyi
* @see ServerEvaluationStrategy
*/
public class DefaultServerEvaluationStrategy extends ServerEvaluationStrategy {

/**
* Used to store the address set by property {@code che.docker.ip}, if applicable.
*/
protected String internalAddressProperty;

/**
* Used to store the address set by property {@code che.docker.ip.external}. if applicable.
*/
protected String externalAddressProperty;
public class DefaultServerEvaluationStrategy extends CustomServerEvaluationStrategy {

@Inject
public DefaultServerEvaluationStrategy(@Nullable @Named("che.docker.ip") String internalAddress,
@Nullable @Named("che.docker.ip.external") String externalAddress) {
this.internalAddressProperty = internalAddress;
this.externalAddressProperty = externalAddress;
}

@Override
protected Map<String, String> getInternalAddressesAndPorts(ContainerInfo containerInfo, String internalHost) {
String internalAddress = internalAddressProperty != null ?
internalAddressProperty :
internalHost;

return getExposedPortsToAddressPorts(internalAddress, containerInfo.getNetworkSettings().getPorts());
}

@Override
protected Map<String, String> getExternalAddressesAndPorts(ContainerInfo containerInfo,
String internalHost) {
String externalAddress = externalAddressProperty != null ?
externalAddressProperty :
internalAddressProperty != null ?
internalAddressProperty :
internalHost;

return super.getExposedPortsToAddressPorts(externalAddress, containerInfo.getNetworkSettings().getPorts());
}

@Override
protected boolean useHttpsForExternalUrls() {
return false;
super(internalAddress, externalAddress, null, null, null, false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ public class DockerInstanceRuntimeInfo implements MachineRuntimeInfo {
*/
public static final String CHE_MACHINE_NAME = "CHE_MACHINE_NAME";

/**
* Environment variable that will contain Name of the machine
*/
public static final String CHE_IS_DEV_MACHINE = "CHE_IS_DEV_MACHINE";

/**
* Default HOSTNAME that will be added in all docker containers that are started. This host will container the Docker host's ip
* reachable inside the container.
Expand Down
Loading