mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-24 14:38:45 +00:00
bug4811: refactored UpgradeAmi procedure and continued with its snapshot handling
This commit is contained in:
+15
@@ -24,6 +24,7 @@ import com.sap.sailing.landscape.SailingAnalyticsMetrics;
|
||||
import com.sap.sailing.landscape.SailingAnalyticsReplica;
|
||||
import com.sap.sailing.landscape.impl.BearerTokenReplicationCredentials;
|
||||
import com.sap.sailing.landscape.procedures.StartSailingAnalyticsMaster;
|
||||
import com.sap.sailing.landscape.procedures.UpgradeAmi;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.landscape.InboundReplicationConfiguration;
|
||||
@@ -67,6 +68,20 @@ public class TestProcedures {
|
||||
securityServiceReplicationBearerToken = System.getProperty(SECURITY_SERVICE_REPLICATION_BEARER_TOKEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImageUpgrade() throws Exception {
|
||||
final com.sap.sailing.landscape.procedures.UpgradeAmi.Builder<String, SailingAnalyticsMaster<String>, SailingAnalyticsReplica<String>> imageUpgradeProcedureBuilder = UpgradeAmi.builder();
|
||||
final UpgradeAmi<String, SailingAnalyticsMaster<String>, SailingAnalyticsReplica<String>> imageUpgradeProcedure =
|
||||
imageUpgradeProcedureBuilder.build();
|
||||
try {
|
||||
imageUpgradeProcedure.run();
|
||||
int continueHere;
|
||||
// TODO add test verdicts
|
||||
} finally {
|
||||
imageUpgradeProcedure.getUpgradedAmi().delete();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMongoReplica() throws Exception {
|
||||
final Builder<String, ApplicationProcessMetrics, ?, ?> startMongoDBServerProcedureBuilder = StartMongoDBServer.builder();
|
||||
|
||||
+14
-15
@@ -21,7 +21,8 @@ import com.sap.sse.landscape.orchestration.Procedure;
|
||||
* @param <ShardingKey>
|
||||
* @param <HostT>
|
||||
*/
|
||||
public abstract class StartEmptyServer<ShardingKey, MetricsT extends ApplicationProcessMetrics,
|
||||
public abstract class StartEmptyServer<T extends StartEmptyServer<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>,
|
||||
ShardingKey, MetricsT extends ApplicationProcessMetrics,
|
||||
MasterProcessT extends ApplicationMasterProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
HostT extends AwsInstance<ShardingKey, MetricsT>>
|
||||
@@ -43,42 +44,40 @@ implements Procedure<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> {
|
||||
* </ul>
|
||||
* @author Axel Uhl (D043530)
|
||||
*/
|
||||
public static interface Builder<ShardingKey, MetricsT extends ApplicationProcessMetrics,
|
||||
public static interface Builder<T extends StartEmptyServer<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>,
|
||||
ShardingKey, MetricsT extends ApplicationProcessMetrics,
|
||||
MasterProcessT extends ApplicationMasterProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
HostT extends AwsInstance<ShardingKey, MetricsT>>
|
||||
extends StartAwsHost.Builder<StartEmptyServer<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> {
|
||||
boolean isNoShutdown();
|
||||
|
||||
Builder<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setNoShutdown(boolean noShutdown);
|
||||
extends StartAwsHost.Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> {
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setNoShutdown(boolean noShutdown);
|
||||
}
|
||||
|
||||
protected abstract static class BuilderImpl<ShardingKey, MetricsT extends ApplicationProcessMetrics,
|
||||
protected abstract static class BuilderImpl<T extends StartEmptyServer<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>,
|
||||
ShardingKey, MetricsT extends ApplicationProcessMetrics,
|
||||
MasterProcessT extends ApplicationMasterProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
HostT extends AwsInstance<ShardingKey, MetricsT>>
|
||||
extends StartAwsHost.BuilderImpl<StartEmptyServer<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
implements Builder<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> {
|
||||
extends StartAwsHost.BuilderImpl<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
implements Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> {
|
||||
private boolean noShutdown = true;
|
||||
|
||||
@Override
|
||||
public boolean isNoShutdown() {
|
||||
protected boolean isNoShutdown() {
|
||||
return noShutdown;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setNoShutdown(boolean noShutdown) {
|
||||
public Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setNoShutdown(boolean noShutdown) {
|
||||
this.noShutdown = noShutdown;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstanceName() {
|
||||
protected String getInstanceName() {
|
||||
return super.getInstanceName() == null ? IMAGE_UPGRADE_USER_DATA+" for "+getMachineImage().getId() : super.getInstanceName();
|
||||
}
|
||||
}
|
||||
|
||||
public StartEmptyServer(Builder<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> builder) {
|
||||
public StartEmptyServer(BuilderImpl<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> builder) {
|
||||
super(builder);
|
||||
addUserData(Collections.singleton(IMAGE_UPGRADE_USER_DATA));
|
||||
if (builder.isNoShutdown()) {
|
||||
|
||||
+30
-25
@@ -6,12 +6,11 @@ import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.landscape.SailingAnalyticsHost;
|
||||
import com.sap.sailing.landscape.SailingAnalyticsMetrics;
|
||||
import com.sap.sailing.landscape.impl.SailingAnalyticsHostImpl;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.landscape.application.ApplicationMasterProcess;
|
||||
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
|
||||
import com.sap.sse.landscape.application.ApplicationReplicaProcess;
|
||||
import com.sap.sse.landscape.aws.AwsInstance;
|
||||
import com.sap.sse.landscape.aws.AwsAvailabilityZone;
|
||||
import com.sap.sse.landscape.aws.AwsLandscape;
|
||||
import com.sap.sse.landscape.aws.HostSupplier;
|
||||
import com.sap.sse.landscape.ssh.SshCommandChannel;
|
||||
|
||||
@@ -30,13 +29,12 @@ import software.amazon.awssdk.services.ec2.model.InstanceType;
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
* @param <ShardingKey>
|
||||
* @param <HostT>
|
||||
* @param <SailingAnalyticsHost<ShardingKey>>
|
||||
*/
|
||||
public class StartMultiServer<ShardingKey, MetricsT extends ApplicationProcessMetrics,
|
||||
MasterProcessT extends ApplicationMasterProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
HostT extends AwsInstance<ShardingKey, MetricsT>>
|
||||
extends StartEmptyServer<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> {
|
||||
public class StartMultiServer<ShardingKey,
|
||||
MasterProcessT extends ApplicationMasterProcess<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT>,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT>>
|
||||
extends StartEmptyServer<StartMultiServer<ShardingKey, MasterProcessT, ReplicaProcessT>, ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT, SailingAnalyticsHost<ShardingKey>> {
|
||||
private static final Logger logger = Logger.getLogger(StartMultiServer.class.getName());
|
||||
private Optional<Duration> optionalTimeout;
|
||||
|
||||
@@ -46,41 +44,48 @@ extends StartEmptyServer<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT,
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*/
|
||||
public static interface Builder<ShardingKey, MetricsT extends ApplicationProcessMetrics,
|
||||
MasterProcessT extends ApplicationMasterProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
HostT extends AwsInstance<ShardingKey, MetricsT>>
|
||||
extends StartEmptyServer.Builder<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> {
|
||||
@Override
|
||||
default boolean isNoShutdown() {
|
||||
return true;
|
||||
}
|
||||
public static interface Builder<ShardingKey,
|
||||
MasterProcessT extends ApplicationMasterProcess<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT>,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT>>
|
||||
extends StartEmptyServer.Builder<StartMultiServer<ShardingKey, MasterProcessT, ReplicaProcessT>, ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT, SailingAnalyticsHost<ShardingKey>> {
|
||||
}
|
||||
|
||||
protected static class BuilderImpl<ShardingKey,
|
||||
MasterProcessT extends ApplicationMasterProcess<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT>,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT>>
|
||||
extends StartEmptyServer.BuilderImpl<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT, SailingAnalyticsHost<ShardingKey>>
|
||||
implements Builder<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT, SailingAnalyticsHost<ShardingKey>> {
|
||||
extends StartEmptyServer.BuilderImpl<StartMultiServer<ShardingKey, MasterProcessT, ReplicaProcessT>,
|
||||
ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT, SailingAnalyticsHost<ShardingKey>>
|
||||
implements Builder<ShardingKey, MasterProcessT, ReplicaProcessT> {
|
||||
@Override
|
||||
public StartMultiServer<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT, SailingAnalyticsHost<ShardingKey>> build() {
|
||||
public StartMultiServer<ShardingKey, MasterProcessT, ReplicaProcessT> build() {
|
||||
return new StartMultiServer<>(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isNoShutdown() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HostSupplier<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT, SailingAnalyticsHost<ShardingKey>> getHostSupplier() {
|
||||
return SailingAnalyticsHostImpl::new;
|
||||
return new HostSupplier<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT, SailingAnalyticsHost<ShardingKey>>() {
|
||||
@Override
|
||||
public SailingAnalyticsHost<ShardingKey> supply(String instanceId, AwsAvailabilityZone az,
|
||||
AwsLandscape<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT> landscape) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static <ShardingKey,
|
||||
MasterProcessT extends ApplicationMasterProcess<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT>,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT>,
|
||||
HostT extends AwsInstance<ShardingKey, SailingAnalyticsMetrics>> Builder<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT, SailingAnalyticsHost<ShardingKey>> builder() {
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT>>
|
||||
Builder<ShardingKey, MasterProcessT, ReplicaProcessT> builder() {
|
||||
return new BuilderImpl<>();
|
||||
}
|
||||
|
||||
protected StartMultiServer(Builder<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> builder) {
|
||||
protected StartMultiServer(BuilderImpl<ShardingKey, MasterProcessT, ReplicaProcessT> builder) {
|
||||
super(builder);
|
||||
this.optionalTimeout = builder.getOptionalTimeout();
|
||||
}
|
||||
|
||||
+1
-1
@@ -147,7 +147,7 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsMaste
|
||||
}
|
||||
}
|
||||
|
||||
protected StartSailingAnalyticsHost(Builder<? extends StartSailingAnalyticsHost<ShardingKey, ProcessT>, ShardingKey, ProcessT> builder) {
|
||||
protected StartSailingAnalyticsHost(BuilderImpl<? extends StartSailingAnalyticsHost<ShardingKey, ProcessT>, ShardingKey, ProcessT> builder) {
|
||||
super(builder);
|
||||
// remember the port we need in order to hand out the process
|
||||
this.port = builder.getPort();
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ public class StartSailingAnalyticsMaster<ShardingKey>
|
||||
return new BuilderImpl<>();
|
||||
}
|
||||
|
||||
protected StartSailingAnalyticsMaster(Builder<ShardingKey> builder) {
|
||||
protected StartSailingAnalyticsMaster(BuilderImpl<ShardingKey> builder) {
|
||||
super(builder);
|
||||
addUserData(ProcessConfigurationVariable.USE_ENVIRONMENT, "live-master-server"); // TODO maybe this should be handled by this procedure adding the correct defaults, e.g., for replicating security/sharedsailing?
|
||||
}
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ public class StartSailingAnalyticsReplica<ShardingKey>
|
||||
return new BuilderImpl<>();
|
||||
}
|
||||
|
||||
protected StartSailingAnalyticsReplica(Builder<ShardingKey> builder) {
|
||||
protected StartSailingAnalyticsReplica(BuilderImpl<ShardingKey> builder) {
|
||||
super(builder);
|
||||
addUserData(ProcessConfigurationVariable.USE_ENVIRONMENT, "live-replica-server"); // TODO maybe this should be handled by this procedure adding the correct defaults, e.g., for replicating security/sharedsailing?
|
||||
}
|
||||
|
||||
+109
-19
@@ -1,22 +1,29 @@
|
||||
package com.sap.sailing.landscape.procedures;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.sap.sailing.landscape.SailingAnalyticsHost;
|
||||
import com.sap.sailing.landscape.SailingAnalyticsMetrics;
|
||||
import com.sap.sailing.landscape.impl.SailingAnalyticsHostImpl;
|
||||
import com.sap.sailing.landscape.procedures.UpgradeAmi.Builder;
|
||||
import com.sap.sailing.landscape.procedures.UpgradeAmi.Builder.VersionPart;
|
||||
import com.sap.sse.landscape.MachineImage;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.landscape.application.ApplicationMasterProcess;
|
||||
import com.sap.sse.landscape.application.ApplicationReplicaProcess;
|
||||
import com.sap.sse.landscape.aws.AmazonMachineImage;
|
||||
import com.sap.sse.landscape.aws.AwsInstance;
|
||||
import com.sap.sse.landscape.aws.HostSupplier;
|
||||
import com.sap.sse.landscape.aws.orchestration.StartAwsHost;
|
||||
import com.sap.sse.landscape.orchestration.Procedure;
|
||||
|
||||
import software.amazon.awssdk.services.ec2.model.BlockDeviceMapping;
|
||||
import software.amazon.awssdk.services.ec2.model.Instance;
|
||||
import software.amazon.awssdk.services.ec2.model.InstanceStateName;
|
||||
|
||||
/**
|
||||
* Upgrades an existing Amazon Machine Image that is expected to be prepared for such an upgrade, by
|
||||
* invoking it with very specific user data that trigger the automatic upgrade. The resulting AMI can
|
||||
@@ -41,14 +48,18 @@ import com.sap.sse.landscape.orchestration.Procedure;
|
||||
public class UpgradeAmi<ShardingKey,
|
||||
MasterProcessT extends ApplicationMasterProcess<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT>,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT>>
|
||||
extends StartEmptyServer<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT, SailingAnalyticsHost<ShardingKey>>
|
||||
extends StartEmptyServer<UpgradeAmi<ShardingKey, MasterProcessT, ReplicaProcessT>, ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT, SailingAnalyticsHost<ShardingKey>>
|
||||
implements Procedure<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT> {
|
||||
private static final Logger logger = Logger.getLogger(UpgradeAmi.class.getName());
|
||||
private static final String IMAGE_UPGRADE_USER_DATA = "image-upgrade";
|
||||
private static final String NO_SHUTDOWN_USER_DATA = "no-shutdown";
|
||||
private static final Pattern imageNamePattern = Pattern.compile("^(.*) ([0-9]+)\\.([0-9]+)(\\.([0-9]+))?$");
|
||||
|
||||
private final String upgradedImageName;
|
||||
private MachineImage upgradedAmi;
|
||||
private final Duration timeout;
|
||||
private final boolean waitForShutdown; // no need to wait if no shutdown was requested
|
||||
private final Map<String, String> deviceNamesToSnapshotBaseNames;
|
||||
private AmazonMachineImage<ShardingKey, SailingAnalyticsMetrics> upgradedAmi;
|
||||
|
||||
/**
|
||||
* Additional default rules in addition to what the {@link StartAwsHost.Builder parent builder} defines:
|
||||
@@ -71,8 +82,7 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, Repli
|
||||
public static interface Builder<ShardingKey,
|
||||
MasterProcessT extends ApplicationMasterProcess<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT>,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT>>
|
||||
extends
|
||||
StartEmptyServer.Builder<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT, SailingAnalyticsHost<ShardingKey>> {
|
||||
extends StartEmptyServer.Builder<UpgradeAmi<ShardingKey, MasterProcessT, ReplicaProcessT>, ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT, SailingAnalyticsHost<ShardingKey>> {
|
||||
enum VersionPart {
|
||||
MAJOR, MINOR, MICRO
|
||||
}
|
||||
@@ -80,18 +90,35 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, Repli
|
||||
Builder<ShardingKey, MasterProcessT, ReplicaProcessT> setUpgradedImageName(String upgradedImageName);
|
||||
|
||||
Builder<ShardingKey, MasterProcessT, ReplicaProcessT> setVersionPartToIncrement(VersionPart versionPartToIncrement);
|
||||
|
||||
/**
|
||||
* An optional timeout when waiting for the upgraded instance to shut down for image creation.
|
||||
*/
|
||||
Builder<ShardingKey, MasterProcessT, ReplicaProcessT> setTimeout(Duration timeout);
|
||||
|
||||
/**
|
||||
* It is possible to assign base names for snapshots based on their device name in the AMI. For example, "/dev/sdc" may
|
||||
* be the "Swap" device, and "/dev/xvda" may be the "System" partition. The full name for the snapshot is then assembled from
|
||||
* the AMI's name including its version and this base name. If no such basename is provided for a device name for which
|
||||
* a block device mapping to a snapshot exists, the snapshot will only be named after the AMI's name, so when multiple snapshots
|
||||
* are connected to the AMI then their names will not be discernible.
|
||||
*/
|
||||
Builder<ShardingKey, MasterProcessT, ReplicaProcessT> setSnapshotBaseName(String deviceName, String snapshotBaseName);
|
||||
}
|
||||
|
||||
protected static class BuilderImpl<ShardingKey,
|
||||
MasterProcessT extends ApplicationMasterProcess<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT>,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT>>
|
||||
extends StartEmptyServer.BuilderImpl<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT, SailingAnalyticsHost<ShardingKey>>
|
||||
extends StartEmptyServer.BuilderImpl<UpgradeAmi<ShardingKey, MasterProcessT, ReplicaProcessT>, ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT, SailingAnalyticsHost<ShardingKey>>
|
||||
implements Builder<ShardingKey, MasterProcessT, ReplicaProcessT> {
|
||||
private String upgradedImageName;
|
||||
private VersionPart versionPartToIncrement;
|
||||
private Duration timeout;
|
||||
private final Map<String, String> deviceNamesToSnapshotBaseNames;
|
||||
|
||||
private BuilderImpl() {
|
||||
super();
|
||||
deviceNamesToSnapshotBaseNames = new HashMap<>();
|
||||
setNoShutdown(false);
|
||||
}
|
||||
|
||||
@@ -101,22 +128,36 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, Repli
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<ShardingKey, MasterProcessT, ReplicaProcessT> setTimeout(Duration timeout) {
|
||||
this.timeout = timeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
private String increaseVersionNumber(String imageName) {
|
||||
final String result;
|
||||
final Matcher versionNumberMatcher = imageNamePattern.matcher(imageName);
|
||||
if (versionNumberMatcher.matches()) {
|
||||
final String imageBaseName = versionNumberMatcher.group(1);
|
||||
final String majorVersion = versionNumberMatcher.group(2);
|
||||
final String minorVersion = versionNumberMatcher.group(3);
|
||||
final String microVersion = versionNumberMatcher.group(5);
|
||||
final Integer oldMajorVersion = Integer.valueOf(versionNumberMatcher.group(2));
|
||||
final Integer oldMinorVersion = Integer.valueOf(versionNumberMatcher.group(3));
|
||||
final Integer oldMicroVersion = versionNumberMatcher.group(5) == null ? null : Integer.valueOf(versionNumberMatcher.group(5));
|
||||
final VersionPart partToEffectivelyIncrement = versionPartToIncrement == null
|
||||
? oldMicroVersion == null ? VersionPart.MINOR : VersionPart.MICRO
|
||||
: versionPartToIncrement;
|
||||
final Integer newMajorVersion = partToEffectivelyIncrement == VersionPart.MAJOR ? oldMajorVersion + 1 : oldMajorVersion;
|
||||
final Integer newMinorVersion = partToEffectivelyIncrement == VersionPart.MINOR ? oldMinorVersion + 1 : oldMinorVersion;
|
||||
final Integer newMicroVersion = oldMajorVersion == null ?
|
||||
partToEffectivelyIncrement == VersionPart.MICRO ? 0 : null :
|
||||
partToEffectivelyIncrement == VersionPart.MICRO ? oldMajorVersion + 1 : oldMajorVersion;
|
||||
final StringBuilder sb = new StringBuilder(imageBaseName);
|
||||
sb.append(' ');
|
||||
sb.append(majorVersion);
|
||||
sb.append(newMajorVersion);
|
||||
sb.append('.');
|
||||
sb.append(minorVersion);
|
||||
if (microVersion != null || versionPartToIncrement == VersionPart.MICRO) {
|
||||
sb.append(newMinorVersion);
|
||||
if (newMicroVersion != null) {
|
||||
sb.append('.');
|
||||
sb.append(microVersion);
|
||||
sb.append(newMicroVersion);
|
||||
}
|
||||
result = sb.toString();
|
||||
} else {
|
||||
@@ -131,6 +172,12 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, Repli
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<ShardingKey, MasterProcessT, ReplicaProcessT> setSnapshotBaseName(String deviceName, String snapshotBaseName) {
|
||||
deviceNamesToSnapshotBaseNames.put(deviceName, snapshotBaseName);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HostSupplier<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, ReplicaProcessT, SailingAnalyticsHost<ShardingKey>> getHostSupplier() {
|
||||
return SailingAnalyticsHostImpl::new;
|
||||
@@ -139,6 +186,17 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, Repli
|
||||
protected String getUpgradedImageName() {
|
||||
return upgradedImageName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code null} means wait forever
|
||||
*/
|
||||
protected Duration getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
protected Map<String, String> getDeviceNamesToSnapshotBaseNames() {
|
||||
return Collections.unmodifiableMap(deviceNamesToSnapshotBaseNames);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpgradeAmi<ShardingKey, MasterProcessT, ReplicaProcessT> build() {
|
||||
@@ -159,6 +217,9 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, Repli
|
||||
protected UpgradeAmi(BuilderImpl<ShardingKey, MasterProcessT, ReplicaProcessT> builder) {
|
||||
super(builder);
|
||||
upgradedImageName = builder.getUpgradedImageName();
|
||||
timeout = builder.getTimeout();
|
||||
waitForShutdown = !builder.isNoShutdown();
|
||||
deviceNamesToSnapshotBaseNames = builder.getDeviceNamesToSnapshotBaseNames();
|
||||
addUserData(Collections.singleton(IMAGE_UPGRADE_USER_DATA));
|
||||
if (builder.isNoShutdown()) {
|
||||
addUserData(Collections.singleton(NO_SHUTDOWN_USER_DATA));
|
||||
@@ -168,16 +229,45 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, MasterProcessT, Repli
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
super.run(); // launches the machine in upgrade mode and shuts it down again, preparing for AMI creation
|
||||
final Instance instance = getLandscape().getInstance(getHost().getInstanceId(), getHost().getRegion());
|
||||
if (waitForShutdown) {
|
||||
logger.info("Waiting for shutdown of instance "+instance.instanceId());
|
||||
// wait for the instance to shut down
|
||||
final TimePoint startedWaiting = TimePoint.now();
|
||||
while (instance.state().name() != InstanceStateName.STOPPED && (timeout == null || startedWaiting.until(TimePoint.now()).compareTo(timeout) < 0)) {
|
||||
logger.info("Instance " + instance.instanceId() + " still in state " + instance.state().name()
|
||||
+ ". Waiting " + (timeout == null ? "forever"
|
||||
: ("for " + timeout.minus(startedWaiting.until(TimePoint.now())))));
|
||||
Thread.sleep(5000);
|
||||
}
|
||||
}
|
||||
upgradedAmi = getLandscape().createImage(getHost(), upgradedImageName);
|
||||
// TODO now comes the waiting for the shutdown and initiating the creation of an AMI for the instance
|
||||
// TODO then comes the tagging of the volume snapshots created
|
||||
// TODO then tag the resulting AMI according to the original image's tags, except for the name where automatic version number increment should be implemented
|
||||
for (final BlockDeviceMapping blockDeviceMapping : upgradedAmi.getBlockDeviceMappings()) {
|
||||
if (blockDeviceMapping.ebs() != null) {
|
||||
final String snapshotId = blockDeviceMapping.ebs().snapshotId();
|
||||
final String deviceName = blockDeviceMapping.deviceName();
|
||||
final String snapshotName = getSnapshotName(deviceName);
|
||||
getLandscape().setSnapshotName(getHost().getRegion(), snapshotId, snapshotName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getSnapshotName(String deviceName) {
|
||||
final StringBuilder result = new StringBuilder();
|
||||
result.append(upgradedImageName);
|
||||
final String baseName = deviceNamesToSnapshotBaseNames.get(deviceName);
|
||||
if (baseName != null) {
|
||||
result.append(" (");
|
||||
result.append(baseName);
|
||||
result.append(")");
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the resulting AMI that has the upgraded version of everything
|
||||
*/
|
||||
public MachineImage getUpgradedAmi() {
|
||||
public AmazonMachineImage<ShardingKey, SailingAnalyticsMetrics> getUpgradedAmi() {
|
||||
return upgradedAmi;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +122,10 @@ extends Landscape<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> {
|
||||
|
||||
AmazonMachineImage<ShardingKey, MetricsT> getLatestImageWithTag(Region region, String tagName, String tagValue);
|
||||
|
||||
void setSnapshotName(Region region, String snapshotId, String snapshotName);
|
||||
|
||||
void deleteSnapshot(Region region, String snapshotId);
|
||||
|
||||
/**
|
||||
* Finds EC2 instances in the {@code region} that have a tag named {@code tagName} with value {@code tagValue}.
|
||||
*/
|
||||
|
||||
+6
@@ -61,6 +61,12 @@ public class AmazonMachineImageImpl<ShardingKey, MetricsT extends ApplicationPro
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
for (final BlockDeviceMapping blockDeviceMapping : getBlockDeviceMappings()) {
|
||||
if (blockDeviceMapping.ebs() != null) {
|
||||
// TODO landscape.deleteSnapshot(blockDeviceMapping.ebs().snapshotId())
|
||||
}
|
||||
}
|
||||
int forceWarningTODO;
|
||||
// TODO implement AmazonMachineImageImpl.delete(); we probably want landscape here...
|
||||
}
|
||||
|
||||
|
||||
+11
@@ -455,6 +455,7 @@ ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterP
|
||||
|
||||
@Override
|
||||
public AmazonMachineImage<ShardingKey, MetricsT> createImage(AwsInstance<ShardingKey, MetricsT> instance, String imageName) {
|
||||
logger.info("Creating Amazon Machine Image (AMI) named "+imageName+" for instance "+instance.getInstanceId());
|
||||
final Ec2Client client = getEc2Client(getRegion(instance.getRegion()));
|
||||
final String imageId = client.createImage(b->b
|
||||
.instanceId(instance.getInstanceId())
|
||||
@@ -469,6 +470,16 @@ ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterP
|
||||
return new AmazonMachineImageImpl<>(response.images().stream().max(getMachineImageCreationDateComparator()).get(), region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSnapshotName(com.sap.sse.landscape.Region region, String snapshotId, String snapshotName) {
|
||||
getEc2Client(getRegion(region)).createTags(b->b.tags(Tag.builder().key("Name").value(snapshotName).build()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteSnapshot(com.sap.sse.landscape.Region region, String snapshotId) {
|
||||
getEc2Client(getRegion(region)).deleteSnapshot(b->b.snapshotId(snapshotId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AwsInstance<ShardingKey, MetricsT>> getHostsWithTagValue(com.sap.sse.landscape.Region region,
|
||||
String tagName, String tagValue) {
|
||||
|
||||
+50
-110
@@ -48,17 +48,7 @@ public abstract class StartAwsHost<ShardingKey,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
HostT extends AwsInstance<ShardingKey, MetricsT>>
|
||||
extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> {
|
||||
/**
|
||||
* The {@link AwsLandscape#getLatestImageWithTag(com.sap.sse.landscape.Region, String, String)} method is
|
||||
* used to obtain default images for specific AWS host starting procedures that subclass this class. The
|
||||
* Amazon Machine Images (AMIs) for this are then expected to be tagged with a tag named as specified by this
|
||||
* constant ("image-type"). The tag value then must match what the subclass wants.
|
||||
*
|
||||
* @see #getLatestImageOfType(String)
|
||||
*/
|
||||
private final static String IMAGE_TYPE_TAG_NAME = "image-type";
|
||||
|
||||
private static final String NAME_TAG_NAME = "Name";
|
||||
protected static final String NAME_TAG_NAME = "Name";
|
||||
|
||||
private final List<String> userData;
|
||||
private final InstanceType instanceType;
|
||||
@@ -68,7 +58,6 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
private final Optional<Tags> tags;
|
||||
private final HostSupplier<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> hostSupplier;
|
||||
private HostT host;
|
||||
|
||||
|
||||
/**
|
||||
* A builder that helps building an instance of type {@link StartAwsHost} or any subclass thereof (then using
|
||||
@@ -110,110 +99,58 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
HostT extends AwsInstance<ShardingKey, MetricsT>>
|
||||
extends StartHost.Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> {
|
||||
@Override
|
||||
AmazonMachineImage<ShardingKey, MetricsT> getMachineImage();
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setMachineImage(AmazonMachineImage<ShardingKey, MetricsT> machineImage);
|
||||
|
||||
/**
|
||||
* When not {@code null}, the newest {@link AmazonMachineImage} tagged with a tag named as specified by the constant {@link #IMAGE_TYPE_TAG_NAME}
|
||||
* with the value provided by the result of this method will be searched and will be used as the default for {@link #getMachineImage()}.
|
||||
*/
|
||||
String getImageType();
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setImageType(String imageType);
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setImageType(String imageType);
|
||||
|
||||
/**
|
||||
* By default, the release pre-deployed in the image will be used, represented by an empty {@link Optional}
|
||||
* returned by this default method implementation.
|
||||
*/
|
||||
Optional<Release> getRelease();
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setRelease(Optional<Release> release);
|
||||
|
||||
@Override
|
||||
AwsLandscape<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> getLandscape();
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setLandscape(AwsLandscape<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> landscape);
|
||||
|
||||
InstanceType getInstanceType();
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setInstanceType(InstanceType instanceType);
|
||||
|
||||
AwsAvailabilityZone getAvailabilityZone();
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setAvailabilityZone(AwsAvailabilityZone availabilityZone);
|
||||
|
||||
String getKeyName();
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setKeyName(String keyName);
|
||||
|
||||
Iterable<SecurityGroup> getSecurityGroups();
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setSecurityGroups(Iterable<SecurityGroup> securityGroups);
|
||||
|
||||
Optional<Tags> getTags();
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setTags(Optional<Tags> tags);
|
||||
|
||||
Iterable<String> getUserData();
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setUserData(String[] userData);
|
||||
|
||||
AwsRegion getRegion();
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setRegion(AwsRegion region);
|
||||
|
||||
String getInstanceName();
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setInstanceName(String name);
|
||||
|
||||
String getServerName();
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setServerName(String serverName);
|
||||
|
||||
String getDatabaseName();
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setDatabaseName(String databaseName);
|
||||
|
||||
Optional<InboundReplicationConfiguration> getInboundReplicationConfiguration();
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setReplicationConfiguration(
|
||||
InboundReplicationConfiguration replicationConfiguration);
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setOutboundReplicationConfiguration(OutboundReplicationConfiguration outboundReplicationConfiguration);
|
||||
|
||||
RabbitMQEndpoint getRabbitConfiguration();
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setRabbitConfiguration(RabbitMQEndpoint rabbitConfiguration);
|
||||
|
||||
Database getDatabaseConfiguration();
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setDatabaseConfiguration(Database databaseConfiguration);
|
||||
|
||||
String getCommaSeparatedEmailAddressesToNotifyOfStartup();
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setCommaSeparatedEmailAddressesToNotifyOfStartup(
|
||||
String commaSeparatedEmailAddressesToNotifyOfStartup);
|
||||
|
||||
/**
|
||||
* A timeout for interacting with the instance, such as when creating an SSH / SFTP connection or waiting for its
|
||||
* public IP address.
|
||||
*/
|
||||
Optional<Duration> getOptionalTimeout();
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setOptionalTimeout(Optional<Duration> optionalTimeout);
|
||||
|
||||
HostSupplier<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> getHostSupplier();
|
||||
|
||||
OutboundReplicationConfiguration getOutboundReplicationConfiguration();
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setHostSupplier(HostSupplier<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> hostSupplier);
|
||||
}
|
||||
|
||||
protected abstract static class BuilderImpl<T extends StartAwsHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>, ShardingKey,
|
||||
MetricsT extends ApplicationProcessMetrics,
|
||||
MasterProcessT extends ApplicationMasterProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
HostT extends AwsInstance<ShardingKey, MetricsT>> implements Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> {
|
||||
HostT extends AwsInstance<ShardingKey, MetricsT>>
|
||||
extends StartHost.BuilderImpl<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
implements Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> {
|
||||
private AmazonMachineImage<ShardingKey, MetricsT> machineImage;
|
||||
private String imageType;
|
||||
private Optional<Release> release = Optional.empty();
|
||||
@@ -234,10 +171,10 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
private OutboundReplicationConfiguration outboundReplicationConfiguration;
|
||||
private String commaSeparatedEmailAddressesToNotifyOfStartup;
|
||||
private Optional<Duration> optionalTimeout;
|
||||
private HostSupplier<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> hostSupplier;
|
||||
|
||||
@Override
|
||||
public AmazonMachineImage<ShardingKey, MetricsT> getMachineImage() {
|
||||
return machineImage == null ? getLatestImageOfType(getImageType(), getLandscape(), getRegion()) : machineImage;
|
||||
protected AmazonMachineImage<ShardingKey, MetricsT> getMachineImage() {
|
||||
return machineImage == null ? getLandscape().getLatestImageWithTag((Region) getRegion(), IMAGE_TYPE_TAG_NAME, getImageType()) : machineImage;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -247,8 +184,11 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImageType() {
|
||||
/**
|
||||
* When not {@code null}, the newest {@link AmazonMachineImage} tagged with a tag named as specified by the constant {@link #IMAGE_TYPE_TAG_NAME}
|
||||
* with the value provided by the result of this method will be searched and will be used as the default for {@link #getMachineImage()}.
|
||||
*/
|
||||
protected String getImageType() {
|
||||
return imageType;
|
||||
}
|
||||
|
||||
@@ -259,8 +199,11 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Release> getRelease() {
|
||||
/**
|
||||
* By default, the release pre-deployed in the image will be used, represented by an empty {@link Optional}
|
||||
* returned by this default method implementation.
|
||||
*/
|
||||
protected Optional<Release> getRelease() {
|
||||
return release;
|
||||
}
|
||||
|
||||
@@ -270,8 +213,7 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AwsLandscape<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> getLandscape() {
|
||||
protected AwsLandscape<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> getLandscape() {
|
||||
return landscape;
|
||||
}
|
||||
|
||||
@@ -282,8 +224,7 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceType getInstanceType() {
|
||||
protected InstanceType getInstanceType() {
|
||||
return instanceType;
|
||||
}
|
||||
|
||||
@@ -294,8 +235,7 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AwsAvailabilityZone getAvailabilityZone() {
|
||||
protected AwsAvailabilityZone getAvailabilityZone() {
|
||||
return availabilityZone == null ? getRandomAvailabilityZone(getRegion(), getLandscape()) : availabilityZone;
|
||||
}
|
||||
|
||||
@@ -306,8 +246,7 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKeyName() {
|
||||
protected String getKeyName() {
|
||||
return keyName;
|
||||
}
|
||||
|
||||
@@ -317,8 +256,7 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<SecurityGroup> getSecurityGroups() {
|
||||
protected Iterable<SecurityGroup> getSecurityGroups() {
|
||||
return securityGroups == null ? Collections.singleton(getLandscape().getDefaultSecurityGroupForApplicationHosts(getRegion())) : securityGroups;
|
||||
}
|
||||
|
||||
@@ -329,8 +267,7 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Tags> getTags() {
|
||||
protected Optional<Tags> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
@@ -340,8 +277,7 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> getUserData() {
|
||||
protected Iterable<String> getUserData() {
|
||||
return Collections.unmodifiableList(userData);
|
||||
}
|
||||
|
||||
@@ -355,8 +291,7 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AwsRegion getRegion() {
|
||||
protected AwsRegion getRegion() {
|
||||
return region == null ? getAvailabilityZone().getRegion() : region;
|
||||
}
|
||||
|
||||
@@ -366,8 +301,7 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstanceName() {
|
||||
protected String getInstanceName() {
|
||||
return instanceName;
|
||||
}
|
||||
|
||||
@@ -381,8 +315,7 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerName() {
|
||||
protected String getServerName() {
|
||||
return serverName;
|
||||
}
|
||||
|
||||
@@ -392,8 +325,7 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDatabaseName() {
|
||||
protected String getDatabaseName() {
|
||||
return databaseName == null ? getServerName() : databaseName;
|
||||
}
|
||||
|
||||
@@ -403,8 +335,7 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Database getDatabaseConfiguration() {
|
||||
protected Database getDatabaseConfiguration() {
|
||||
return databaseConfiguration == null ? getLandscape().getDatabase(getRegion(), getDatabaseName()) : databaseConfiguration;
|
||||
}
|
||||
|
||||
@@ -414,8 +345,7 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RabbitMQEndpoint getRabbitConfiguration() {
|
||||
protected RabbitMQEndpoint getRabbitConfiguration() {
|
||||
return rabbitConfiguration;
|
||||
}
|
||||
|
||||
@@ -438,8 +368,7 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
return outboundReplicationConfiguration != null && outboundReplicationConfiguration.getOutboundRabbitMQEndpoint() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutboundReplicationConfiguration getOutboundReplicationConfiguration() {
|
||||
protected OutboundReplicationConfiguration getOutboundReplicationConfiguration() {
|
||||
final OutboundReplicationConfiguration.Builder resultBuilder;
|
||||
if (outboundReplicationConfiguration != null) {
|
||||
resultBuilder = OutboundReplicationConfiguration.copy(outboundReplicationConfiguration);
|
||||
@@ -461,8 +390,7 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<InboundReplicationConfiguration> getInboundReplicationConfiguration() {
|
||||
protected Optional<InboundReplicationConfiguration> getInboundReplicationConfiguration() {
|
||||
final InboundReplicationConfiguration.Builder resultBuilder;
|
||||
if (inboundReplicationConfiguration == null || !inboundReplicationConfiguration.isPresent()) {
|
||||
resultBuilder = InboundReplicationConfiguration.builder();
|
||||
@@ -482,8 +410,7 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommaSeparatedEmailAddressesToNotifyOfStartup() {
|
||||
protected String getCommaSeparatedEmailAddressesToNotifyOfStartup() {
|
||||
return commaSeparatedEmailAddressesToNotifyOfStartup;
|
||||
}
|
||||
|
||||
@@ -493,7 +420,10 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* A timeout for interacting with the instance, such as when creating an SSH / SFTP connection or waiting for its
|
||||
* public IP address.
|
||||
*/
|
||||
public Optional<Duration> getOptionalTimeout() {
|
||||
return optionalTimeout == null ? Optional.empty() : optionalTimeout;
|
||||
}
|
||||
@@ -504,9 +434,19 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
this.optionalTimeout = optionalTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected HostSupplier<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> getHostSupplier() {
|
||||
return hostSupplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setHostSupplier(HostSupplier<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> hostSupplier) {
|
||||
this.hostSupplier = hostSupplier;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
protected StartAwsHost(Builder<? extends StartAwsHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> builder) {
|
||||
protected StartAwsHost(BuilderImpl<? extends StartAwsHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> builder) {
|
||||
super(builder);
|
||||
this.userData = new ArrayList<>();
|
||||
for (final String ud : builder.getUserData()) {
|
||||
|
||||
@@ -41,5 +41,5 @@ ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterP
|
||||
*/
|
||||
Iterable<Region> getRegions();
|
||||
|
||||
|
||||
MachineImage getLatestImageWithTag(Region region, String tagName, String tagValue);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.sap.sse.landscape.orchestration;
|
||||
import com.sap.sse.landscape.Host;
|
||||
import com.sap.sse.landscape.Landscape;
|
||||
import com.sap.sse.landscape.MachineImage;
|
||||
import com.sap.sse.landscape.Region;
|
||||
import com.sap.sse.landscape.application.ApplicationMasterProcess;
|
||||
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
|
||||
import com.sap.sse.landscape.application.ApplicationReplicaProcess;
|
||||
@@ -14,6 +15,16 @@ public abstract class StartHost<ShardingKey,
|
||||
HostT extends Host>
|
||||
extends AbstractProcedureImpl<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>
|
||||
implements Procedure<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> {
|
||||
/**
|
||||
* The {@link AwsLandscape#getLatestImageWithTag(com.sap.sse.landscape.Region, String, String)} method is
|
||||
* used to obtain default images for specific AWS host starting procedures that subclass this class. The
|
||||
* Amazon Machine Images (AMIs) for this are then expected to be tagged with a tag named as specified by this
|
||||
* constant ("image-type"). The tag value then must match what the subclass wants.
|
||||
*
|
||||
* @see #getLatestImageOfType(String)
|
||||
*/
|
||||
protected final static String IMAGE_TYPE_TAG_NAME = "image-type";
|
||||
|
||||
private final MachineImage machineImage;
|
||||
|
||||
/**
|
||||
@@ -28,13 +39,57 @@ implements Procedure<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> {
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
HostT extends Host> {
|
||||
T build();
|
||||
|
||||
MachineImage getMachineImage();
|
||||
|
||||
Landscape<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> getLandscape();
|
||||
}
|
||||
|
||||
protected StartHost(Builder<? extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> builder) {
|
||||
protected abstract static class BuilderImpl<T extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>, ShardingKey,
|
||||
MetricsT extends ApplicationProcessMetrics,
|
||||
MasterProcessT extends ApplicationMasterProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
HostT extends Host>
|
||||
implements Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> {
|
||||
private MachineImage machineImage;
|
||||
private Landscape<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> landscape;
|
||||
private Region region;
|
||||
private String imageType;
|
||||
|
||||
protected MachineImage getMachineImage() {
|
||||
return machineImage == null ? getLandscape().getLatestImageWithTag(getRegion(), IMAGE_TYPE_TAG_NAME, getImageType()) : machineImage;
|
||||
}
|
||||
|
||||
protected Region getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
protected Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setRegion(Region region) {
|
||||
this.region = region;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setMachineImage(MachineImage machineImage) {
|
||||
this.machineImage = machineImage;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected String getImageType() {
|
||||
return imageType;
|
||||
}
|
||||
|
||||
protected Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setImageType(String imageType) {
|
||||
this.imageType = imageType;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Landscape<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> getLandscape() {
|
||||
return landscape;
|
||||
}
|
||||
|
||||
protected Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setLandscape(Landscape<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> landscape) {
|
||||
this.landscape = landscape;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
protected StartHost(BuilderImpl<? extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> builder) {
|
||||
super(builder.getLandscape());
|
||||
this.machineImage = builder.getMachineImage();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user