From e76d7b0ead35efe407d7253886c6b2b70dc41966 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Tue, 21 Sep 2021 18:44:08 +0200 Subject: [PATCH] bug5311: fixed (but didn't test) producing ARCHIVE rewrites when archiving a replica set --- ...LBToReverseProxyArchiveRedirectMapper.java | 52 +++++++++++++++++++ .../ALBToReverseProxyRedirectMapper.java | 24 ++++----- ...stractALBToReverseProxyRedirectMapper.java | 51 ++++++++++++++++++ .../LandscapeManagementWriteServiceImpl.java | 4 +- .../api/MigrateLeaderboardgroupResource.java | 6 +++ .../sap/sse/landscape/aws/ReverseProxy.java | 21 ++++++-- .../aws/impl/ApacheReverseProxy.java | 22 +++++++- .../aws/impl/ApacheReverseProxyCluster.java | 24 +++++++++ 8 files changed, 184 insertions(+), 20 deletions(-) create mode 100755 java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/ALBToReverseProxyArchiveRedirectMapper.java create mode 100755 java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/AbstractALBToReverseProxyRedirectMapper.java diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/ALBToReverseProxyArchiveRedirectMapper.java b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/ALBToReverseProxyArchiveRedirectMapper.java new file mode 100755 index 00000000000..477d76c229f --- /dev/null +++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/ALBToReverseProxyArchiveRedirectMapper.java @@ -0,0 +1,52 @@ +package com.sap.sailing.landscape.ui.server; + +import java.util.Optional; + +import com.sap.sailing.landscape.ui.shared.EventRedirectDTO; +import com.sap.sailing.landscape.ui.shared.EventSeriesRedirectDTO; +import com.sap.sailing.landscape.ui.shared.HomeRedirectDTO; +import com.sap.sailing.landscape.ui.shared.PlainRedirectDTO; +import com.sap.sailing.landscape.ui.shared.RedirectDTO; +import com.sap.sailing.landscape.ui.shared.RedirectVisitor; +import com.sap.sse.landscape.Log; +import com.sap.sse.landscape.application.ApplicationProcess; +import com.sap.sse.landscape.application.ApplicationProcessMetrics; +import com.sap.sse.landscape.aws.ReverseProxy; + +/** + * From the respective {@link RedirectDTO} produces a corresponding {@link ReverseProxy} redirect that maps to the ARCHIVE server. + * For the "Plain" / index.html routing we don't currently have a corresponding ARCHIVE rewrite macro, hence a plain + * routing is mapped to a Home.html rewrite for the ARCHIVE. + * + * @author Axel Uhl (D043530) + * + */ +public class ALBToReverseProxyArchiveRedirectMapper, LogT extends Log> +extends AbstractALBToReverseProxyRedirectMapper +implements RedirectVisitor { + + public ALBToReverseProxyArchiveRedirectMapper(ReverseProxy reverseProxy, + String hostname, ProcessT master, Optional optionalKeyName, byte[] privateKeyDecryptionPassphrase) { + super(reverseProxy, hostname, optionalKeyName, privateKeyDecryptionPassphrase); + } + + @Override + public void visit(PlainRedirectDTO plainRedirectDTO) throws Exception { + getReverseProxy().setHomeArchiveRedirect(getHostname(), getOptionalKeyName(), getPrivateKeyDecryptionPassphrase()); + } + + @Override + public void visit(HomeRedirectDTO homeRedirectDTO) throws Exception { + getReverseProxy().setHomeArchiveRedirect(getHostname(), getOptionalKeyName(), getPrivateKeyDecryptionPassphrase()); + } + + @Override + public void visit(EventRedirectDTO eventRedirectDTO) throws Exception { + getReverseProxy().setEventArchiveRedirect(getHostname(), eventRedirectDTO.getId(), getOptionalKeyName(), getPrivateKeyDecryptionPassphrase()); + } + + @Override + public void visit(EventSeriesRedirectDTO eventSeriesRedirectDTO) throws Exception { + getReverseProxy().setEventSeriesArchiveRedirect(getHostname(), eventSeriesRedirectDTO.getId(), getOptionalKeyName(), getPrivateKeyDecryptionPassphrase()); + } +} diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/ALBToReverseProxyRedirectMapper.java b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/ALBToReverseProxyRedirectMapper.java index ced40c5a533..50def413412 100755 --- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/ALBToReverseProxyRedirectMapper.java +++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/ALBToReverseProxyRedirectMapper.java @@ -14,47 +14,41 @@ import com.sap.sse.landscape.application.ApplicationProcessMetrics; import com.sap.sse.landscape.aws.ReverseProxy; /** - * From the respective {@link RedirectDTO} produces a corresponding {@link ReverseProxy} redirect. + * From the respective {@link RedirectDTO} produces a corresponding {@link ReverseProxy} redirect that uses a process's + * host's private IP address to route requests to it. This assumes that routing is enabled from the reverse proxy + * to the process's host, either by both being within the same VPC or, e.g., by peering the VPCs they are in. * * @author Axel Uhl (D043530) * */ public class ALBToReverseProxyRedirectMapper, LogT extends Log> +extends AbstractALBToReverseProxyRedirectMapper implements RedirectVisitor { - private final ReverseProxy reverseProxy; - private final String hostname; private final ProcessT master; - private final Optional optionalKeyName; - private final byte[] privateKeyDecryptionPassphrase; public ALBToReverseProxyRedirectMapper(ReverseProxy reverseProxy, String hostname, ProcessT master, Optional optionalKeyName, byte[] privateKeyDecryptionPassphrase) { - super(); - this.reverseProxy = reverseProxy; - this.hostname = hostname; + super(reverseProxy, hostname, optionalKeyName, privateKeyDecryptionPassphrase); this.master = master; - this.optionalKeyName = optionalKeyName; - this.privateKeyDecryptionPassphrase = privateKeyDecryptionPassphrase; } @Override public void visit(PlainRedirectDTO plainRedirectDTO) throws Exception { - reverseProxy.setPlainRedirect(hostname, master, optionalKeyName, privateKeyDecryptionPassphrase); + getReverseProxy().setPlainRedirect(getHostname(), master, getOptionalKeyName(), getPrivateKeyDecryptionPassphrase()); } @Override public void visit(HomeRedirectDTO homeRedirectDTO) throws Exception { - reverseProxy.setHomeRedirect(hostname, master, optionalKeyName, privateKeyDecryptionPassphrase); + getReverseProxy().setHomeRedirect(getHostname(), master, getOptionalKeyName(), getPrivateKeyDecryptionPassphrase()); } @Override public void visit(EventRedirectDTO eventRedirectDTO) throws Exception { - reverseProxy.setEventRedirect(hostname, master, eventRedirectDTO.getId(), optionalKeyName, privateKeyDecryptionPassphrase); + getReverseProxy().setEventRedirect(getHostname(), master, eventRedirectDTO.getId(), getOptionalKeyName(), getPrivateKeyDecryptionPassphrase()); } @Override public void visit(EventSeriesRedirectDTO eventSeriesRedirectDTO) throws Exception { - reverseProxy.setEventSeriesRedirect(hostname, master, eventSeriesRedirectDTO.getId(), optionalKeyName, privateKeyDecryptionPassphrase); + getReverseProxy().setEventSeriesRedirect(getHostname(), master, eventSeriesRedirectDTO.getId(), getOptionalKeyName(), getPrivateKeyDecryptionPassphrase()); } - } diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/AbstractALBToReverseProxyRedirectMapper.java b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/AbstractALBToReverseProxyRedirectMapper.java new file mode 100755 index 00000000000..7e3bbdefd68 --- /dev/null +++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/AbstractALBToReverseProxyRedirectMapper.java @@ -0,0 +1,51 @@ +package com.sap.sailing.landscape.ui.server; + +import java.util.Optional; + +import com.sap.sailing.landscape.ui.shared.RedirectDTO; +import com.sap.sailing.landscape.ui.shared.RedirectVisitor; +import com.sap.sse.landscape.Log; +import com.sap.sse.landscape.application.ApplicationProcess; +import com.sap.sse.landscape.application.ApplicationProcessMetrics; +import com.sap.sse.landscape.aws.ReverseProxy; + +/** + * From the respective {@link RedirectDTO} produces a corresponding {@link ReverseProxy} redirect that uses a process's + * host's private IP address to route requests to it. This assumes that routing is enabled from the reverse proxy + * to the process's host, either by both being within the same VPC or, e.g., by peering the VPCs they are in. + * + * @author Axel Uhl (D043530) + * + */ +public abstract class AbstractALBToReverseProxyRedirectMapper, LogT extends Log> +implements RedirectVisitor { + private final ReverseProxy reverseProxy; + private final String hostname; + private final Optional optionalKeyName; + private final byte[] privateKeyDecryptionPassphrase; + + public AbstractALBToReverseProxyRedirectMapper(ReverseProxy reverseProxy, + String hostname, Optional optionalKeyName, byte[] privateKeyDecryptionPassphrase) { + super(); + this.reverseProxy = reverseProxy; + this.hostname = hostname; + this.optionalKeyName = optionalKeyName; + this.privateKeyDecryptionPassphrase = privateKeyDecryptionPassphrase; + } + + protected ReverseProxy getReverseProxy() { + return reverseProxy; + } + + protected String getHostname() { + return hostname; + } + + protected Optional getOptionalKeyName() { + return optionalKeyName; + } + + protected byte[] getPrivateKeyDecryptionPassphrase() { + return privateKeyDecryptionPassphrase; + } +} diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/LandscapeManagementWriteServiceImpl.java b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/LandscapeManagementWriteServiceImpl.java index 46a5f4b9712..f023f20eb53 100755 --- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/LandscapeManagementWriteServiceImpl.java +++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/LandscapeManagementWriteServiceImpl.java @@ -740,7 +740,9 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem final ReverseProxy, RotatingFileBasedLog> centralReverseProxy = getLandscape().getCentralReverseProxy(region); SailingAnalyticsProcess archiveMaster = getSailingAnalyticsProcessFromDTO(archiveReplicaSet.getMaster()); - defaultRedirect.accept(new ALBToReverseProxyRedirectMapper<>( + // TODO bug5311: when refactoring this for general scope migration, moving to a dedicated replica set will not require this + // TODO bug5311: when refactoring this for general scope migration, moving into a cold storage server other than ARCHIVE will require ALBToReverseProxyRedirectMapper instead + defaultRedirect.accept(new ALBToReverseProxyArchiveRedirectMapper<>( centralReverseProxy, hostnameFromWhichToArchive, archiveMaster, Optional.ofNullable(optionalKeyName), passphraseForPrivateKeyDecryption)); if (removeApplicationReplicaSet) { final SailingAnalyticsProcess fromMaster = getSailingAnalyticsProcessFromDTO(applicationReplicaSetToArchive.getMaster()); diff --git a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/MigrateLeaderboardgroupResource.java b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/MigrateLeaderboardgroupResource.java index 74a603b0be5..79feb4c6d2c 100644 --- a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/MigrateLeaderboardgroupResource.java +++ b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/MigrateLeaderboardgroupResource.java @@ -224,6 +224,7 @@ public class MigrateLeaderboardgroupResource extends AbstractSailingServerResour private Pair doMDI(String remoteServerHostAsString, String dedicatedServerHostAsString, Set leaderboardGroupIds, String remoteServerBearerToken, String dedicatedServerBearerToken, boolean override) throws Exception { + // TODO bug5311 migrate to use SailingServer.importMasterData final StringJoiner form = new StringJoiner("&"); form.add(MasterDataImportResource.REMOTE_SERVER_URL_FORM_PARAM + "=" + remoteServerHostAsString); form.add(MasterDataImportResultJsonSerializer.OVERRIDE_FORM_PARAM + "=" + override); @@ -284,6 +285,7 @@ public class MigrateLeaderboardgroupResource extends AbstractSailingServerResour private Pair doCompareServers(String server1, String server2, String bearer1, String bearer2, Set leaderboardGroupIds) throws Exception { + // TODO bug5311 migrate to using SailingServer.compareServers final StringJoiner form = new StringJoiner("&"); form.add(CompareServersResource.SERVER1_FORM_PARAM + "=" + server1); form.add(CompareServersResource.SERVER2_FORM_PARAM + "=" + server2); @@ -295,6 +297,7 @@ public class MigrateLeaderboardgroupResource extends AbstractSailingServerResour private Pair doRemoteServerReferenceAdd(String serverToAddTo, String serverUrlToBeAdded, String serverToAddToBearerToken, Iterable eventIds) throws Exception { + // TODO bug5311 migrate to use SailingServer.addRemoteServerReference final Pair result; final RemoteSailingServerReference existingRef = getExistingRemoteServerReference(serverToAddTo, serverToAddToBearerToken, serverUrlToBeAdded); if (existingRef == null) { @@ -334,6 +337,7 @@ public class MigrateLeaderboardgroupResource extends AbstractSailingServerResour return result; } + // TODO bug5311 can probably be removed after migrating the other doRemoteServerReference* methods to using SailingServer.* methods private Pair doRemoteServerReferenceUpdate(String serverOnWhichToUpdateRemoteReference, String bearerToken, RemoteSailingServerReference updatedRef) throws IOException, Exception { final StringJoiner form = new StringJoiner("&"); @@ -345,6 +349,7 @@ public class MigrateLeaderboardgroupResource extends AbstractSailingServerResour return putFormAndReturnJsonAndResponseCode(serverOnWhichToUpdateRemoteReference, bearerToken, REMOTESERVERREFERENCEUPDATE_PATH, form); } + // TODO bug5311 can probably be removed after migrating the other doRemoteServerReference* methods to using SailingServer.* methods private RemoteSailingServerReference getExistingRemoteServerReference(final String serverUrlFromWhereToFetch, final String bearerToken, final String remoteReferenceServerUrl) throws MalformedURLException, Exception { final HttpClient client = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategyForAllRedirectResponseCodes()).build(); @@ -367,6 +372,7 @@ public class MigrateLeaderboardgroupResource extends AbstractSailingServerResour private Pair doRemoteServerReferenceRemove(String serverFromWhichToDelete, String serverUrlToDelete, String serverFromWhichToDeleteBearerToken, Iterable eventIds) throws Exception { + // TODO bug5311 migrate to use SailingServer.removeRemoteServerReference final RemoteSailingServerReference existingRef = getExistingRemoteServerReference(serverFromWhichToDelete, serverFromWhichToDeleteBearerToken, serverUrlToDelete); final Pair result; if (existingRef != null) { diff --git a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/ReverseProxy.java b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/ReverseProxy.java index 0478f30617f..c0bfa2e7512 100755 --- a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/ReverseProxy.java +++ b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/ReverseProxy.java @@ -50,14 +50,12 @@ public interface ReverseProxy optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception; /** * Configures a redirect in this reverse proxy such that requests for it will go to the * {@code /gwt/Home.html} landing page for the application replica set provided. - * @param optionalKeyName TODO */ void setHomeRedirect(String hostname, ProcessT applicationProcess, Optional optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception; @@ -65,7 +63,6 @@ public interface ReverseProxy optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception; @@ -77,6 +74,24 @@ public interface ReverseProxy optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception; + /** + * Like {@link #setEventRedirect(String, ApplicationProcess, UUID, Optional, byte[])}, only that the redirect points + * to the {@code ARCHIVE} server in the landscape. + */ + void setEventArchiveRedirect(String hostname, UUID eventId, Optional optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception; + + /** + * Like {@link #setEventSeriesRedirect(String, ApplicationProcess, UUID, Optional, byte[])}, only that the redirect + * points to the {@code ARCHIVE} server in the landscape. + */ + void setEventSeriesArchiveRedirect(String hostname, UUID leaderboardGroupId, Optional optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception; + + /** + * Like {@link #setHomeRedirect(String, ApplicationProcess, Optional, byte[])}, only that the redirect + * points to the {@code ARCHIVE} server in the landscape. + */ + void setHomeArchiveRedirect(String hostname, Optional optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception; + /** * Configures a rule for requests for anything from within {@code scope} such that those requests * are sent to the {@code applicationReplicaSet}. diff --git a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/ApacheReverseProxy.java b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/ApacheReverseProxy.java index 4dbb5e45830..7043db4cdcd 100755 --- a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/ApacheReverseProxy.java +++ b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/ApacheReverseProxy.java @@ -59,7 +59,10 @@ implements com.sap.sse.landscape.Process { private static final String HOME_REDIRECT_MACRO = "Home-SSL"; private static final String PLAIN_REDIRECT_MACRO = "Plain-SSL"; private static final String EVENT_REDIRECT_MACRO = "Event-SSL"; - private static final String SERIES_REDIRECT_MACRO = "Series-SSL"; + private static final String SERIES_REDIRECT_MACRO = "Series-SSL"; + private static final String HOME_ARCHIVE_REDIRECT_MACRO = "Home-ARCHIVE"; + private static final String EVENT_ARCHIVE_REDIRECT_MACRO = "Event-ARCHIVE"; + private static final String SERIES_ARCHIVE_REDIRECT_MACRO = "Series-ARCHIVE"; private static final String STATUS = "Status"; private static final String CONFIG_FILE_FOR_INTERNALS = "001-internals"+CONFIG_FILE_EXTENSION; @@ -135,6 +138,23 @@ implements com.sap.sse.landscape.Process { setRedirect(getConfigFileNameForHostname(hostname), SERIES_REDIRECT_MACRO, hostname, optionalKeyName, privateKeyEncryptionPassphrase, leaderboardGroupId.toString(), host, ""+port); } + @Override + public void setHomeArchiveRedirect(String hostname, Optional optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception { + setRedirect(getConfigFileNameForHostname(hostname), HOME_ARCHIVE_REDIRECT_MACRO, hostname, optionalKeyName, privateKeyEncryptionPassphrase); + } + + @Override + public void setEventArchiveRedirect(String hostname, UUID eventId, Optional optionalKeyName, + byte[] privateKeyEncryptionPassphrase) throws Exception { + setRedirect(getConfigFileNameForHostname(hostname), EVENT_ARCHIVE_REDIRECT_MACRO, hostname, optionalKeyName, privateKeyEncryptionPassphrase, eventId.toString()); + } + + @Override + public void setEventSeriesArchiveRedirect(String hostname, UUID leaderboardGroupId, + Optional optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception { + setRedirect(getConfigFileNameForHostname(hostname), SERIES_ARCHIVE_REDIRECT_MACRO, hostname, optionalKeyName, privateKeyEncryptionPassphrase, leaderboardGroupId.toString()); + } + @Override public void createInternalStatusRedirect(Optional optionalTimeout, Optional optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception { setRedirect(CONFIG_FILE_FOR_INTERNALS, STATUS, getHost().getPrivateAddress(optionalTimeout).getHostAddress(), optionalKeyName, privateKeyEncryptionPassphrase, INTERNAL_SERVER_STATUS); diff --git a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/ApacheReverseProxyCluster.java b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/ApacheReverseProxyCluster.java index 5ce45bfdd8d..312d87443b9 100755 --- a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/ApacheReverseProxyCluster.java +++ b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/ApacheReverseProxyCluster.java @@ -117,6 +117,30 @@ implements ReverseProxyCluster optionalKeyName, + byte[] privateKeyEncryptionPassphrase) throws Exception { + for (final ApacheReverseProxy proxy : getReverseProxies()) { + proxy.setEventArchiveRedirect(hostname, eventId, optionalKeyName, privateKeyEncryptionPassphrase); + } + } + + @Override + public void setEventSeriesArchiveRedirect(String hostname, UUID leaderboardGroupId, + Optional optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception { + for (final ApacheReverseProxy proxy : getReverseProxies()) { + proxy.setEventSeriesArchiveRedirect(hostname, leaderboardGroupId, optionalKeyName, privateKeyEncryptionPassphrase); + } + } + + @Override + public void setHomeArchiveRedirect(String hostname, Optional optionalKeyName, + byte[] privateKeyEncryptionPassphrase) throws Exception { + for (final ApacheReverseProxy proxy : getReverseProxies()) { + proxy.setHomeArchiveRedirect(hostname, optionalKeyName, privateKeyEncryptionPassphrase); + } + } + @Override public void setScopeRedirect(Scope scope, ProcessT applicationProcess) { for (final ApacheReverseProxy proxy : getReverseProxies()) {