java/com.sap.sailing.landscape/src/com/sap/sailing/landscape/impl/LandscapeServiceImpl.java
... ...
@@ -83,6 +83,7 @@ import com.sap.sse.landscape.aws.AwsInstance;
83 83
import com.sap.sse.landscape.aws.AwsLandscape;
84 84
import com.sap.sse.landscape.aws.AwsShard;
85 85
import com.sap.sse.landscape.aws.HostSupplier;
86
+import com.sap.sse.landscape.aws.LandscapeConstants;
86 87
import com.sap.sse.landscape.aws.ReverseProxy;
87 88
import com.sap.sse.landscape.aws.ReverseProxyCluster;
88 89
import com.sap.sse.landscape.aws.Tags;
... ...
@@ -264,7 +265,7 @@ public class LandscapeServiceImpl implements LandscapeService {
264 265
getLandscape().getCentralReverseProxy(region);
265 266
final com.sap.sailing.landscape.procedures.StartSailingAnalyticsMasterHost.Builder<?, String> masterHostBuilder = StartSailingAnalyticsMasterHost.masterHostBuilder(masterConfigurationBuilder);
266 267
masterHostBuilder
267
- .setAvailabilityZone(getBestAvailabilityZoneForArchiveCandidate(region, landscape, reverseProxyCluster))
268
+ .setAvailabilityZone(getBestAvailabilityZoneForArchiveCandidate(region, landscape, reverseProxyCluster, optionalKeyName, privateKeyEncryptionPassphrase))
268 269
.setInstanceName(SharedLandscapeConstants.ARCHIVE_SERVER_NEW_CANDIDATE_INSTANCE_NAME)
269 270
.setInstanceType(InstanceType.valueOf(instanceType))
270 271
.setOptionalTimeout(Landscape.WAIT_FOR_HOST_TIMEOUT)
... ...
@@ -291,12 +292,39 @@ public class LandscapeServiceImpl implements LandscapeService {
291 292
}
292 293
293 294
private AwsAvailabilityZone getBestAvailabilityZoneForArchiveCandidate(AwsRegion region, AwsLandscape<String> landscape,
294
- ReverseProxyCluster<String, SailingAnalyticsMetrics, SailingAnalyticsProcess<String>, RotatingFileBasedLog> reverseProxyCluster) {
295
+ ReverseProxyCluster<String, SailingAnalyticsMetrics, SailingAnalyticsProcess<String>, RotatingFileBasedLog> reverseProxyCluster,
296
+ String optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception {
297
+ final AwsApplicationReplicaSet<String, SailingAnalyticsMetrics, SailingAnalyticsProcess<String>> oldArchiveReplicaSet = getLandscape()
298
+ .getApplicationReplicaSetByTagValue(region,
299
+ SharedLandscapeConstants.SAILING_ANALYTICS_APPLICATION_HOST_TAG,
300
+ SharedLandscapeConstants.ARCHIVE_SERVER_APPLICATION_REPLICA_SET_NAME,
301
+ new SailingAnalyticsHostSupplier<String>(), Landscape.WAIT_FOR_PROCESS_TIMEOUT,
302
+ Optional.ofNullable(optionalKeyName), privateKeyEncryptionPassphrase);
303
+ final SailingAnalyticsProcess<String> oldArchivePrimary = oldArchiveReplicaSet.getMaster();
304
+ final AwsAvailabilityZone oldArchiveAZ = oldArchivePrimary.getHost().getAvailabilityZone();
305
+ AwsAvailabilityZone result = null;
295 306
for (final AwsInstance<String> reverseProxyHost : reverseProxyCluster.getHosts()) {
296 307
final AwsAvailabilityZone az = reverseProxyHost.getAvailabilityZone();
308
+ if (!az.equals(oldArchiveAZ)) {
309
+ result = az;
310
+ break;
311
+ }
297 312
}
298
- // TODO bug6203: choose AZ such that ideally we have a reverse proxy in that AZ and the AZ differs from the current production ARCHIVE's AZ (which will become the failover later)
299
- return null;
313
+ if (result == null) {
314
+ logger.warning(
315
+ "Couldn't find a reverse proxy in an availabililty zone different from that of the current ARCHIVE server ("
316
+ + oldArchiveAZ + "). Reverse proxies in AZs " + Util.joinStrings(", ",
317
+ Util.map(reverseProxyCluster.getHosts(), host -> host.getAvailabilityZone())));
318
+ // no AZ found that is not the same as for the current ARCHIVE server and also has a reverse proxy;
319
+ // now we have to choose between "a rock and a hard place:" either launch in an AZ where we don't have
320
+ // a reverse proxy and hence will see slightly less throughput and some additional cost for cross-AZ
321
+ // traffic; or launch in the same AZ the current ARCHIVE runs in; this will put the new failover (the
322
+ // current production ARCHIVE) and the new production ARCHIVE into the same AZ, not benefiting from
323
+ // the availability improvements incurred by running in multiple AZs.
324
+ result = Util.first(reverseProxyCluster.getHosts()).getAvailabilityZone();
325
+ logger.info("Choosing the AZ of the first reverse proxy to avoid cost and performance reduction by cross-AZ traffic: "+result);
326
+ }
327
+ return result;
300 328
}
301 329
302 330
@Override