java/com.sap.sailing.landscape.ui/META-INF/MANIFEST.MF
... ...
@@ -36,6 +36,8 @@ Export-Package: com.google.gwt.user.client.rpc.core.com.sap.sse.landscape.aws.co
36 36
Bundle-ActivationPolicy: lazy
37 37
Import-Package: com.sap.sailing.domain.common,
38 38
com.sap.sailing.server.gateway.interfaces,
39
+ javax.servlet;version="[3.1.0,4.0.0)",
40
+ javax.servlet.http;version="[3.1.0,4.0.0)",
39 41
org.osgi.framework;version="1.8.0",
40 42
org.osgi.util.tracker;version="1.5.1"
41 43
Bundle-Activator: com.sap.sailing.landscape.ui.impl.Activator
java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/LandscapeManagementWriteServiceImpl.java
... ...
@@ -4,6 +4,7 @@ import java.io.IOException;
4 4
import java.net.InetAddress;
5 5
import java.net.MalformedURLException;
6 6
import java.net.URISyntaxException;
7
+import java.net.URL;
7 8
import java.net.UnknownHostException;
8 9
import java.util.ArrayList;
9 10
import java.util.Arrays;
... ...
@@ -705,12 +706,14 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem
705 706
final Database databaseConfiguration = master.getDatabaseConfiguration(region,
706 707
Landscape.WAIT_FOR_PROCESS_TIMEOUT, Optional.ofNullable(optionalKeyName),
707 708
privateKeyEncryptionPassphrase);
709
+ final URL requestURL = new URL(getThreadLocalRequest().getRequestURL().toString());
710
+ final URL continuationBaseURL = new URL(requestURL.getProtocol(), requestURL.getHost(), requestURL.getPort(), "/");
708 711
getLandscapeService()
709 712
.createArchiveReplicaSet(regionId, replicaSetName, instanceType, releaseNameOrNullForLatestMaster,
710 713
databaseConfiguration, optionalKeyName, privateKeyEncryptionPassphrase,
711
- userSetOrArchiveServerSecurityReplicationBearerToken, replicaReplicationBearerToken, domainName,
712
- optionalMemoryInMegabytesOrNull, optionalMemoryTotalSizeFactorOrNull,
713
- /* optionalIgtimiRiotPort */ null);
714
+ replicaReplicationBearerToken, domainName, optionalMemoryInMegabytesOrNull,
715
+ userSetOrArchiveServerSecurityReplicationBearerToken, optionalMemoryTotalSizeFactorOrNull,
716
+ /* optionalIgtimiRiotPort */ null, continuationBaseURL);
714 717
}
715 718
716 719
@Override
java/com.sap.sailing.landscape/resources/stringmessages/SailingLandscape_StringMessages.properties
... ...
@@ -15,4 +15,4 @@ FinishedToArchiveReplicaSetIntoBody=Archiving a replica set to {0} has finished.
15 15
FinishedToArchiveReplicaSetSubject=Archiving replica set {0} finished
16 16
FinishedToArchiveReplicaSetBody=Archiving replica set {0} has finished.\nIf you requested so, the original replica set has been removed.\n\nYou are receiving this mail because you have administrative permissions for {0}.\nRemove those permissions at <https://sapsailing.com/gwt/AdminConsole.html#UserManagementPlace:> if you do not like to receive these messages anymore.
17 17
NewArchiveCandidateReadyForSpotChecksAndRotationSubject=The new {0} candidate is ready for spot checks
18
-NewArchiveCandidateReadyForSpotChecksAndRotationBody=We''ve run the following checks:\n{3}.\nThe new {0} candidate is ready for spot checks and, if OK, rotation to become the new production {0}.\nRun your spot checks at <https://{1}/gwt/Home.html#EventsPlace:> and compare to <https://{2}/gwt/Home.html#EventsPlace:>.\nStart the rotation to the new production server at <https://security-service.sapsailing.com/gwt/AdminConsole.html#LandscapeManagementPlace:> after successful checks.
... ...
\ No newline at end of file
0
+NewArchiveCandidateReadyForSpotChecksAndRotationBody=We''ve run the following checks:\n{3}.\nThe new {0} candidate is ready for spot checks and, if OK, rotation to become the new production {0}.\nRun your spot checks at <https://{1}/gwt/Home.html#EventsPlace:> and compare to <https://{2}/gwt/Home.html#EventsPlace:>.\nStart the rotation to the new production server at <{4}/gwt/AdminConsole.html#LandscapeManagementPlace:> after successful checks.
... ...
\ No newline at end of file
java/com.sap.sailing.landscape/resources/stringmessages/SailingLandscape_StringMessages_de.properties
... ...
@@ -15,4 +15,4 @@ FinishedToArchiveReplicaSetIntoBody=Die Archivierung des Anwendungs-Clusters nac
15 15
FinishedToArchiveReplicaSetSubject=Archivierung des Anwendungs-Clusters {0} beendet
16 16
FinishedToArchiveReplicaSetBody=Die Archivierung des Anwendungs-Clusters {0} ist beendet.\nFalls angefragt, wurde das Original Anwendungs-Cluster entfernt.\n\nDiese Nachricht wurde versandt, weil Du über administrative Rechte für {0} verfügst.\nUm das zu ändern, besuche <https://sapsailing.com/gwt/AdminConsole.html#UserManagementPlace:>, um diese Rechte für Dein Benutzerkonto zu entfernen.
17 17
NewArchiveCandidateReadyForSpotChecksAndRotationSubject=Der neue {0} Kandidat ist bereit für einen stichprobenartigen Vergleich
18
-NewArchiveCandidateReadyForSpotChecksAndRotationBody=Es wurden die folgenden Prüfungen durchgeführt:\n{3}.\nDer neue {0} Kandidat ist bereit für einen stichprobenartigen Vergleich\nund, falls OK, Rotation zum neuen Produktiv-Server für {0}.\nStichprobenartiger Vergleich unter https://{1}/gwt/Home.html#EventsPlace: und https://{2}/gwt/Home.html#EventsPlace:.\nRotation nach erfolgreichen Prüfungen unter <https://security-service.sapsailing.com/gwt/AdminConsole.html#LandscapeManagementPlace:> starten.
... ...
\ No newline at end of file
0
+NewArchiveCandidateReadyForSpotChecksAndRotationBody=Es wurden die folgenden Prüfungen durchgeführt:\n{3}.\nDer neue {0} Kandidat ist bereit für einen stichprobenartigen Vergleich\nund, falls OK, Rotation zum neuen Produktiv-Server für {0}.\nStichprobenartiger Vergleich unter https://{1}/gwt/Home.html#EventsPlace: und https://{2}/gwt/Home.html#EventsPlace:.\nRotation nach erfolgreichen Prüfungen unter <{4}/gwt/AdminConsole.html#LandscapeManagementPlace:> starten.
... ...
\ No newline at end of file
java/com.sap.sailing.landscape/src/com/sap/sailing/landscape/LandscapeService.java
... ...
@@ -2,6 +2,7 @@ package com.sap.sailing.landscape;
2 2
3 3
import java.io.IOException;
4 4
import java.net.MalformedURLException;
5
+import java.net.URL;
5 6
import java.util.Map;
6 7
import java.util.Optional;
7 8
import java.util.concurrent.ExecutionException;
... ...
@@ -166,12 +167,16 @@ public interface LandscapeService {
166 167
* receives an e-mail that asks for manual spot checks and a confirmation about the rotation. A link embedded in the
167 168
* e-mail grants the user easy access to the
168 169
* {@link #makeCandidateArchiveServerGoLive(String, String, byte[], String)} method which then performs phase 2.
170
+ *
171
+ * @param continuationBaseURL
172
+ * the base URL to which to direct the user for continuation of the ARCHIVE upgrade process (phase 2)
173
+ * after this first phase has completed successfully
169 174
*/
170 175
void createArchiveReplicaSet(
171 176
String regionId, String name, String instanceType, String releaseNameOrNullForLatestMaster, Database databaseConfiguration,
172
- String optionalKeyName, byte[] privateKeyEncryptionPassphrase, String securityServiceReplicationBearerToken,
173
- String replicaReplicationBearerToken, String optionalDomainName, Integer optionalMemoryInMegabytesOrNull,
174
- Integer optionalMemoryTotalSizeFactorOrNull, Integer optionalIgtimiRiotPort) throws Exception;
177
+ String optionalKeyName, byte[] privateKeyEncryptionPassphrase, String replicaReplicationBearerToken,
178
+ String optionalDomainName, Integer optionalMemoryInMegabytesOrNull, String securityServiceReplicationBearerToken,
179
+ Integer optionalMemoryTotalSizeFactorOrNull, Integer optionalIgtimiRiotPort, URL continuationBaseURL) throws Exception;
175 180
176 181
/**
177 182
* Phase 2 of an ARCHIVE server upgrade. This is to be triggered ideally after a "human in the loop" step
java/com.sap.sailing.landscape/src/com/sap/sailing/landscape/impl/ArchiveCandidateMonitoringBackgroundTask.java
... ...
@@ -114,6 +114,7 @@ public class ArchiveCandidateMonitoringBackgroundTask implements Runnable {
114 114
private final String candidateHostname;
115 115
private final LandscapeService landscapeService;
116 116
private final AwsApplicationReplicaSet<String, SailingAnalyticsMetrics, SailingAnalyticsProcess<String>> replicaSet;
117
+ private final URL continuationBaseURL;
117 118
private final ScheduledExecutorService executor;
118 119
119 120
/**
... ...
@@ -130,9 +131,10 @@ public class ArchiveCandidateMonitoringBackgroundTask implements Runnable {
130 131
AwsApplicationReplicaSet<String, SailingAnalyticsMetrics, SailingAnalyticsProcess<String>> replicaSet,
131 132
String candidateHostname,
132 133
ScheduledExecutorService executor,
133
- String effectiveBearerToken) {
134
+ String effectiveBearerToken, URL continuationBaseURL) {
134 135
this.currentUser = currentUser;
135 136
this.landscapeService = landscapeService;
137
+ this.continuationBaseURL = continuationBaseURL;
136 138
this.replicaSet = replicaSet;
137 139
this.candidateHostname = candidateHostname;
138 140
this.executor = executor;
... ...
@@ -296,6 +298,7 @@ public class ArchiveCandidateMonitoringBackgroundTask implements Runnable {
296 298
private void notifyProcessOwnerCandidateIsReadyForSpotChecksAndRotation() throws MailException, InterruptedException, ExecutionException {
297 299
landscapeService.sendMailToUser(currentUser, "NewArchiveCandidateReadyForSpotChecksAndRotationSubject",
298 300
"NewArchiveCandidateReadyForSpotChecksAndRotationBody", replicaSet.getName(), candidateHostname,
299
- replicaSet.getHostname(), " - "+Util.joinStrings("\n - ", Util.map(checks, Check::getName)));
301
+ replicaSet.getHostname(), " - "+Util.joinStrings("\n - ", Util.map(checks, Check::getName)),
302
+ continuationBaseURL.toString());
300 303
}
301 304
}
java/com.sap.sailing.landscape/src/com/sap/sailing/landscape/impl/LandscapeServiceImpl.java
... ...
@@ -240,9 +240,9 @@ public class LandscapeServiceImpl implements LandscapeService {
240 240
@Override
241 241
public void createArchiveReplicaSet(
242 242
String regionId, String replicaSetName, String instanceType, String releaseNameOrNullForLatestMaster, Database databaseConfiguration,
243
- String optionalKeyName, byte[] privateKeyEncryptionPassphrase, String securityServiceReplicationBearerToken, String replicaReplicationBearerToken,
244
- String optionalDomainName, Integer optionalMemoryInMegabytesOrNull,
245
- Integer optionalMemoryTotalSizeFactorOrNull, Integer optionalIgtimiRiotPort) throws Exception {
243
+ String optionalKeyName, byte[] privateKeyEncryptionPassphrase, String replicaReplicationBearerToken, String optionalDomainName,
244
+ Integer optionalMemoryInMegabytesOrNull, String securityServiceReplicationBearerToken,
245
+ Integer optionalMemoryTotalSizeFactorOrNull, Integer optionalIgtimiRiotPort, URL continuationBaseURL) throws Exception {
246 246
assert getSecurityService().getCurrentUser() != null;
247 247
final AwsLandscape<String> landscape = getLandscape();
248 248
final String candidateHostname = getHostname(SharedLandscapeConstants.ARCHIVE_CANDIDATE_SUBDOMAIN, optionalDomainName);
... ...
@@ -297,7 +297,7 @@ public class LandscapeServiceImpl implements LandscapeService {
297 297
final ScheduledExecutorService monitorTaskExecutor = ThreadPoolUtil.INSTANCE.getDefaultBackgroundTaskThreadPoolExecutor();
298 298
final ArchiveCandidateMonitoringBackgroundTask monitoringTask = new ArchiveCandidateMonitoringBackgroundTask(
299 299
getSecurityService().getCurrentUser(), this, replicaSet, candidateHostname, monitorTaskExecutor,
300
- bearerTokenUsedByReplicas);
300
+ bearerTokenUsedByReplicas, continuationBaseURL);
301 301
monitorTaskExecutor.execute(monitoringTask);
302 302
}
303 303
java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/AwsLandscapeImpl.java
... ...
@@ -693,7 +693,11 @@ public class AwsLandscapeImpl<ShardingKey> implements AwsLandscape<ShardingKey>
693 693
*/
694 694
@Override
695 695
public <HostT extends AwsInstance<ShardingKey>> HostT getHostByPrivateDnsNameOrIpAddress(com.sap.sse.landscape.Region region, String privateIpAddress, HostSupplier<ShardingKey, HostT> hostSupplier) {
696
- return getHost(region, getInstanceByPrivateDnsNameOrIpAddress(region, privateIpAddress), hostSupplier);
696
+ final Instance instanceByPrivateDnsNameOrIpAddress = getInstanceByPrivateDnsNameOrIpAddress(region, privateIpAddress);
697
+ if (instanceByPrivateDnsNameOrIpAddress == null) {
698
+ throw new IllegalArgumentException("Couldn't find instance with IP/hostname "+privateIpAddress+" in region "+region);
699
+ }
700
+ return getHost(region, instanceByPrivateDnsNameOrIpAddress, hostSupplier);
697 701
}
698 702
699 703
private Route53Client getRoute53Client() {