Skip to content

Commit

Permalink
Fix webapp startup if no docker IP's set. (#8655)
Browse files Browse the repository at this point in the history
  • Loading branch information
mshaposhnik committed Feb 8, 2018
1 parent ba22044 commit 3700d41
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
import org.eclipse.che.workspace.infrastructure.docker.provisioner.securityopt.SecurityOptProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.provisioner.volume.ExtraVolumesProvisioner;
import org.eclipse.che.workspace.infrastructure.docker.server.mapping.ExternalIpURLRewriter;
import org.eclipse.che.workspace.infrastructure.docker.server.mapping.SinglePortHostnameBuilder;
import org.eclipse.che.workspace.infrastructure.docker.server.mapping.SinglePortHostnameBuilder.SinglePortHostnameBuilderProvider;
import org.eclipse.che.workspace.infrastructure.docker.server.mapping.SinglePortUrlRewriter;

/** @author Alexander Garagatyi */
Expand Down Expand Up @@ -76,6 +78,7 @@ protected void configure() {
MapBinder.newMapBinder(binder(), String.class, URLRewriter.class);
rewriters.addBinding("default").to(ExternalIpURLRewriter.class);
rewriters.addBinding("singleport").to(SinglePortUrlRewriter.class);
bind(SinglePortHostnameBuilder.class).toProvider(SinglePortHostnameBuilderProvider.class);

bind(URLRewriter.class).toProvider(UrlRewriterProvider.class);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import org.eclipse.che.api.core.model.workspace.config.ServerConfig;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
Expand All @@ -35,7 +36,7 @@
*/
public class SinglePortLabelsProvisioner implements ConfigurationProvisioner {

private final SinglePortHostnameBuilder hostnameBuilder;
private final Provider<SinglePortHostnameBuilder> hostnameBuilderProvider;
private final String internalIpOfContainers;
private final String externalIpOfContainers;
private final String dockerNetwork;
Expand All @@ -45,14 +46,8 @@ public SinglePortLabelsProvisioner(
@Nullable @Named("che.docker.ip") String internalIpOfContainers,
@Nullable @Named("che.docker.ip.external") String externalIpOfContainers,
@Nullable @Named("che.docker.network") String dockerNetwork,
@Nullable @Named("che.singleport.wildcard_domain.host") String wildcardHost) {
if (internalIpOfContainers == null && externalIpOfContainers == null) {
throw new IllegalStateException(
"Value of both of the properties 'che.docker.ip' and 'che.docker.ip.external' is null,"
+ " which is unsuitable for the single-port mode");
}
this.hostnameBuilder =
new SinglePortHostnameBuilder(externalIpOfContainers, internalIpOfContainers, wildcardHost);
Provider<SinglePortHostnameBuilder> hostnameBuilderProvider) {
this.hostnameBuilderProvider = hostnameBuilderProvider;
this.internalIpOfContainers = internalIpOfContainers;
this.externalIpOfContainers = externalIpOfContainers;
this.dockerNetwork = dockerNetwork;
Expand All @@ -72,7 +67,9 @@ public void provision(DockerEnvironment internalEnv, RuntimeIdentity identity)
continue;
}
final String host =
hostnameBuilder.build(serverEntry.getKey(), machineName, identity.getWorkspaceId());
hostnameBuilderProvider
.get()
.build(serverEntry.getKey(), machineName, identity.getWorkspaceId());
final String serviceName = getServiceName(host);
final String port = serverEntry.getValue().getPort().split("/")[0];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
import java.net.UnknownHostException;
import java.util.StringJoiner;
import java.util.regex.Pattern;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import org.eclipse.che.commons.annotation.Nullable;
import org.eclipse.che.inject.ConfigurationException;

/**
* Produces host names in form:
Expand Down Expand Up @@ -93,4 +98,37 @@ private String normalize(String input) {
}
return normalized;
}

public static class SinglePortHostnameBuilderProvider
implements Provider<SinglePortHostnameBuilder> {

private final SinglePortHostnameBuilder instance;

@Inject
public SinglePortHostnameBuilderProvider(
@Named("che.single.port") boolean isSinglePortEnabled,
@Nullable @Named("che.docker.ip") String internalIpOfContainers,
@Nullable @Named("che.docker.ip.external") String externalIpOfContainers,
@Nullable @Named("che.singleport.wildcard_domain.host") String wildcardHost) {
if (isSinglePortEnabled && internalIpOfContainers == null && externalIpOfContainers == null) {
throw new ConfigurationException(
"Value of both of the properties 'che.docker.ip' and 'che.docker.ip.external' is null,"
+ " which is unsuitable for the single-port mode");
}
this.instance =
isSinglePortEnabled
? new SinglePortHostnameBuilder(
externalIpOfContainers, internalIpOfContainers, wildcardHost)
: null;
}

@Override
public SinglePortHostnameBuilder get() {
if (instance == null) {
throw new IllegalStateException(
"This class may not be used other than in single-port mode.");
}
return instance;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriBuilderException;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
Expand All @@ -30,23 +31,14 @@
*/
public class SinglePortUrlRewriter implements URLRewriter {

private final SinglePortHostnameBuilder hostnameBuilder;
private final Provider<SinglePortHostnameBuilder> hostnameBuilderprovider;
private final int chePort;

@Inject
public SinglePortUrlRewriter(
@Nullable @Named("che.docker.ip") String internalIpOfContainers,
@Named("che.port") int chePort,
@Nullable @Named("che.docker.ip.external") String externalIpOfContainers,
@Nullable @Named("che.singleport.wildcard_domain.host") String wildcardHost) {
if (internalIpOfContainers == null && externalIpOfContainers == null) {
throw new IllegalStateException(
"Value of both of the properties 'che.docker.ip' and 'che.docker.ip.external' is null,"
+ " which is unsuitable for the single-port mode");
}
this.hostnameBuilder =
new SinglePortHostnameBuilder(externalIpOfContainers, internalIpOfContainers, wildcardHost);
@Named("che.port") int chePort, Provider<SinglePortHostnameBuilder> hostnameBuilderProvider) {
this.chePort = chePort;
this.hostnameBuilderprovider = hostnameBuilderProvider;
}

@Override
Expand All @@ -56,7 +48,8 @@ public String rewriteURL(
@Nullable String serverName,
String url)
throws InfrastructureException {
final String host = hostnameBuilder.build(serverName, machineName, identity.getWorkspaceId());
final String host =
hostnameBuilderprovider.get().build(serverName, machineName, identity.getWorkspaceId());
try {
UriBuilder uriBUilder = UriBuilder.fromUri(url).host(host);
if (chePort != 80 && chePort != 443) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import static org.testng.Assert.assertEquals;

import javax.inject.Provider;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.workspace.server.model.impl.RuntimeIdentityImpl;
import org.eclipse.che.api.workspace.server.spi.InternalInfrastructureException;
Expand All @@ -32,8 +33,9 @@ public void shouldRewriteURL(
String incomeURL,
String expectedURL)
throws Exception {
SinglePortUrlRewriter rewriter =
new SinglePortUrlRewriter(externalIP, 8080, internalIp, nioHost);
Provider<SinglePortHostnameBuilder> provider =
() -> new SinglePortHostnameBuilder(externalIP, internalIp, nioHost);
SinglePortUrlRewriter rewriter = new SinglePortUrlRewriter(8080, provider);

String rewrittenURL = rewriter.rewriteURL(identity, machineName, serverName, incomeURL);

Expand All @@ -46,8 +48,8 @@ public static Object[][] urlRewritingTestProvider() {
// External IP
{
new RuntimeIdentityImpl("ws123", null, null),
"127.0.0.1",
"172.12.0.2",
"127.0.0.1",
"machine1",
"exec/http",
"my.io",
Expand Down Expand Up @@ -96,8 +98,9 @@ public static Object[][] urlRewritingTestProvider() {
"Rewriting of host 'server.machine1.ws123.172.12.0.2.nip.io' in URL ':' failed. Error: .*"
)
public void shouldThrowExceptionWhenRewritingFails() throws Exception {
SinglePortUrlRewriter rewriter =
new SinglePortUrlRewriter("127.0.0.1", 8080, "172.12.0.2", null);
Provider<SinglePortHostnameBuilder> provider =
() -> new SinglePortHostnameBuilder("172.12.0.2", "127.0.0.1", null);
SinglePortUrlRewriter rewriter = new SinglePortUrlRewriter(8080, provider);
rewriter.rewriteURL(new RuntimeIdentityImpl("ws123", null, null), "machine1", "server", ":");
}
}

0 comments on commit 3700d41

Please sign in to comment.