mirror of
https://github.com/google/nomulus.git
synced 2025-05-13 07:57:13 +02:00
Use -dot- subdomain notation in MapReduce console links
appspot.com is not provisioned with a multi-level wildcard SSL certificate, so URLs of the form https://service.projectid.appspot.com/path need to be rewritten as https://service-dot-projectid.appspot.com/path (and same for version names). This is a follow-up to [] ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=231418795
This commit is contained in:
parent
6e0b8f2cfd
commit
3812c2ceda
7 changed files with 85 additions and 6 deletions
|
@ -284,7 +284,10 @@ public class MapreduceRunner {
|
|||
|
||||
private String renderMapreduceConsoleLink(String jobId) {
|
||||
return String.format(
|
||||
MAPREDUCE_CONSOLE_LINK_FORMAT, appEngineServiceUtils.getServiceHostname("backend"), jobId);
|
||||
MAPREDUCE_CONSOLE_LINK_FORMAT,
|
||||
appEngineServiceUtils.convertToSingleSubdomain(
|
||||
appEngineServiceUtils.getServiceHostname("backend")),
|
||||
jobId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -301,7 +304,7 @@ public class MapreduceRunner {
|
|||
}
|
||||
|
||||
public void sendLinkToMapreduceConsole(Response response) {
|
||||
response.setPayload(getLinkToMapreduceConsole());
|
||||
response.setPayload(getLinkToMapreduceConsole() + "\n");
|
||||
}
|
||||
|
||||
public String getLinkToMapreduceConsole() {
|
||||
|
|
|
@ -38,6 +38,25 @@ public interface AppEngineServiceUtils {
|
|||
/** Returns a host name to use for the given service and version. */
|
||||
String getVersionHostname(String service, String version);
|
||||
|
||||
/**
|
||||
* Converts a multi-level App Engine host name (not URL) to the -dot- single subdomain format.
|
||||
*
|
||||
* <p>This is needed because appspot.com only has a single wildcard SSL certificate, so the native
|
||||
* App Engine URLs of the form service.projectid.appspot.com or
|
||||
* version.service.projectid.appspot.com won't work over HTTPS when being fetched from outside of
|
||||
* GCP. The work-around is to change all of the "." subdomain markers to "-dot-". E.g.:
|
||||
*
|
||||
* <ul>
|
||||
* <li>tools.projectid.appspot.com --> tools-dot-projectid.appspot.com
|
||||
* <li>version.backend.projectid.appspot.com --> version-dot-backend-dot-projectid.appspot.com
|
||||
* </ul>
|
||||
*
|
||||
* @see <a
|
||||
* href="https://cloud.google.com/appengine/docs/standard/java/how-requests-are-routed">How
|
||||
* App Engine requests are routed</a>
|
||||
*/
|
||||
String convertToSingleSubdomain(String hostname);
|
||||
|
||||
/** Set the number of instances at runtime for a given service and version. */
|
||||
void setNumInstances(String service, String version, long numInstances);
|
||||
}
|
||||
|
|
|
@ -18,11 +18,18 @@ import static com.google.common.base.Preconditions.checkArgument;
|
|||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
|
||||
import com.google.appengine.api.modules.ModulesService;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/** A wrapper for {@link ModulesService} that provides a saner API. */
|
||||
public class AppEngineServiceUtilsImpl implements AppEngineServiceUtils {
|
||||
|
||||
private static final Pattern APPSPOT_HOSTNAME_PATTERN =
|
||||
Pattern.compile("^(.*)\\.appspot\\.com$");
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
private final ModulesService modulesService;
|
||||
|
||||
@Inject
|
||||
|
@ -56,4 +63,14 @@ public class AppEngineServiceUtilsImpl implements AppEngineServiceUtils {
|
|||
checkArgument(numInstances > 0, "Number of instances must be greater than 0");
|
||||
modulesService.setNumInstances(service, version, numInstances);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String convertToSingleSubdomain(String hostname) {
|
||||
Matcher matcher = APPSPOT_HOSTNAME_PATTERN.matcher(hostname);
|
||||
if (!matcher.matches()) {
|
||||
logger.atWarning().log("Skipping conversion because hostname can't be parsed: %s", hostname);
|
||||
return hostname;
|
||||
}
|
||||
return matcher.group(1).replace(".", "-dot-") + ".appspot.com";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,7 +94,8 @@ public class ExportDomainListsActionTest extends MapreduceTestCase<ExportDomainL
|
|||
runMapreduce();
|
||||
assertThat(response.getPayload())
|
||||
.startsWith(
|
||||
"Mapreduce console: https://backend.hostname.tld/_ah/pipeline/status.html?root=");
|
||||
"Mapreduce console: https://backend-dot-projectid.appspot.com"
|
||||
+ "/_ah/pipeline/status.html?root=");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -20,6 +20,7 @@ import static org.mockito.Mockito.mock;
|
|||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.appengine.api.blobstore.dev.LocalBlobstoreService;
|
||||
import com.google.appengine.api.modules.ModulesService;
|
||||
import com.google.appengine.api.taskqueue.dev.LocalTaskQueue;
|
||||
import com.google.appengine.api.taskqueue.dev.QueueStateInfo;
|
||||
import com.google.appengine.api.taskqueue.dev.QueueStateInfo.HeaderWrapper;
|
||||
|
@ -38,6 +39,7 @@ import google.registry.testing.FakeClock;
|
|||
import google.registry.testing.MockitoJUnitRule;
|
||||
import google.registry.testing.ShardableTestCase;
|
||||
import google.registry.util.AppEngineServiceUtils;
|
||||
import google.registry.util.AppEngineServiceUtilsImpl;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
@ -84,16 +86,19 @@ public abstract class MapreduceTestCase<T> extends ShardableTestCase {
|
|||
|
||||
@Rule public final MockitoJUnitRule mocks = MockitoJUnitRule.create();
|
||||
|
||||
@Mock
|
||||
AppEngineServiceUtils appEngineServiceUtils;
|
||||
|
||||
@Mock ModulesService modulesService;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
taskQueue = LocalTaskQueueTestConfig.getLocalTaskQueue();
|
||||
ApiProxyLocal proxy = (ApiProxyLocal) ApiProxy.getDelegate();
|
||||
// Creating files is not allowed in some test execution environments, so don't.
|
||||
proxy.setProperty(LocalBlobstoreService.NO_STORAGE_PROPERTY, "true");
|
||||
when(appEngineServiceUtils.getServiceHostname("backend")).thenReturn("backend.hostname.tld");
|
||||
appEngineServiceUtils = new AppEngineServiceUtilsImpl(modulesService);
|
||||
when(modulesService.getVersionHostname("backend", null))
|
||||
.thenReturn("version.backend.projectid.appspot.com");
|
||||
}
|
||||
|
||||
protected MapreduceRunner makeDefaultRunner() {
|
||||
|
|
|
@ -132,7 +132,8 @@ public class GenerateZoneFilesActionTest extends MapreduceTestCase<GenerateZoneF
|
|||
assertThat(response).containsKey("mapreduceConsoleLink");
|
||||
assertThat(response.get("mapreduceConsoleLink").toString())
|
||||
.startsWith(
|
||||
"Mapreduce console: https://backend.hostname.tld/_ah/pipeline/status.html?root=");
|
||||
"Mapreduce console: https://backend-dot-projectid.appspot.com"
|
||||
+ "/_ah/pipeline/status.html?root=");
|
||||
|
||||
executeTasksUntilEmpty("mapreduce");
|
||||
|
||||
|
|
|
@ -110,4 +110,37 @@ public class AppEngineServiceUtilsImplTest {
|
|||
() -> appEngineServiceUtils.setNumInstances("service", "version", -10L));
|
||||
assertThat(thrown).hasMessageThat().isEqualTo("Number of instances must be greater than 0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_convertToSingleSubdomain_doesNothingWithoutServiceOrHostname() {
|
||||
assertThat(appEngineServiceUtils.convertToSingleSubdomain("projectid.appspot.com"))
|
||||
.isEqualTo("projectid.appspot.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_convertToSingleSubdomain_doesNothingWhenItCannotParseCorrectly() {
|
||||
assertThat(appEngineServiceUtils.convertToSingleSubdomain("garbage.notrealhost.example"))
|
||||
.isEqualTo("garbage.notrealhost.example");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_convertToSingleSubdomain_convertsWithServiceName() {
|
||||
assertThat(appEngineServiceUtils.convertToSingleSubdomain("service.projectid.appspot.com"))
|
||||
.isEqualTo("service-dot-projectid.appspot.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_convertToSingleSubdomain_convertsWithVersionAndServiceName() {
|
||||
assertThat(
|
||||
appEngineServiceUtils.convertToSingleSubdomain("version.service.projectid.appspot.com"))
|
||||
.isEqualTo("version-dot-service-dot-projectid.appspot.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_convertToSingleSubdomain_convertsWithInstanceAndVersionAndServiceName() {
|
||||
assertThat(
|
||||
appEngineServiceUtils.convertToSingleSubdomain(
|
||||
"instanceid.version.service.projectid.appspot.com"))
|
||||
.isEqualTo("instanceid-dot-version-dot-service-dot-projectid.appspot.com");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue