bug4811: major refactoring that removes many unused generic type parameters; added logic for scaling MongoDB replica sets

This commit is contained in:
Axel Uhl committed 2021-02-12 14:45:03 +01:00
1 parent d18126e794
commit 3dae16df8f
46 files changed
+499 -571

No files matched your search

@@ -42,7 +42,6 @@ import com.sap.sse.landscape.InboundReplicationConfiguration;
import com.sap.sse.landscape.application.ApplicationReplicaSet;
import com.sap.sse.landscape.aws.AmazonMachineImage;
import com.sap.sse.landscape.aws.ApplicationProcessHost;
import com.sap.sse.landscape.aws.AwsInstance;
import com.sap.sse.landscape.aws.AwsLandscape;
import com.sap.sse.landscape.aws.Tags;
import com.sap.sse.landscape.aws.impl.AwsRegion;
@@ -72,7 +71,7 @@ import software.amazon.awssdk.services.route53.model.RRType;
public class TestProcedures {
private static final Logger logger = Logger.getLogger(TestProcedures.class.getName());
private static final Optional<Duration> optionalTimeout = Optional.of(Duration.ONE_MINUTE.times(10));
private AwsLandscape<String, SailingAnalyticsMetrics, SailingAnalyticsProcess<String>> landscape;
private AwsLandscape<String> landscape;
private AwsRegion region;
private final static String MAIL_SMTP_PASSWORD = "mail.smtp.password";
private final static String SECURITY_SERVICE_REPLICATION_BEARER_TOKEN = "security.service.replication.bearer.token";
@@ -211,8 +210,8 @@ public class TestProcedures {
public void testAddMongoReplica() throws Exception {
final String keyName = "MyKey-"+UUID.randomUUID();
landscape.createKeyPair(region, keyName, privateKeyEncryptionPassphrase);
final StartMongoDBServer.Builder<?, String, SailingAnalyticsMetrics, SailingAnalyticsProcess<String>> builder = StartMongoDBServer.builder();
final StartMongoDBServer<String, SailingAnalyticsMetrics, SailingAnalyticsProcess<String>> startMongoDBServerProcedure = builder
final StartMongoDBServer.Builder<?, String, MongoProcess> builder = StartMongoDBServer.builder();
final StartMongoDBServer<String, MongoProcess> startMongoDBServerProcedure = builder
.setLandscape(landscape)
.setKeyName(keyName)
.setPrivateKeyEncryptionPassphrase(privateKeyEncryptionPassphrase)
@@ -268,7 +267,7 @@ public class TestProcedures {
.build();
try {
imageUpgradeProcedure.run();
final AmazonMachineImage<String, SailingAnalyticsMetrics> upgradedAmi = imageUpgradeProcedure.getUpgradedAmi();
final AmazonMachineImage<String> upgradedAmi = imageUpgradeProcedure.getUpgradedAmi();
assertTrue(upgradedAmi.getCreatedAt().until(TimePoint.now()).compareTo(Duration.ONE_MINUTE.times(10)) < 0);
assertEquals(3, Util.size(upgradedAmi.getBlockDeviceMappings()));
} catch (Exception e) {
@@ -336,15 +335,14 @@ public class TestProcedures {
final String domain = "wiesen-weg.de";
final String hostname = serverName+"."+domain;
CreateDynamicLoadBalancerMapping.Builder<?, ?, String, SailingAnalyticsMetrics,
SailingAnalyticsProcess<String>, AwsInstance<String, SailingAnalyticsMetrics>> createAlbProcedureBuilder = CreateDynamicLoadBalancerMapping.builder();
SailingAnalyticsProcess<String>> createAlbProcedureBuilder = CreateDynamicLoadBalancerMapping.builder();
createAlbProcedureBuilder
.setProcess(process)
.setHostname(hostname)
.setTargetGroupNamePrefix("S-ded-") // TODO when we combine procedures for launching dedicated hosts (StartSailingAnlayticsHost and specializations) then "S-ded-" should be the default; for DeployProcessOnMultiServer, "S-shared-" should be the default
.setLandscape(landscape);
optionalTimeout.ifPresent(createAlbProcedureBuilder::setTimeout);
final CreateDynamicLoadBalancerMapping<String, SailingAnalyticsMetrics, SailingAnalyticsProcess<String>, AwsInstance<String, SailingAnalyticsMetrics>> createAlbProcedure =
createAlbProcedureBuilder.build();
final CreateDynamicLoadBalancerMapping<String, SailingAnalyticsMetrics, SailingAnalyticsProcess<String>> createAlbProcedure = createAlbProcedureBuilder.build();
try {
createAlbProcedure.run();
// A few validations:
@@ -174,7 +174,9 @@ public class LandscapeManagementPanel extends VerticalPanel implements AwsAccess
}, stringMessages.hostname());
final ActionsColumn<MongoEndpointDTO, MongoEndpointsImagesBarCell> mongoEndpointsActionColumn = new ActionsColumn<MongoEndpointDTO, MongoEndpointsImagesBarCell>(
new MongoEndpointsImagesBarCell(stringMessages), /* permission checker */ (mongoEndpoint, action)->true);
mongoEndpointsActionColumn.addAction(MongoEndpointsImagesBarCell.ACTION_SCALE, mongoEndpointToScale->scaleMongoEndpoint(stringMessages, mongoEndpointToScale));
mongoEndpointsActionColumn.addAction(MongoEndpointsImagesBarCell.ACTION_SCALE,
mongoEndpointToScale -> scaleMongoEndpoint(stringMessages,
regionsTable.getSelectionModel().getSelectedObject(), mongoEndpointToScale));
mongoEndpointsTable.addColumn(mongoEndpointsActionColumn);
final CaptionPanel mongoEndpointsCaptionPanel = new CaptionPanel(stringMessages.mongoEndpoints());
final VerticalPanel mongoEndpointsVerticalPanel = new VerticalPanel();
@@ -288,12 +290,13 @@ public class LandscapeManagementPanel extends VerticalPanel implements AwsAccess
}
}
private void scaleMongoEndpoint(StringMessages stringMessages, MongoEndpointDTO mongoEndpointToScale) {
private void scaleMongoEndpoint(StringMessages stringMessages, String selectedRegion, MongoEndpointDTO mongoEndpointToScale) {
new MongoScalingDialog(mongoEndpointToScale, stringMessages, errorReporter, landscapeManagementService, new DialogCallback<MongoScalingInstructionsDTO>() {
@Override
public void ok(MongoScalingInstructionsDTO mongoScalingInstructions) {
mongoEndpointsBusy.setBusy(true);
landscapeManagementService.scaleMongo(mongoScalingInstructions, new AsyncCallback<Void>() {
landscapeManagementService.scaleMongo(awsAccessKeyTextBox.getValue(), awsSecretPasswordTextBox.getValue(), selectedRegion,
mongoScalingInstructions, new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
mongoEndpointsBusy.setBusy(false);
@@ -36,5 +36,5 @@ public interface LandscapeManagementWriteService extends RemoteService {
AmazonMachineImageDTO upgradeAmazonMachineImage(String awsAccessKey, String awsSecret, String region, String machineImageId) throws Exception;
void scaleMongo(MongoScalingInstructionsDTO mongoScalingInstructions);
void scaleMongo(String awsAccessKey, String awsSecret, String region, MongoScalingInstructionsDTO mongoScalingInstructions) throws Exception;
}
@@ -55,5 +55,6 @@ public interface LandscapeManagementWriteServiceAsync {
void upgradeAmazonMachineImage(String awsAccessKey, String awsSecret, String region, String machineImageId,
AsyncCallback<AmazonMachineImageDTO> callback);
void scaleMongo(MongoScalingInstructionsDTO mongoScalingInstructions, AsyncCallback<Void> asyncCallback);
void scaleMongo(String awsAccessKey, String awsSecret, String region,
MongoScalingInstructionsDTO mongoScalingInstructions, AsyncCallback<Void> asyncCallback);
}
@@ -10,7 +10,6 @@ import org.apache.shiro.subject.Subject;
import org.osgi.framework.BundleContext;
import com.jcraft.jsch.JSchException;
import com.sap.sailing.landscape.SailingAnalyticsMetrics;
import com.sap.sailing.landscape.SailingAnalyticsProcess;
import com.sap.sailing.landscape.procedures.UpgradeAmi;
import com.sap.sailing.landscape.ui.client.LandscapeManagementWriteService;
@@ -29,6 +28,7 @@ import com.sap.sse.landscape.application.ApplicationProcessMetrics;
import com.sap.sse.landscape.aws.AmazonMachineImage;
import com.sap.sse.landscape.aws.AwsLandscape;
import com.sap.sse.landscape.aws.impl.AwsRegion;
import com.sap.sse.landscape.aws.orchestration.StartMongoDBServer;
import com.sap.sse.landscape.common.shared.SecuredLandscapeTypes;
import com.sap.sse.landscape.mongodb.MongoEndpoint;
import com.sap.sse.landscape.mongodb.MongoProcess;
@@ -148,7 +148,7 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem
@Override
public ArrayList<SSHKeyPairDTO> getSshKeys(String awsAccessKey, String awsSecret, String regionId) {
final ArrayList<SSHKeyPairDTO> result = new ArrayList<>();
final AwsLandscape<Object, ApplicationProcessMetrics, ?> landscape = AwsLandscape.obtain(awsAccessKey, awsSecret);
final AwsLandscape<String> landscape = AwsLandscape.obtain(awsAccessKey, awsSecret);
final AwsRegion region = new AwsRegion(regionId);
for (final KeyPairInfo keyPairInfo : landscape.getAllKeyPairInfos(region)) {
final SSHKeyPair key = landscape.getSSHKeyPair(region, keyPairInfo.keyName());
@@ -169,7 +169,7 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem
@Override
public byte[] getEncryptedSshPrivateKey(String regionId, String keyName) throws JSchException {
final AwsLandscape<Object, ApplicationProcessMetrics, ?> landscape = AwsLandscape.obtain();
final AwsLandscape<String> landscape = AwsLandscape.obtain();
final SSHKeyPair keyPair = landscape.getSSHKeyPair(new AwsRegion(regionId), keyName);
getSecurityService().checkCurrentUserReadPermission(keyPair);
return keyPair.getEncryptedPrivateKey();
@@ -177,7 +177,7 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem
@Override
public byte[] getSshPublicKey(String regionId, String keyName) throws JSchException {
final AwsLandscape<Object, ApplicationProcessMetrics, ?> landscape = AwsLandscape.obtain();
final AwsLandscape<String> landscape = AwsLandscape.obtain();
final SSHKeyPair keyPair = landscape.getSSHKeyPair(new AwsRegion(regionId), keyName);
getSecurityService().checkCurrentUserReadPermission(keyPair);
return keyPair.getPublicKey();
@@ -189,9 +189,9 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem
new TypeRelativeObjectIdentifier("AWS")));
final ArrayList<AmazonMachineImageDTO> result = new ArrayList<>();
final AwsRegion awsRegion = new AwsRegion(region);
final AwsLandscape<Object, ApplicationProcessMetrics, ?> landscape = AwsLandscape.obtain(awsAccessKey, awsSecret);
final AwsLandscape<String> landscape = AwsLandscape.obtain(awsAccessKey, awsSecret);
for (final String imageType : landscape.getMachineImageTypes(awsRegion)) {
for (final AmazonMachineImage<Object, ApplicationProcessMetrics> machineImage : landscape.getAllImagesWithType(awsRegion, imageType)) {
for (final AmazonMachineImage<String> machineImage : landscape.getAllImagesWithType(awsRegion, imageType)) {
final AmazonMachineImageDTO dto = new AmazonMachineImageDTO(machineImage.getId(),
machineImage.getRegion().getId(), machineImage.getName(), imageType, machineImage.getState().name(),
machineImage.getCreatedAt());
@@ -205,8 +205,8 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem
public void removeAmazonMachineImage(String awsAccessKey, String awsSecret, String region, String machineImageId) {
SecurityUtils.getSubject().checkPermission(SecuredLandscapeTypes.LANDSCAPE.getStringPermissionForTypeRelativeIdentifier(SecuredLandscapeTypes.LandscapeActions.MANAGE,
new TypeRelativeObjectIdentifier("AWS")));
final AwsLandscape<Object, ApplicationProcessMetrics, ?> landscape = AwsLandscape.obtain(awsAccessKey, awsSecret);
final AmazonMachineImage<Object, ApplicationProcessMetrics> ami = landscape.getImage(new AwsRegion(region), machineImageId);
final AwsLandscape<String> landscape = AwsLandscape.obtain(awsAccessKey, awsSecret);
final AmazonMachineImage<String> ami = landscape.getImage(new AwsRegion(region), machineImageId);
ami.delete();
}
@@ -214,9 +214,9 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem
public AmazonMachineImageDTO upgradeAmazonMachineImage(String awsAccessKey, String awsSecret, String region, String machineImageId) throws Exception {
SecurityUtils.getSubject().checkPermission(SecuredLandscapeTypes.LANDSCAPE.getStringPermissionForTypeRelativeIdentifier(SecuredLandscapeTypes.LandscapeActions.MANAGE,
new TypeRelativeObjectIdentifier("AWS")));
final AwsLandscape<String, SailingAnalyticsMetrics, SailingAnalyticsProcess<String>> landscape = AwsLandscape.obtain(awsAccessKey, awsSecret);
final AwsLandscape<String> landscape = AwsLandscape.obtain(awsAccessKey, awsSecret);
final AwsRegion awsRegion = new AwsRegion(region);
final AmazonMachineImage<?, ?> ami = landscape.getImage(awsRegion, machineImageId);
final AmazonMachineImage<String> ami = landscape.getImage(awsRegion, machineImageId);
final UpgradeAmi.Builder<?, String, SailingAnalyticsProcess<String>> upgradeAmiBuilder = UpgradeAmi.builder();
upgradeAmiBuilder
.setLandscape(landscape)
@@ -225,13 +225,29 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem
.setOptionalTimeout(IMAGE_UPGRADE_TIMEOUT);
final UpgradeAmi<String> upgradeAmi = upgradeAmiBuilder.build();
upgradeAmi.run();
final AmazonMachineImage<String, SailingAnalyticsMetrics> resultingAmi = upgradeAmi.getUpgradedAmi();
final AmazonMachineImage<String> resultingAmi = upgradeAmi.getUpgradedAmi();
return new AmazonMachineImageDTO(resultingAmi.getId(), resultingAmi.getRegion().getId(), resultingAmi.getName(), /* TODO type */ null, resultingAmi.getState().name(), resultingAmi.getCreatedAt());
}
@Override
public void scaleMongo(MongoScalingInstructionsDTO mongoScalingInstructions) {
// TODO Implement LandscapeManagementWriteServiceImpl.scaleMongo(...)
public void scaleMongo(String awsAccessKey, String awsSecret, String regionId, MongoScalingInstructionsDTO mongoScalingInstructions) throws Exception {
if (mongoScalingInstructions.getReplicaSetName() == null) {
throw new IllegalArgumentException("Can only scale MongoDB Replica Sets, not standalone instances");
}
final AwsLandscape<String> landscape = AwsLandscape.obtain(awsAccessKey, awsSecret);
final AwsRegion region = new AwsRegion(regionId);
for (int i=0; i<mongoScalingInstructions.getLaunchParameters().getNumberOfInstances(); i++) {
final StartMongoDBServer.Builder<?, String, MongoProcessInReplicaSet> startMongoProcessBuilder = StartMongoDBServer.builder();
final StartMongoDBServer<String, MongoProcessInReplicaSet> startMongoDBServer = startMongoProcessBuilder
.setLandscape(landscape)
.setInstanceType(InstanceType.valueOf(mongoScalingInstructions.getLaunchParameters().getInstanceType()))
.setRegion(region)
.setReplicaSetName(mongoScalingInstructions.getReplicaSetName())
.setReplicaSetPrimary(mongoScalingInstructions.getLaunchParameters().getReplicaSetPrimary())
.setReplicaSetPriority(mongoScalingInstructions.getLaunchParameters().getReplicaSetPriority())
.setReplicaSetVotes(mongoScalingInstructions.getLaunchParameters().getReplicaSetVotes())
.build();
startMongoDBServer.run();
}
}
}
@@ -33,11 +33,11 @@ import com.sap.sse.landscape.ssh.SshCommandChannel;
*
* @author Axel Uhl (D043530)
*/
public class DeployProcessOnMultiServer<ShardingKey, HostT extends AwsInstance<ShardingKey, SailingAnalyticsMetrics>,
public class DeployProcessOnMultiServer<ShardingKey, HostT extends AwsInstance<ShardingKey>,
ApplicationConfigurationT extends SailingAnalyticsApplicationConfiguration<ShardingKey>,
ApplicationConfigurationBuilderT extends SailingAnalyticsApplicationConfiguration.Builder<ApplicationConfigurationBuilderT, ApplicationConfigurationT, ShardingKey>>
extends AbstractProcedureImpl<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>
implements Procedure<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>> {
extends AbstractProcedureImpl<ShardingKey>
implements Procedure<ShardingKey> {
private static final Logger logger = Logger.getLogger(DeployProcessOnMultiServer.class.getName());
private final ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>> hostToDeployTo;
private final ApplicationConfigurationT applicationConfiguration;
@@ -87,19 +87,19 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProce
*
* @author Axel Uhl (D043530)
*/
public static interface Builder<BuilderT extends Builder<BuilderT, ShardingKey, HostT, ApplicationConfigurationT, ApplicationConfigurationBuilderT>, ShardingKey, HostT extends AwsInstance<ShardingKey, SailingAnalyticsMetrics>,
public static interface Builder<BuilderT extends Builder<BuilderT, ShardingKey, HostT, ApplicationConfigurationT, ApplicationConfigurationBuilderT>, ShardingKey, HostT extends AwsInstance<ShardingKey>,
ApplicationConfigurationT extends SailingAnalyticsApplicationConfiguration<ShardingKey>,
ApplicationConfigurationBuilderT extends SailingAnalyticsApplicationConfiguration.Builder<ApplicationConfigurationBuilderT, ApplicationConfigurationT, ShardingKey>>
extends com.sap.sse.landscape.orchestration.Procedure.Builder<BuilderT, DeployProcessOnMultiServer<ShardingKey, HostT, ApplicationConfigurationT, ApplicationConfigurationBuilderT>, ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>> {
extends com.sap.sse.landscape.orchestration.Procedure.Builder<BuilderT, DeployProcessOnMultiServer<ShardingKey, HostT, ApplicationConfigurationT, ApplicationConfigurationBuilderT>, ShardingKey> {
BuilderT setHostToDeployTo(ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>> hostToDeployTo);
BuilderT setKeyName(String keyName);
BuilderT setPrivateKeyEncryptionPassphrase(byte[] privateKeyEncryptionPassphrase);
}
public static class BuilderImpl<BuilderT extends Builder<BuilderT, ShardingKey, HostT, ApplicationConfigurationT, ApplicationConfigurationBuilderT>, ShardingKey, HostT extends AwsInstance<ShardingKey, SailingAnalyticsMetrics>,
public static class BuilderImpl<BuilderT extends Builder<BuilderT, ShardingKey, HostT, ApplicationConfigurationT, ApplicationConfigurationBuilderT>, ShardingKey, HostT extends AwsInstance<ShardingKey>,
ApplicationConfigurationT extends SailingAnalyticsApplicationConfiguration<ShardingKey>,
ApplicationConfigurationBuilderT extends SailingAnalyticsApplicationConfiguration.Builder<ApplicationConfigurationBuilderT, ApplicationConfigurationT, ShardingKey>>
extends com.sap.sse.landscape.orchestration.AbstractProcedureImpl.BuilderImpl<BuilderT, DeployProcessOnMultiServer<ShardingKey, HostT, ApplicationConfigurationT, ApplicationConfigurationBuilderT>, ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>
extends com.sap.sse.landscape.orchestration.AbstractProcedureImpl.BuilderImpl<BuilderT, DeployProcessOnMultiServer<ShardingKey, HostT, ApplicationConfigurationT, ApplicationConfigurationBuilderT>, ShardingKey>
implements Builder<BuilderT, ShardingKey, HostT, ApplicationConfigurationT, ApplicationConfigurationBuilderT> {
private final SailingAnalyticsApplicationConfiguration.BuilderImpl<ApplicationConfigurationBuilderT, ApplicationConfigurationT, ShardingKey> applicationConfigurationBuilder;
private ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>> hostToDeployTo;
@@ -178,8 +178,8 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProce
* Expose to subclasses
*/
@Override
protected AwsLandscape<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>> getLandscape() {
return (AwsLandscape<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>) super.getLandscape();
protected AwsLandscape<ShardingKey> getLandscape() {
return (AwsLandscape<ShardingKey>) super.getLandscape();
}
@Override
@@ -225,7 +225,7 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProce
}
}
public static <BuilderT extends Builder<BuilderT, ShardingKey, HostT, ApplicationConfigurationT, ApplicationConfigurationBuilderT>, ShardingKey, HostT extends AwsInstance<ShardingKey, SailingAnalyticsMetrics>,
public static <BuilderT extends Builder<BuilderT, ShardingKey, HostT, ApplicationConfigurationT, ApplicationConfigurationBuilderT>, ShardingKey, HostT extends AwsInstance<ShardingKey>,
ApplicationConfigurationT extends SailingAnalyticsApplicationConfiguration<ShardingKey>,
ApplicationConfigurationBuilderT extends SailingAnalyticsApplicationConfiguration.Builder<ApplicationConfigurationBuilderT, ApplicationConfigurationT, ShardingKey>>
Builder<BuilderT, ShardingKey, HostT, ApplicationConfigurationT, ApplicationConfigurationBuilderT> builder(ApplicationConfigurationBuilderT applicationConfigurationBuilder) {
@@ -133,7 +133,7 @@ extends AwsApplicationConfiguration<ShardingKey, SailingAnalyticsMetrics, Sailin
* Expose for callers in same package as this class
*/
@Override
protected AwsLandscape<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>> getLandscape() {
protected AwsLandscape<ShardingKey> getLandscape() {
return super.getLandscape();
}
@@ -4,7 +4,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import com.sap.sailing.landscape.SailingAnalyticsMetrics;
import com.sap.sse.landscape.DefaultProcessConfigurationVariables;
import com.sap.sse.landscape.InboundReplicationConfiguration;
import com.sap.sse.landscape.OutboundReplicationConfiguration;
@@ -82,7 +81,7 @@ extends SailingAnalyticsApplicationConfiguration<ShardingKey> {
}
public static <BuilderT extends Builder<BuilderT, ShardingKey>,
ShardingKey extends AwsInstance<ShardingKey, SailingAnalyticsMetrics>> BuilderT replicaBuilder() {
ShardingKey extends AwsInstance<ShardingKey>> BuilderT replicaBuilder() {
@SuppressWarnings("unchecked")
final BuilderT result = (BuilderT) new BuilderImpl<BuilderT, ShardingKey>();
return result;
@@ -37,9 +37,7 @@ import software.amazon.awssdk.services.ec2.model.InstanceType;
* @param <SailingAnalyticsHost<ShardingKey>>
*/
public class StartMultiServer<ShardingKey>
extends StartEmptyServer<StartMultiServer<ShardingKey>, ShardingKey, SailingAnalyticsMetrics,
SailingAnalyticsProcess<ShardingKey>, ApplicationProcessHost<ShardingKey,
SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>>
extends StartEmptyServer<StartMultiServer<ShardingKey>, ShardingKey, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>>
implements StartFromSailingAnalyticsImage {
private static final Logger logger = Logger.getLogger(StartMultiServer.class.getName());
private Optional<Duration> optionalTimeout;
@@ -56,13 +54,12 @@ implements StartFromSailingAnalyticsImage {
* @author Axel Uhl (D043530)
*/
public static interface Builder<BuilderT extends Builder<BuilderT, ShardingKey>, ShardingKey>
extends StartEmptyServer.Builder<BuilderT, StartMultiServer<ShardingKey>, ShardingKey,
SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>> {
extends StartEmptyServer.Builder<BuilderT, StartMultiServer<ShardingKey>, ShardingKey, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>> {
}
protected static class BuilderImpl<BuilderT extends Builder<BuilderT, ShardingKey>, ShardingKey>
extends StartEmptyServer.BuilderImpl<BuilderT, StartMultiServer<ShardingKey>,
ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>>
ShardingKey, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>>
implements Builder<BuilderT, ShardingKey> {
@Override
public StartMultiServer<ShardingKey> build() {
@@ -91,8 +88,8 @@ implements StartFromSailingAnalyticsImage {
}
@Override
protected HostSupplier<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>> getHostSupplier() {
final HostSupplier<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>> result;
protected HostSupplier<ShardingKey, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>> getHostSupplier() {
final HostSupplier<ShardingKey, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>> result;
if (super.getHostSupplier() == null) {
result = (instanceId, az, landscape)->
new ApplicationProcessHostImpl<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>(instanceId, az, landscape, (host, serverDirectory)->{
@@ -33,7 +33,7 @@ import com.sap.sse.landscape.orchestration.Procedure;
*/
public class StartSailingAnalyticsHost<ShardingKey>
extends StartAwsApplicationHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>>
implements Procedure<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>,
implements Procedure<ShardingKey>,
StartFromSailingAnalyticsImage {
public static final Logger logger = Logger.getLogger(StartSailingAnalyticsHost.class.getName());
private final static String INSTANCE_NAME_DEFAULT_PREFIX = "SL ";
@@ -86,8 +86,8 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProce
}
@Override
protected HostSupplier<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>> getHostSupplier() {
return (String instanceId, AwsAvailabilityZone az, AwsLandscape<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>> landscape)->
protected HostSupplier<ShardingKey, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>> getHostSupplier() {
return (String instanceId, AwsAvailabilityZone az, AwsLandscape<ShardingKey> landscape)->
new ApplicationProcessHostImpl<>(instanceId, az, landscape,
(host, serverDirectory)->{
try {
@@ -58,8 +58,8 @@ import software.amazon.awssdk.services.ec2.model.InstanceType;
* @param <HostT>
*/
public class UpgradeAmi<ShardingKey>
extends StartEmptyServer<UpgradeAmi<ShardingKey>, ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>>
implements Procedure<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>, StartFromSailingAnalyticsImage {
extends StartEmptyServer<UpgradeAmi<ShardingKey>, ShardingKey, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>>
implements Procedure<ShardingKey>, StartFromSailingAnalyticsImage {
private static final Logger logger = Logger.getLogger(UpgradeAmi.class.getName());
private static final Pattern imageNamePattern = Pattern.compile("^(.*) ([0-9]+)\\.([0-9]+)(\\.([0-9]+))?$");
@@ -70,7 +70,7 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProce
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;
private AmazonMachineImage<ShardingKey> upgradedAmi;
/**
* Additional default rules in addition to what the {@link StartAwsHost.Builder parent builder} defines:
@@ -106,7 +106,7 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProce
*/
public static interface Builder<BuilderT extends Builder<BuilderT, ShardingKey, SailingAnalyticsProcess<ShardingKey>>, ShardingKey,
ProcessT extends ApplicationProcess<ShardingKey, SailingAnalyticsMetrics, ProcessT>>
extends StartEmptyServer.Builder<BuilderT, UpgradeAmi<ShardingKey>, ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>> {
extends StartEmptyServer.Builder<BuilderT, UpgradeAmi<ShardingKey>, ShardingKey, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>> {
enum VersionPart {
MAJOR, MINOR, MICRO
}
@@ -126,7 +126,7 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProce
}
protected static class BuilderImpl<BuilderT extends Builder<BuilderT, ShardingKey, SailingAnalyticsProcess<ShardingKey>>, ShardingKey>
extends StartEmptyServer.BuilderImpl<BuilderT, UpgradeAmi<ShardingKey>, ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>>
extends StartEmptyServer.BuilderImpl<BuilderT, UpgradeAmi<ShardingKey>, ShardingKey, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>>
implements Builder<BuilderT, ShardingKey, SailingAnalyticsProcess<ShardingKey>> {
private String upgradedImageName;
private VersionPart versionPartToIncrement;
@@ -248,8 +248,8 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProce
}
@Override
public HostSupplier<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>> getHostSupplier() {
return (String instanceId, AwsAvailabilityZone az, AwsLandscape<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>> landscape)->
public HostSupplier<ShardingKey, ApplicationProcessHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProcess<ShardingKey>>> getHostSupplier() {
return (String instanceId, AwsAvailabilityZone az, AwsLandscape<ShardingKey> landscape)->
new ApplicationProcessHostImpl<>(instanceId, az, landscape,
(host, serverDirectory)->{
try {
@@ -293,7 +293,7 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProce
}
public static <BuilderT extends Builder<BuilderT, ShardingKey, SailingAnalyticsProcess<ShardingKey>>, ShardingKey,
HostT extends AwsInstance<ShardingKey, SailingAnalyticsMetrics>> Builder<BuilderT, ShardingKey, SailingAnalyticsProcess<ShardingKey>> builder() {
HostT extends AwsInstance<ShardingKey>> Builder<BuilderT, ShardingKey, SailingAnalyticsProcess<ShardingKey>> builder() {
return new BuilderImpl<>();
}
@@ -368,7 +368,7 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsProce
/**
* @return the resulting AMI that has the upgraded version of everything
*/
public AmazonMachineImage<ShardingKey, SailingAnalyticsMetrics> getUpgradedAmi() {
public AmazonMachineImage<ShardingKey> getUpgradedAmi() {
return upgradedAmi;
}
}
@@ -71,7 +71,7 @@ import software.amazon.awssdk.services.route53.model.RRType;
public class ConnectivityTest<ProcessT extends ApplicationProcess<String, SailingAnalyticsMetrics, ProcessT>> {
private static final Logger logger = Logger.getLogger(ConnectivityTest.class.getName());
private static final Optional<Duration> optionalTimeout = Optional.of(Duration.ONE_MINUTE.times(5));
private AwsLandscape<String, SailingAnalyticsMetrics, ProcessT> landscape;
private AwsLandscape<String> landscape;
private AwsRegion region;
private byte[] keyPass;
private String AXELS_KEY_PASS;
@@ -153,7 +153,7 @@ public class ConnectivityTest<ProcessT extends ApplicationProcess<String, Sailin
public void testApacheProxyBasics() throws Exception {
final ReverseProxyCluster<String, SailingAnalyticsMetrics, ProcessT, RotatingFileBasedLog> proxy = landscape.getCentralReverseProxy(region);
final String hostname = "kw2021.sapsailing.com";
final AwsInstance<String, SailingAnalyticsMetrics> proxyHost = proxy.getHosts().iterator().next();
final AwsInstance<String> proxyHost = proxy.getHosts().iterator().next();
final ProcessT process = createApplicationProcess(proxyHost);
proxy.setEventRedirect(hostname, process, UUID.randomUUID(), /* optional SSH key name */ Optional.empty(), AXELS_KEY_PASS.getBytes());
final ByteArrayOutputStream configFileContents = new ByteArrayOutputStream();
@@ -169,7 +169,7 @@ public class ConnectivityTest<ProcessT extends ApplicationProcess<String, Sailin
assertTrue(lsOutput.isEmpty());
}
protected ProcessT createApplicationProcess(final AwsInstance<String, SailingAnalyticsMetrics> host) {
protected ProcessT createApplicationProcess(final AwsInstance<String> host) {
@SuppressWarnings("unchecked")
final ProcessT process = (ProcessT) new SailingAnalyticsProcessImpl<String>(8888, host, ApplicationProcessHost.DEFAULT_SERVER_PATH);
return process;
@@ -183,7 +183,7 @@ public class ConnectivityTest<ProcessT extends ApplicationProcess<String, Sailin
final String keyName = "MyKey-"+UUID.randomUUID();
createKeyPair(keyName);
final MongoEndpoint mongoEndpoint = landscape.getMongoEndpoints(region).iterator().next();
final AwsInstance<String, SailingAnalyticsMetrics> host = landscape.launchHost(
final AwsInstance<String> host = landscape.launchHost(
getLatestSailingImage(),
InstanceType.T3_SMALL, landscape.getAvailabilityZoneByName(region, "eu-west-2b"), keyName, Collections.singleton(()->"sg-0b2afd48960251280"),
Optional.of(Tags.with("Name", "MyHost").and("Hello", "World")),
@@ -213,15 +213,15 @@ public class ConnectivityTest<ProcessT extends ApplicationProcess<String, Sailin
final Release release = process.getRelease(new ReleaseRepositoryImpl("http://releases.sapsailing.com", "build"), optionalTimeout, /* optional SSH key name */ Optional.empty(), keyPass);
assertNotNull(release);
assertEquals(14888, process.getTelnetPortToOSGiConsole(optionalTimeout, /* optional SSH key name */ Optional.empty(), keyPass));
final AwsLandscape<String, SailingAnalyticsMetrics, ProcessT> castLandscape = (AwsLandscape<String, SailingAnalyticsMetrics, ProcessT>) landscape;
final CreateDNSBasedLoadBalancerMapping.Builder<?, ?, String, SailingAnalyticsMetrics, ProcessT, AwsInstance<String, SailingAnalyticsMetrics>> builder = CreateDNSBasedLoadBalancerMapping.builder();
final AwsLandscape<String> castLandscape = (AwsLandscape<String>) landscape;
final CreateDNSBasedLoadBalancerMapping.Builder<?, ?, String, SailingAnalyticsMetrics, ProcessT> builder = CreateDNSBasedLoadBalancerMapping.builder();
builder
.setProcess(process)
.setHostname(hostname)
.setTargetGroupNamePrefix(TARGET_GROUP_NAME_PREFIX)
.setLandscape(castLandscape);
optionalTimeout.ifPresent(builder::setTimeout);
final CreateDNSBasedLoadBalancerMapping<String, SailingAnalyticsMetrics, ProcessT, AwsInstance<String, SailingAnalyticsMetrics>> createDNSBasedLoadBalancerMappingProcedure =
final CreateDNSBasedLoadBalancerMapping<String, SailingAnalyticsMetrics, ProcessT> createDNSBasedLoadBalancerMappingProcedure =
builder.build();
final String wiesenWegId = landscape.getDNSHostedZoneId(hostedZoneName);
try {
@@ -241,7 +241,7 @@ public class ConnectivityTest<ProcessT extends ApplicationProcess<String, Sailin
}
}
private AmazonMachineImage<String, SailingAnalyticsMetrics> getLatestSailingImage() {
private AmazonMachineImage<String> getLatestSailingImage() {
return landscape.getLatestImageWithTag(region, "image-type", StartFromSailingAnalyticsImage.IMAGE_TYPE_TAG_VALUE_SAILING);
}
@@ -348,7 +348,7 @@ public class ConnectivityTest<ProcessT extends ApplicationProcess<String, Sailin
}
private void testSshConnectWithKey(final String keyName) throws Exception {
final AwsInstance<String, SailingAnalyticsMetrics> host = landscape.launchHost(getLatestSailingImage(),
final AwsInstance<String> host = landscape.launchHost(getLatestSailingImage(),
InstanceType.T3_SMALL, landscape.getAvailabilityZoneByName(region, "eu-west-2b"), keyName, Collections.singleton(()->"sg-0b2afd48960251280"), /* tags */ Optional.empty());
try {
assertNotNull(host);
@@ -387,7 +387,7 @@ public class ConnectivityTest<ProcessT extends ApplicationProcess<String, Sailin
@Test
public void testImageDate() throws ParseException {
final AmazonMachineImage<String, SailingAnalyticsMetrics> image = landscape.getImage(region, "ami-0c0907685eae2dbab");
final AmazonMachineImage<String> image = landscape.getImage(region, "ami-0c0907685eae2dbab");
assertEquals(TimePoint.of(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz").parse(
/* November 9, 2020 at 9:37:16 PM UTC+1 */ "2020-11-09T21:37:16+0100")),
image.getCreatedAt());
@@ -416,7 +416,7 @@ public class ConnectivityTest<ProcessT extends ApplicationProcess<String, Sailin
@Test
public void createEmptyLoadBalancerTest() throws InterruptedException {
final String albName = "MyAlb"+new Random().nextInt();
final ApplicationLoadBalancer<String, SailingAnalyticsMetrics> alb = landscape.createLoadBalancer(albName, region);
final ApplicationLoadBalancer<String> alb = landscape.createLoadBalancer(albName, region);
try {
assertNotNull(alb);
assertEquals(albName, alb.getName());
@@ -439,9 +439,9 @@ public class ConnectivityTest<ProcessT extends ApplicationProcess<String, Sailin
@Test
public void createAndDeleteTargetGroupTest() {
final String targetGroupName = "TestTargetGroup-"+new Random().nextInt();
final TargetGroup<String, SailingAnalyticsMetrics> targetGroup = landscape.createTargetGroup(region, targetGroupName, 80, "/gwt/status", 80);
final TargetGroup<String> targetGroup = landscape.createTargetGroup(region, targetGroupName, 80, "/gwt/status", 80);
try {
final TargetGroup<String, SailingAnalyticsMetrics> fetchedTargetGroup = landscape.getTargetGroup(region, targetGroupName, targetGroup.getTargetGroupArn());
final TargetGroup<String> fetchedTargetGroup = landscape.getTargetGroup(region, targetGroupName, targetGroup.getTargetGroupArn());
assertEquals(targetGroupName, fetchedTargetGroup.getName());
} finally {
landscape.deleteTargetGroup(targetGroup);
@@ -1,12 +1,11 @@
package com.sap.sse.landscape.aws;
import com.sap.sse.landscape.MachineImage;
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
import software.amazon.awssdk.services.ec2.model.BlockDeviceMapping;
import software.amazon.awssdk.services.ec2.model.ImageState;
public interface AmazonMachineImage<ShardingKey, MetricsT extends ApplicationProcessMetrics> extends MachineImage {
public interface AmazonMachineImage<ShardingKey> extends MachineImage {
Iterable<BlockDeviceMapping> getBlockDeviceMappings();
@Override
@@ -2,7 +2,6 @@ package com.sap.sse.landscape.aws;
import com.sap.sse.common.Named;
import com.sap.sse.landscape.Region;
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
import software.amazon.awssdk.services.elasticloadbalancingv2.model.Listener;
import software.amazon.awssdk.services.elasticloadbalancingv2.model.Rule;
@@ -29,7 +28,7 @@ import software.amazon.awssdk.services.elasticloadbalancingv2.model.Rule;
* @author Axel Uhl (D043530)
*
*/
public interface ApplicationLoadBalancer<ShardingKey, MetricsT extends ApplicationProcessMetrics> extends Named {
public interface ApplicationLoadBalancer<ShardingKey> extends Named {
/**
* The DNS name of this load balancer; can be used, e.g., to set a CNAME DNS record pointing
* to this load balancer.
@@ -77,7 +76,7 @@ public interface ApplicationLoadBalancer<ShardingKey, MetricsT extends Applicati
*/
Iterable<Rule> addRulesAssigningUnusedPriorities(boolean forceContiguous, Rule... rules);
Iterable<TargetGroup<ShardingKey, MetricsT>> getTargetGroups();
Iterable<TargetGroup<ShardingKey>> getTargetGroups();
/**
* Deletes this application load balancer and all its {@link #getTargetGroups target groups}.
@@ -11,7 +11,7 @@ import com.sap.sse.landscape.application.Scope;
public interface ApplicationProcessHost<ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends AwsInstance<ShardingKey, MetricsT> {
extends AwsInstance<ShardingKey> {
String DEFAULT_SERVERS_PATH = "/home/sailing/servers";
String DEFAULT_SERVER_DIRECTORY_NAME = "server";
@@ -36,5 +36,5 @@ extends AwsInstance<ShardingKey, MetricsT> {
*/
Iterable<ProcessT> getApplicationProcesses(Optional<Duration> optionalTimeout, Optional<String> optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception;
AwsLandscape<ShardingKey, MetricsT, ProcessT> getLandscape();
AwsLandscape<ShardingKey> getLandscape();
}
@@ -2,7 +2,6 @@ package com.sap.sse.landscape.aws;
import com.sap.sse.landscape.Host;
import com.sap.sse.landscape.MachineImage;
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
import com.sap.sse.landscape.aws.impl.AwsRegion;
/**
@@ -12,7 +11,7 @@ import com.sap.sse.landscape.aws.impl.AwsRegion;
* @author Axel Uhl (D043530)
*
*/
public interface AwsInstance<ShardingKey, MetricsT extends ApplicationProcessMetrics> extends Host {
public interface AwsInstance<ShardingKey> extends Host {
String getInstanceId();
void terminate();
@@ -75,9 +75,7 @@ import software.amazon.awssdk.services.route53.model.RRType;
* @param <ShardingKey>
* @param <MetricsT>
*/
public interface AwsLandscape<ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends Landscape<ShardingKey, MetricsT, ProcessT> {
public interface AwsLandscape<ShardingKey> extends Landscape<ShardingKey> {
String ACCESS_KEY_ID_SYSTEM_PROPERTY_NAME = "com.sap.sse.landscape.aws.accesskeyid";
String SECRET_ACCESS_KEY_SYSTEM_PROPERTY_NAME = "com.sap.sse.landscape.aws.secretaccesskey";
@@ -124,8 +122,8 @@ extends Landscape<ShardingKey, MetricsT, ProcessT> {
*/
static <ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
AwsLandscape<ShardingKey, MetricsT, ProcessT> obtain() {
final AwsLandscape<ShardingKey, MetricsT, ProcessT> result = new AwsLandscapeImpl<>(Activator.getInstance().getLandscapeState());
AwsLandscape<ShardingKey> obtain() {
final AwsLandscape<ShardingKey> result = new AwsLandscapeImpl<>(Activator.getInstance().getLandscapeState());
return result;
}
@@ -136,16 +134,16 @@ extends Landscape<ShardingKey, MetricsT, ProcessT> {
*/
static <ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
AwsLandscape<ShardingKey, MetricsT, ProcessT> obtain(String accessKey, String secret) {
final AwsLandscape<ShardingKey, MetricsT, ProcessT> result = new AwsLandscapeImpl<>(Activator.getInstance().getLandscapeState(), accessKey, secret);
AwsLandscape<ShardingKey> obtain(String accessKey, String secret) {
final AwsLandscape<ShardingKey> result = new AwsLandscapeImpl<>(Activator.getInstance().getLandscapeState(), accessKey, secret);
return result;
}
default AwsInstance<ShardingKey, MetricsT> launchHost(MachineImage image, InstanceType instanceType,
default AwsInstance<ShardingKey> launchHost(MachineImage image, InstanceType instanceType,
AwsAvailabilityZone availabilityZone, String keyName, Iterable<SecurityGroup> securityGroups,
Optional<Tags> tags, String... userData) {
final HostSupplier<ShardingKey, MetricsT, ProcessT, AwsInstance<ShardingKey, MetricsT>> hostSupplier =
(instanceId, az, landscape)->new AwsInstanceImpl<ShardingKey, MetricsT>(instanceId, az, landscape);
final HostSupplier<ShardingKey, AwsInstance<ShardingKey>> hostSupplier =
(instanceId, az, landscape)->new AwsInstanceImpl<ShardingKey>(instanceId, az, landscape);
return launchHost(hostSupplier, image, instanceType, availabilityZone, keyName, securityGroups, tags, userData);
}
@@ -160,8 +158,8 @@ extends Landscape<ShardingKey, MetricsT, ProcessT> {
* concatenated, using the line separator to join them. The instance is able to read the user data throuh
* the AWS SDK installed on the instance.
*/
default <HostT extends AwsInstance<ShardingKey, MetricsT>> HostT launchHost(
HostSupplier<ShardingKey, MetricsT, ProcessT, HostT> hostSupplier,
default <HostT extends AwsInstance<ShardingKey>> HostT launchHost(
HostSupplier<ShardingKey, HostT> hostSupplier,
MachineImage fromImage, InstanceType instanceType, AwsAvailabilityZone az, String keyName,
Iterable<SecurityGroup> securityGroups, Optional<Tags> tags, String... userData) {
return launchHosts(hostSupplier, /* numberOfHostsToLaunch */ 1, fromImage, instanceType, az, keyName,
@@ -177,27 +175,27 @@ extends Landscape<ShardingKey, MetricsT, ProcessT> {
* the SSH key pair name to use when launching; this will grant root access with the corresponding
* private key; see also {@link #getKeyPairInfo(Region, String)}
*/
<HostT extends AwsInstance<ShardingKey, MetricsT>> Iterable<HostT> launchHosts(
HostSupplier<ShardingKey, MetricsT, ProcessT, HostT> hostSupplier, int numberOfHostsToLaunch,
<HostT extends AwsInstance<ShardingKey>> Iterable<HostT> launchHosts(
HostSupplier<ShardingKey, HostT> hostSupplier, int numberOfHostsToLaunch,
MachineImage fromImage, InstanceType instanceType,
AwsAvailabilityZone az, String keyName, Iterable<SecurityGroup> securityGroups, Optional<Tags> tags,
String... userData);
AmazonMachineImage<ShardingKey, MetricsT> getImage(Region region, String imageId);
AmazonMachineImage<ShardingKey> getImage(Region region, String imageId);
AmazonMachineImage<ShardingKey, MetricsT> createImage(AwsInstance<ShardingKey, MetricsT> instance, String imageName, Optional<Tags> tags);
AmazonMachineImage<ShardingKey> createImage(AwsInstance<ShardingKey> instance, String imageName, Optional<Tags> tags);
void deleteImage(Region region, String imageId);
AmazonMachineImage<ShardingKey, MetricsT> getLatestImageWithTag(Region region, String tagName, String tagValue);
AmazonMachineImage<ShardingKey> getLatestImageWithTag(Region region, String tagName, String tagValue);
default AmazonMachineImage<ShardingKey, MetricsT> getLatestImageWithType(Region region, String imageType) {
default AmazonMachineImage<ShardingKey> getLatestImageWithType(Region region, String imageType) {
return getLatestImageWithTag(region, IMAGE_TYPE_TAG_NAME, imageType);
}
Iterable<AmazonMachineImage<ShardingKey, MetricsT>> getAllImagesWithTag(Region region, String tagName, String tagValue);
Iterable<AmazonMachineImage<ShardingKey>> getAllImagesWithTag(Region region, String tagName, String tagValue);
default Iterable<AmazonMachineImage<ShardingKey, MetricsT>> getAllImagesWithType(Region region, String imageType) {
default Iterable<AmazonMachineImage<ShardingKey>> getAllImagesWithType(Region region, String imageType) {
return getAllImagesWithTag(region, IMAGE_TYPE_TAG_NAME, imageType);
}
@@ -216,7 +214,7 @@ extends Landscape<ShardingKey, MetricsT, ProcessT> {
*
* @see #getRunningHostsWithTagValue(Region, String)
*/
Iterable<AwsInstance<ShardingKey, MetricsT>> getHostsWithTagValue(Region region, String tagName, String tagValue);
Iterable<AwsInstance<ShardingKey>> getHostsWithTagValue(Region region, String tagName, String tagValue);
/**
* Finds EC2 instances in the {@code region} that have a tag named {@code tagName}. The tag may have any value. The
@@ -224,19 +222,19 @@ extends Landscape<ShardingKey, MetricsT, ProcessT> {
*
* @see #getRunningHostsWithTag(Region, String)
*/
Iterable<AwsInstance<ShardingKey, MetricsT>> getHostsWithTag(Region region, String tagName);
Iterable<AwsInstance<ShardingKey>> getHostsWithTag(Region region, String tagName);
/**
* Finds EC2 instances in the {@code region} that have a tag named {@code tagName}. The tag may have any value. The
* instances returned have been in state RUNNING at the time of the request.
*/
Iterable<AwsInstance<ShardingKey, MetricsT>> getRunningHostsWithTag(Region region, String tagName);
Iterable<AwsInstance<ShardingKey>> getRunningHostsWithTag(Region region, String tagName);
/**
* Finds EC2 instances in the {@code region} that have a tag named {@code tagName} with value {@code tagValue}. The
* instances returned have been in state RUNNING at the time of the request.
*/
Iterable<AwsInstance<ShardingKey, MetricsT>> getRunningHostsWithTagValue(Region region, String tagName,
Iterable<AwsInstance<ShardingKey>> getRunningHostsWithTagValue(Region region, String tagName,
String tagValue);
KeyPairInfo getKeyPairInfo(Region region, String keyName);
@@ -253,7 +251,7 @@ extends Landscape<ShardingKey, MetricsT, ProcessT> {
*/
SSHKeyPair importKeyPair(Region region, byte[] publicKey, byte[] encryptedPrivateKey, String keyName) throws JSchException;
void terminate(AwsInstance<ShardingKey, MetricsT> host);
void terminate(AwsInstance<ShardingKey> host);
/**
* The calling subject must have {@code READ} permission for the key requested.
@@ -309,7 +307,7 @@ extends Landscape<ShardingKey, MetricsT, ProcessT> {
* @param hostname
* the fully-qualified host name
*/
ChangeInfo setDNSRecordToApplicationLoadBalancer(String hostedZoneId, String hostname, ApplicationLoadBalancer<ShardingKey, MetricsT> alb);
ChangeInfo setDNSRecordToApplicationLoadBalancer(String hostedZoneId, String hostname, ApplicationLoadBalancer<ShardingKey> alb);
String getDNSHostedZoneId(String hostedZoneName);
@@ -340,22 +338,22 @@ extends Landscape<ShardingKey, MetricsT, ProcessT> {
ChangeInfo getUpdatedChangeInfo(ChangeInfo changeInfo);
Iterable<ApplicationLoadBalancer<ShardingKey, MetricsT>> getLoadBalancers(Region region);
Iterable<ApplicationLoadBalancer<ShardingKey>> getLoadBalancers(Region region);
ApplicationLoadBalancer<ShardingKey, MetricsT> getLoadBalancer(String loadBalancerArn, Region region);
ApplicationLoadBalancer<ShardingKey> getLoadBalancer(String loadBalancerArn, Region region);
ApplicationLoadBalancer<ShardingKey, MetricsT> getLoadBalancerByName(String name, Region region);
ApplicationLoadBalancer<ShardingKey> getLoadBalancerByName(String name, Region region);
/**
* Creates an application load balancer with the name and in the region specified. The method returns once the request
* has been responded to. The load balancer may still be in a pre-ready state. Use {@link #getApplicationLoadBalancerStatus(ApplicationLoadBalancer)}
* to find out more.
*/
ApplicationLoadBalancer<ShardingKey, MetricsT> createLoadBalancer(String name, Region region);
ApplicationLoadBalancer<ShardingKey> createLoadBalancer(String name, Region region);
Iterable<Listener> getListeners(ApplicationLoadBalancer<ShardingKey, MetricsT> alb);
Iterable<Listener> getListeners(ApplicationLoadBalancer<ShardingKey> alb);
LoadBalancerState getApplicationLoadBalancerStatus(ApplicationLoadBalancer<ShardingKey, MetricsT> alb);
LoadBalancerState getApplicationLoadBalancerStatus(ApplicationLoadBalancer<ShardingKey> alb);
Iterable<AvailabilityZone> getAvailabilityZones(Region awsRegion);
@@ -365,13 +363,13 @@ extends Landscape<ShardingKey, MetricsT, ProcessT> {
* Deletes this load balancer and all its target groups (the target groups to which this load balancer currently
* forwards any traffic).
*/
void deleteLoadBalancer(ApplicationLoadBalancer<ShardingKey, MetricsT> alb);
void deleteLoadBalancer(ApplicationLoadBalancer<ShardingKey> alb);
/**
* All target groups that have the load balancer identified by the ARN as "their" load balancer which means that
* this load balancer is forwarding traffic to all those target groups.
*/
Iterable<TargetGroup<ShardingKey, MetricsT>> getTargetGroupsByLoadBalancerArn(Region region, String loadBalancerArn);
Iterable<TargetGroup<ShardingKey>> getTargetGroupsByLoadBalancerArn(Region region, String loadBalancerArn);
/**
* Looks up a target group by its name in a region. The main reason is to obtain the target group's ARN in order to
@@ -380,17 +378,17 @@ extends Landscape<ShardingKey, MetricsT, ProcessT> {
* @return {@code null} if no target group named according to the value of {@code targetGroupName} is found in the
* {@code region}
*/
TargetGroup<ShardingKey, MetricsT> getTargetGroup(Region region, String targetGroupName);
TargetGroup<ShardingKey> getTargetGroup(Region region, String targetGroupName);
/**
* Creates a target group with a default configuration that includes a health check URL. Stickiness is enabled with
* the default duration of one day. The load balancing algorithm is set to {@code least_outstanding_requests}.
* The protocol (HTTP or HTTPS) is inferred from the port: 443 means HTTPS; anything else means HTTP.
*/
TargetGroup<ShardingKey, MetricsT> createTargetGroup(Region region, String targetGroupName, int port,
TargetGroup<ShardingKey> createTargetGroup(Region region, String targetGroupName, int port,
String healthCheckPath, int healthCheckPort);
default TargetGroup<ShardingKey, MetricsT> getTargetGroup(Region region, String targetGroupName, String targetGroupArn) {
default TargetGroup<ShardingKey> getTargetGroup(Region region, String targetGroupName, String targetGroupArn) {
return new AwsTargetGroupImpl<>(this, region, targetGroupName, targetGroupArn);
}
@@ -398,9 +396,9 @@ extends Landscape<ShardingKey, MetricsT, ProcessT> {
software.amazon.awssdk.services.elasticloadbalancingv2.model.TargetGroup getAwsTargetGroupByArn(Region region, String targetGroupArn);
Map<AwsInstance<ShardingKey, MetricsT>, TargetHealth> getTargetHealthDescriptions(TargetGroup<ShardingKey, MetricsT> targetGroup);
Map<AwsInstance<ShardingKey>, TargetHealth> getTargetHealthDescriptions(TargetGroup<ShardingKey> targetGroup);
<SK, MT extends ApplicationProcessMetrics> void deleteTargetGroup(TargetGroup<SK, MT> targetGroup);
<SK> void deleteTargetGroup(TargetGroup<SK> targetGroup);
Iterable<Rule> getLoadBalancerListenerRules(Listener loadBalancerListener, Region region);
@@ -422,12 +420,12 @@ extends Landscape<ShardingKey, MetricsT, ProcessT> {
SecurityGroup getSecurityGroup(String securityGroupId, Region region);
void addTargetsToTargetGroup(
TargetGroup<ShardingKey, MetricsT> targetGroup,
Iterable<AwsInstance<ShardingKey, MetricsT>> targets);
TargetGroup<ShardingKey> targetGroup,
Iterable<AwsInstance<ShardingKey>> targets);
void removeTargetsFromTargetGroup(
TargetGroup<ShardingKey, MetricsT> targetGroup,
Iterable<AwsInstance<ShardingKey, MetricsT>> targets);
TargetGroup<ShardingKey> targetGroup,
Iterable<AwsInstance<ShardingKey>> targets);
LoadBalancer getAwsLoadBalancer(String loadBalancerArn, Region region);
@@ -438,6 +436,7 @@ extends Landscape<ShardingKey, MetricsT, ProcessT> {
* dedicated load balancer rule, such as "cold storage" hostnames that have been archived. May return {@code null}
* in case in the given {@code region} no such reverse proxy has been configured / set up yet.
*/
<MetricsT extends ApplicationProcessMetrics, ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
ReverseProxyCluster<ShardingKey, MetricsT, ProcessT, RotatingFileBasedLog> getCentralReverseProxy(Region region);
/**
@@ -454,7 +453,7 @@ extends Landscape<ShardingKey, MetricsT, ProcessT> {
* @param wildcardDomain e.g., "sapsailing.com" without leading and without trailing dot
*
*/
ApplicationLoadBalancer<ShardingKey, MetricsT> getNonDNSMappedLoadBalancer(Region region, String wildcardDomain);
ApplicationLoadBalancer<ShardingKey> getNonDNSMappedLoadBalancer(Region region, String wildcardDomain);
/**
* Creates an application load balancer (ALB) intended to serve requests for dynamically-mapped sub-domains where
@@ -462,13 +461,13 @@ extends Landscape<ShardingKey, MetricsT, ProcessT> {
* {@link #getNonDNSMappedLoadBalancer(Region, String)}, when called with an equal {@code wildcardDomain} and
* {@code region}, will deliver the load balancer created by this call.
*/
ApplicationLoadBalancer<ShardingKey, MetricsT> createNonDNSMappedLoadBalancer(Region region, String wildcardDomain);
ApplicationLoadBalancer<ShardingKey> createNonDNSMappedLoadBalancer(Region region, String wildcardDomain);
/**
* Looks up the hostname in the DNS and assumes to get a load balancer CNAME record for it that exists in the {@code region}
* specified. The load balancer is then looked up by its {@link ApplicationLoadBalancer#getDNSName() host name}.
*/
ApplicationLoadBalancer<ShardingKey, MetricsT> getDNSMappedLoadBalancerFor(Region region, String hostname);
ApplicationLoadBalancer<ShardingKey> getDNSMappedLoadBalancerFor(Region region, String hostname);
/**
* The default MongoDB configuration to connect to. See also {@link #MONGO_DEFAULT_REPLICA_SET_NAME} and
@@ -524,7 +523,7 @@ extends Landscape<ShardingKey, MetricsT, ProcessT> {
* Looks for a tag with key as specified by {@code tagName} on the {@code host} specified. If found, the tag's value
* is returned. Otherwise, the {@link Optional} returned {@link Optional#isPresent() is not present}.
*/
Optional<String> getTag(AwsInstance<ShardingKey, MetricsT> host, String tagName);
Optional<String> getTag(AwsInstance<ShardingKey> host, String tagName);
/**
* Obtains all hosts with a tag named {@code tagName}, regardless the tag's value, and returns them as
@@ -535,6 +534,7 @@ extends Landscape<ShardingKey, MetricsT, ProcessT> {
* takes the host and the server directory as arguments and is expected to produce an
* {@link ApplicationProcess} object of some sort.
*/
<MetricsT extends ApplicationProcessMetrics, ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
Iterable<ApplicationProcessHost<ShardingKey, MetricsT, ProcessT>> getApplicationProcessHostsByTag(Region region,
String tagName, BiFunction<Host, String, ProcessT> processFactoryFromHostAndServerDirectory);
@@ -551,6 +551,7 @@ extends Landscape<ShardingKey, MetricsT, ProcessT> {
* an optional timeout for communicating with the application server(s) to try to read the application
* configuration; used, e.g., as timeout during establishing SSH connections
*/
<MetricsT extends ApplicationProcessMetrics, ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
Iterable<ApplicationReplicaSet<ShardingKey, MetricsT, ProcessT>> getApplicationReplicaSetsByTag(Region region,
String tagName, BiFunction<Host, String, ProcessT> processFactoryFromHostAndServerDirectory,
Optional<Duration> optionalTimeout, Optional<String> optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception;
@@ -1,11 +1,6 @@
package com.sap.sse.landscape.aws;
import com.sap.sse.landscape.application.ApplicationProcess;
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
@FunctionalInterface
public interface HostSupplier<ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>,
HostT extends AwsInstance<ShardingKey, MetricsT>> {
HostT supply(String instanceId, AwsAvailabilityZone az, AwsLandscape<ShardingKey, MetricsT, ProcessT> landscape);
public interface HostSupplier<ShardingKey, HostT extends AwsInstance<ShardingKey>> {
HostT supply(String instanceId, AwsAvailabilityZone az, AwsLandscape<ShardingKey> landscape);
}
@@ -22,21 +22,21 @@ extends ReverseProxy<ShardingKey, MetricsT, ProcessT, LogT> {
*
* @return at least one host
*/
Iterable<AwsInstance<ShardingKey, MetricsT>> getHosts();
Iterable<AwsInstance<ShardingKey>> getHosts();
/**
* Add one host of the instance type specified to the availability zone {@code az}.
*
* @return the host that was added by this request; it will also be part of the response of {@link #getHosts()} now
*/
AwsInstance<ShardingKey, MetricsT> createHost(InstanceType instanceType, AwsAvailabilityZone az, String keyName);
AwsInstance<ShardingKey> createHost(InstanceType instanceType, AwsAvailabilityZone az, String keyName);
void addHost(AwsInstance<ShardingKey, MetricsT> host);
void addHost(AwsInstance<ShardingKey> host);
/**
* Removes a single host from this reverse proxy, terminating the host. When trying to remove the last remaining
* host, an {@link IllegalStateException} will be thrown and the method will not complete the request. Consider
* using {@link #terminate()} to terminate all hosts forming this reverse proxy.
*/
void removeHost(AwsInstance<ShardingKey, MetricsT> host);
void removeHost(AwsInstance<ShardingKey> host);
}
@@ -5,7 +5,6 @@ import java.util.Map;
import com.sap.sse.common.Named;
import com.sap.sse.landscape.Region;
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
import software.amazon.awssdk.services.elasticloadbalancingv2.model.TargetHealth;
@@ -15,24 +14,24 @@ import software.amazon.awssdk.services.elasticloadbalancingv2.model.TargetHealth
* @author Axel Uhl (D043530)
*
*/
public interface TargetGroup<ShardingKey, MetricsT extends ApplicationProcessMetrics> extends Named {
public interface TargetGroup<ShardingKey> extends Named {
Region getRegion();
Map<AwsInstance<ShardingKey, MetricsT>, TargetHealth> getRegisteredTargets();
Map<AwsInstance<ShardingKey>, TargetHealth> getRegisteredTargets();
default void addTarget(AwsInstance<ShardingKey, MetricsT> target) {
default void addTarget(AwsInstance<ShardingKey> target) {
addTargets(Collections.singleton(target));
}
void addTargets(Iterable<AwsInstance<ShardingKey, MetricsT>> targets);
void addTargets(Iterable<AwsInstance<ShardingKey>> targets);
default void removeTarget(AwsInstance<ShardingKey, MetricsT> target) {
default void removeTarget(AwsInstance<ShardingKey> target) {
removeTargets(Collections.singleton(target));
}
void removeTargets(Iterable<AwsInstance<ShardingKey, MetricsT>> targets);
void removeTargets(Iterable<AwsInstance<ShardingKey>> targets);
String getTargetGroupArn();
ApplicationLoadBalancer<ShardingKey, MetricsT> getLoadBalancer();
ApplicationLoadBalancer<ShardingKey> getLoadBalancer();
}
@@ -10,13 +10,13 @@ public abstract class AbstractApacheReverseProxy<ShardingKey, MetricsT extends A
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
implements ReverseProxy<ShardingKey, MetricsT, ProcessT, RotatingFileBasedLog> {
protected static final String INTERNAL_SERVER_STATUS = "internal-server-status";
private final AwsLandscape<ShardingKey, MetricsT, ProcessT> landscape;
private final AwsLandscape<ShardingKey> landscape;
public AbstractApacheReverseProxy(AwsLandscape<ShardingKey, MetricsT, ProcessT> landscape) {
public AbstractApacheReverseProxy(AwsLandscape<ShardingKey> landscape) {
this.landscape = landscape;
}
protected AwsLandscape<ShardingKey, MetricsT, ProcessT> getLandscape() {
protected AwsLandscape<ShardingKey> getLandscape() {
return landscape;
}
@@ -7,7 +7,6 @@ import java.util.TimeZone;
import com.sap.sse.common.TimePoint;
import com.sap.sse.landscape.Region;
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
import com.sap.sse.landscape.aws.AmazonMachineImage;
import com.sap.sse.landscape.aws.AwsLandscape;
@@ -15,13 +14,13 @@ import software.amazon.awssdk.services.ec2.model.BlockDeviceMapping;
import software.amazon.awssdk.services.ec2.model.Image;
import software.amazon.awssdk.services.ec2.model.ImageState;
public class AmazonMachineImageImpl<ShardingKey, MetricsT extends ApplicationProcessMetrics> implements AmazonMachineImage<ShardingKey, MetricsT> {
public class AmazonMachineImageImpl<ShardingKey> implements AmazonMachineImage<ShardingKey> {
private static final long serialVersionUID = 1615200981492476022L;
private final Image image;
private final Region region;
private final AwsLandscape<ShardingKey, MetricsT, ?> landscape;
private final AwsLandscape<ShardingKey> landscape;
public AmazonMachineImageImpl(Image image, Region region, AwsLandscape<ShardingKey, MetricsT, ?> landscape) {
public AmazonMachineImageImpl(Image image, Region region, AwsLandscape<ShardingKey> landscape) {
this.image = image;
this.region = region;
this.landscape = landscape;
@@ -56,7 +55,7 @@ public class AmazonMachineImageImpl<ShardingKey, MetricsT extends ApplicationPro
}
@Override
public AmazonMachineImage<ShardingKey, MetricsT> updateAllPackages() {
public AmazonMachineImage<ShardingKey> updateAllPackages() {
// launch with "image-upgrade" as the only user data, then produce the new image
// TODO Implement MachineImage<AwsInstance>.updateAllPackages(...)
return null;
@@ -63,9 +63,9 @@ implements com.sap.sse.landscape.Process<RotatingFileBasedLog, MetricsT> {
private static final String STATUS = "Status";
private static final String CONFIG_FILE_FOR_INTERNALS = "001-internals"+CONFIG_FILE_EXTENSION;
private final AwsInstance<ShardingKey, MetricsT> host;
private final AwsInstance<ShardingKey> host;
public ApacheReverseProxy(AwsLandscape<ShardingKey, MetricsT, ProcessT> landscape, AwsInstance<ShardingKey, MetricsT> host) {
public ApacheReverseProxy(AwsLandscape<ShardingKey> landscape, AwsInstance<ShardingKey> host) {
super(landscape);
this.host = host;
}
@@ -178,7 +178,7 @@ implements com.sap.sse.landscape.Process<RotatingFileBasedLog, MetricsT> {
* {@link AwsInstance}.
*/
@Override
public AwsInstance<ShardingKey, MetricsT> getHost() {
public AwsInstance<ShardingKey> getHost() {
return host;
}
@@ -28,15 +28,15 @@ public class ApacheReverseProxyCluster<ShardingKey, MetricsT extends Application
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>, LogT extends Log>
extends AbstractApacheReverseProxy<ShardingKey, MetricsT, ProcessT>
implements ReverseProxyCluster<ShardingKey, MetricsT, ProcessT, RotatingFileBasedLog> {
private Set<AwsInstance<ShardingKey, MetricsT>> hosts;
private Set<AwsInstance<ShardingKey>> hosts;
public ApacheReverseProxyCluster(AwsLandscape<ShardingKey, MetricsT, ProcessT> landscape) {
public ApacheReverseProxyCluster(AwsLandscape<ShardingKey> landscape) {
super(landscape);
this.hosts = new HashSet<>();
}
@Override
public Iterable<AwsInstance<ShardingKey, MetricsT>> getHosts() {
public Iterable<AwsInstance<ShardingKey>> getHosts() {
return Collections.unmodifiableCollection(hosts);
}
@@ -45,14 +45,14 @@ implements ReverseProxyCluster<ShardingKey, MetricsT, ProcessT, RotatingFileBase
}
@Override
public void addHost(AwsInstance<ShardingKey, MetricsT> host) {
public void addHost(AwsInstance<ShardingKey> host) {
hosts.add(host);
}
@Override
public AwsInstance<ShardingKey, MetricsT> createHost(InstanceType instanceType, AwsAvailabilityZone az, String keyName) {
final AwsInstance<ShardingKey, MetricsT> host = getLandscape().launchHost(
(instanceId, availabilityZone, landscape) -> new AwsInstanceImpl<ShardingKey, MetricsT>(instanceId,
public AwsInstance<ShardingKey> createHost(InstanceType instanceType, AwsAvailabilityZone az, String keyName) {
final AwsInstance<ShardingKey> host = getLandscape().launchHost(
(instanceId, availabilityZone, landscape) -> new AwsInstanceImpl<ShardingKey>(instanceId,
availabilityZone, landscape),
getAmiId(), instanceType, az, keyName,
Collections.singleton(getSecurityGroup(az.getRegion())), Optional.of(Tags.with("Name", "ReverseProxy")));
@@ -61,7 +61,7 @@ implements ReverseProxyCluster<ShardingKey, MetricsT, ProcessT, RotatingFileBase
}
@Override
public void removeHost(AwsInstance<ShardingKey, MetricsT> host) {
public void removeHost(AwsInstance<ShardingKey> host) {
assert Util.contains(getHosts(), host);
if (Util.size(getHosts()) == 1) {
throw new IllegalStateException("Trying to remove the last hosts of reverse proxy "+this+". Use terminate() instead");
@@ -80,9 +80,9 @@ implements ReverseProxyCluster<ShardingKey, MetricsT, ProcessT, RotatingFileBase
@Override
public void terminate() {
Set<AwsInstance<ShardingKey, MetricsT>> hosts = new HashSet<>();
Set<AwsInstance<ShardingKey>> hosts = new HashSet<>();
Util.addAll(getHosts(), hosts);
for (final AwsInstance<ShardingKey, MetricsT> host : hosts) {
for (final AwsInstance<ShardingKey> host : hosts) {
getLandscape().terminate(host);
}
}
@@ -9,7 +9,6 @@ import java.util.List;
import com.sap.sse.common.Duration;
import com.sap.sse.common.Util;
import com.sap.sse.landscape.Region;
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
import com.sap.sse.landscape.aws.ApplicationLoadBalancer;
import com.sap.sse.landscape.aws.AwsLandscape;
import com.sap.sse.landscape.aws.TargetGroup;
@@ -20,8 +19,8 @@ import software.amazon.awssdk.services.elasticloadbalancingv2.model.ProtocolEnum
import software.amazon.awssdk.services.elasticloadbalancingv2.model.Rule;
import software.amazon.awssdk.services.elasticloadbalancingv2.model.RulePriorityPair;
public class ApplicationLoadBalancerImpl<ShardingKey, MetricsT extends ApplicationProcessMetrics>
implements ApplicationLoadBalancer<ShardingKey, MetricsT> {
public class ApplicationLoadBalancerImpl<ShardingKey>
implements ApplicationLoadBalancer<ShardingKey> {
private static final long serialVersionUID = -5297220031399131769L;
/**
@@ -33,9 +32,9 @@ implements ApplicationLoadBalancer<ShardingKey, MetricsT> {
private final Region region;
private final AwsLandscape<ShardingKey, MetricsT, ?> landscape;
private final AwsLandscape<ShardingKey> landscape;
public ApplicationLoadBalancerImpl(Region region, LoadBalancer loadBalancer, AwsLandscape<ShardingKey, MetricsT, ?> landscape) {
public ApplicationLoadBalancerImpl(Region region, LoadBalancer loadBalancer, AwsLandscape<ShardingKey> landscape) {
this.region = region;
this.loadBalancer = loadBalancer;
this.landscape = landscape;
@@ -149,7 +148,7 @@ implements ApplicationLoadBalancer<ShardingKey, MetricsT> {
}
@Override
public Iterable<TargetGroup<ShardingKey, MetricsT>> getTargetGroups() {
public Iterable<TargetGroup<ShardingKey>> getTargetGroups() {
return landscape.getTargetGroupsByLoadBalancerArn(getRegion(), getArn());
}
@@ -164,14 +163,14 @@ implements ApplicationLoadBalancer<ShardingKey, MetricsT> {
@Override
public void delete() throws InterruptedException {
// first obtain the target groups to which, based on the current ALB configuration, traffic is forwarded
final Iterable<TargetGroup<ShardingKey, MetricsT>> targetGroups = getTargetGroups();
final Iterable<TargetGroup<ShardingKey>> targetGroups = getTargetGroups();
// now delete the rules to free up all target groups to which the ALB could have forwarded, except the default rule
deleteAllRules();
deleteAllListeners();
landscape.deleteLoadBalancer(this);
Thread.sleep(Duration.ONE_SECOND.times(5).asMillis()); // wait a bit until the target groups are no longer considered "in use"
// now that all target groups the ALB used are freed up, delete them:
for (final TargetGroup<?, ?> targetGroup : targetGroups) {
for (final TargetGroup<?> targetGroup : targetGroups) {
landscape.deleteTargetGroup(landscape.getTargetGroup(getRegion(), targetGroup.getName(), targetGroup.getTargetGroupArn()));
}
}
@@ -22,23 +22,20 @@ import com.sap.sse.landscape.aws.ReverseProxy;
public class ApplicationProcessHostImpl<ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends AwsInstanceImpl<ShardingKey, MetricsT>
extends AwsInstanceImpl<ShardingKey>
implements ApplicationProcessHost<ShardingKey, MetricsT, ProcessT> {
private static final Logger logger = Logger.getLogger(ApplicationProcessHostImpl.class.getName());
private final BiFunction<Host, String, ProcessT> processFactoryFromHostAndServerDirectory;
public ApplicationProcessHostImpl(String instanceId, AwsAvailabilityZone availabilityZone,
AwsLandscape<ShardingKey, MetricsT, ?> landscape, BiFunction<Host, String, ProcessT> processFactoryFromHostAndServerDirectory) {
AwsLandscape<ShardingKey> landscape, BiFunction<Host, String, ProcessT> processFactoryFromHostAndServerDirectory) {
super(instanceId, availabilityZone, landscape);
this.processFactoryFromHostAndServerDirectory = processFactoryFromHostAndServerDirectory;
}
@Override
public AwsLandscape<ShardingKey, MetricsT, ProcessT> getLandscape() {
@SuppressWarnings("unchecked")
final AwsLandscape<ShardingKey, MetricsT, ProcessT> castLandscape =
(AwsLandscape<ShardingKey, MetricsT, ProcessT>) super.getLandscape();
return castLandscape;
public AwsLandscape<ShardingKey> getLandscape() {
return super.getLandscape();
}
@Override
@@ -22,7 +22,6 @@ import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.landscape.SecurityGroup;
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
import com.sap.sse.landscape.aws.AwsAvailabilityZone;
import com.sap.sse.landscape.aws.AwsInstance;
import com.sap.sse.landscape.aws.AwsLandscape;
@@ -36,14 +35,14 @@ import com.sap.sse.util.Wait;
import software.amazon.awssdk.services.ec2.model.Instance;
import software.amazon.awssdk.services.ec2.model.InstanceStateName;
public class AwsInstanceImpl<ShardingKey, MetricsT extends ApplicationProcessMetrics> implements AwsInstance<ShardingKey, MetricsT> {
public class AwsInstanceImpl<ShardingKey> implements AwsInstance<ShardingKey> {
private final static Logger logger = Logger.getLogger(AwsInstanceImpl.class.getName());
private static final String ROOT_USER_NAME = "root";
private final String instanceId;
private final AwsAvailabilityZone availabilityZone;
private final AwsLandscape<ShardingKey, MetricsT, ?> landscape;
private final AwsLandscape<ShardingKey> landscape;
public AwsInstanceImpl(String instanceId, AwsAvailabilityZone availabilityZone, AwsLandscape<ShardingKey, MetricsT, ?> landscape) {
public AwsInstanceImpl(String instanceId, AwsAvailabilityZone availabilityZone, AwsLandscape<ShardingKey> landscape) {
this.instanceId = instanceId;
this.availabilityZone = availabilityZone;
this.landscape = landscape;
@@ -51,9 +50,7 @@ public class AwsInstanceImpl<ShardingKey, MetricsT extends ApplicationProcessMet
@Override
public boolean equals(Object other) {
@SuppressWarnings("unchecked")
AwsInstance<?, ? extends ApplicationProcessMetrics> otherCast = (AwsInstance<?, ? extends ApplicationProcessMetrics>) other;
return otherCast.getInstanceId().equals(getInstanceId());
return ((AwsInstance<?>) other).getInstanceId().equals(getInstanceId());
}
@Override
@@ -258,7 +255,7 @@ public class AwsInstanceImpl<ShardingKey, MetricsT extends ApplicationProcessMet
landscape.terminate(this);
}
protected AwsLandscape<ShardingKey, MetricsT, ?> getLandscape() {
protected AwsLandscape<ShardingKey> getLandscape() {
return landscape;
}
@@ -136,9 +136,7 @@ import software.amazon.awssdk.services.route53.model.RRType;
import software.amazon.awssdk.services.route53.model.ResourceRecord;
import software.amazon.awssdk.services.route53.model.ResourceRecordSet;
public class AwsLandscapeImpl<ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
public class AwsLandscapeImpl<ShardingKey> implements AwsLandscape<ShardingKey> {
private static final String DEFAULT_TARGET_GROUP_PREFIX = "D";
private static final Logger logger = Logger.getLogger(AwsLandscapeImpl.class.getName());
private static final long DEFAULT_DNS_TTL_MILLIS = 60000l;
@@ -241,7 +239,7 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public ApplicationLoadBalancer<ShardingKey, MetricsT> createLoadBalancer(String name, com.sap.sse.landscape.Region region) {
public ApplicationLoadBalancer<ShardingKey> createLoadBalancer(String name, com.sap.sse.landscape.Region region) {
Region awsRegion = getRegion(region);
final ElasticLoadBalancingV2Client client = getLoadBalancingClient(awsRegion);
final Iterable<AvailabilityZone> availabilityZones = getAvailabilityZones(region);
@@ -255,16 +253,17 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
LoadBalancerAttribute.builder().key("access_logs.s3.enabled").value("true").build(),
LoadBalancerAttribute.builder().key("access_logs.s3.bucket").value(getS3BucketForAlbLogs(region)).build(),
LoadBalancerAttribute.builder().key("idle_timeout.timeout_seconds").value("4000").build()).build());
final ApplicationLoadBalancer<ShardingKey, MetricsT> result = new ApplicationLoadBalancerImpl<>(region, response.loadBalancers().iterator().next(), this);
final ApplicationLoadBalancer<ShardingKey> result = new ApplicationLoadBalancerImpl<>(region, response.loadBalancers().iterator().next(), this);
createLoadBalancerListener(result, ProtocolEnum.HTTP);
createLoadBalancerListener(result, ProtocolEnum.HTTPS);
return result;
}
private Listener createLoadBalancerListener(ApplicationLoadBalancer<ShardingKey, MetricsT> alb, ProtocolEnum protocol) {
private <MetricsT extends ApplicationProcessMetrics, ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
Listener createLoadBalancerListener(ApplicationLoadBalancer<ShardingKey> alb, ProtocolEnum protocol) {
final int port = protocol==ProtocolEnum.HTTP?80:443;
final ReverseProxyCluster<ShardingKey, MetricsT, ProcessT, RotatingFileBasedLog> reverseProxy = getCentralReverseProxy(alb.getRegion());
final TargetGroup<ShardingKey, MetricsT> defaultTargetGroup = createTargetGroup(alb.getRegion(), DEFAULT_TARGET_GROUP_PREFIX+alb.getName()+"-"+protocol.name(),
final TargetGroup<ShardingKey> defaultTargetGroup = createTargetGroup(alb.getRegion(), DEFAULT_TARGET_GROUP_PREFIX+alb.getName()+"-"+protocol.name(),
port, reverseProxy.getHealthCheckPath(), /* healthCheckPort */ port);
defaultTargetGroup.addTargets(reverseProxy.getHosts());
return getLoadBalancingClient(
@@ -287,24 +286,24 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public void deleteLoadBalancer(ApplicationLoadBalancer<ShardingKey, MetricsT> alb) {
public void deleteLoadBalancer(ApplicationLoadBalancer<ShardingKey> alb) {
getLoadBalancingClient(getRegion(alb.getRegion())).deleteLoadBalancer(DeleteLoadBalancerRequest.builder().loadBalancerArn(alb.getArn()).build());
}
@Override
public Iterable<TargetGroup<ShardingKey, MetricsT>> getTargetGroupsByLoadBalancerArn(com.sap.sse.landscape.Region region, String loadBalancerArn) {
public Iterable<TargetGroup<ShardingKey>> getTargetGroupsByLoadBalancerArn(com.sap.sse.landscape.Region region, String loadBalancerArn) {
return Util.map(getLoadBalancingClient(getRegion(region)).describeTargetGroups(tg->tg.loadBalancerArn(loadBalancerArn)).targetGroups(),
tg->new AwsTargetGroupImpl<>(this, region, tg.targetGroupName(), tg.targetGroupArn()));
}
@Override
public Iterable<Listener> getListeners(ApplicationLoadBalancer<ShardingKey, MetricsT> alb) {
public Iterable<Listener> getListeners(ApplicationLoadBalancer<ShardingKey> alb) {
final ElasticLoadBalancingV2Client client = getLoadBalancingClient(getRegion(alb.getRegion()));
return client.describeListeners(b->b.loadBalancerArn(alb.getArn())).listeners();
}
@Override
public LoadBalancerState getApplicationLoadBalancerStatus(ApplicationLoadBalancer<ShardingKey, MetricsT> alb) {
public LoadBalancerState getApplicationLoadBalancerStatus(ApplicationLoadBalancer<ShardingKey> alb) {
final ElasticLoadBalancingV2Client client = getLoadBalancingClient(getRegion(alb.getRegion()));
final DescribeLoadBalancersResponse response = client.describeLoadBalancers(b->b.loadBalancerArns(alb.getArn()));
return response.loadBalancers().iterator().next().state();
@@ -364,7 +363,7 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public Iterable<ApplicationLoadBalancer<ShardingKey, MetricsT>> getLoadBalancers(com.sap.sse.landscape.Region region) {
public Iterable<ApplicationLoadBalancer<ShardingKey>> getLoadBalancers(com.sap.sse.landscape.Region region) {
final List<LoadBalancer> loadBalancers = getLoadBalancingClient(getRegion(region))
.describeLoadBalancers(DescribeLoadBalancersRequest.builder().build())
.loadBalancers();
@@ -373,7 +372,7 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public ApplicationLoadBalancer<ShardingKey, MetricsT> getLoadBalancerByName(String name, com.sap.sse.landscape.Region region) {
public ApplicationLoadBalancer<ShardingKey> getLoadBalancerByName(String name, com.sap.sse.landscape.Region region) {
try {
final DescribeLoadBalancersResponse response = getLoadBalancingClient(getRegion(region)).describeLoadBalancers(b->b.names(name));
return response.hasLoadBalancers() ? new ApplicationLoadBalancerImpl<>(region, response.loadBalancers().iterator().next(), this) : null;
@@ -383,7 +382,7 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public ApplicationLoadBalancer<ShardingKey, MetricsT> getLoadBalancer(String loadBalancerArn, com.sap.sse.landscape.Region region) {
public ApplicationLoadBalancer<ShardingKey> getLoadBalancer(String loadBalancerArn, com.sap.sse.landscape.Region region) {
final LoadBalancer loadBalancer = getLoadBalancingClient(getRegion(region))
.describeLoadBalancers(DescribeLoadBalancersRequest.builder().loadBalancerArns(loadBalancerArn).build())
.loadBalancers().iterator().next();
@@ -409,7 +408,7 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
@Override
public ChangeInfo setDNSRecordToApplicationLoadBalancer(String hostedZoneId, String hostname,
ApplicationLoadBalancer<ShardingKey, MetricsT> alb) {
ApplicationLoadBalancer<ShardingKey> alb) {
final String dnsName = alb.getDNSName();
return setDNSRecord(hostedZoneId, hostname, RRType.CNAME, dnsName);
}
@@ -456,14 +455,14 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public AmazonMachineImage<ShardingKey, MetricsT> getImage(com.sap.sse.landscape.Region region, String imageId) {
public AmazonMachineImage<ShardingKey> getImage(com.sap.sse.landscape.Region region, String imageId) {
final DescribeImagesResponse response = getEc2Client(getRegion(region))
.describeImages(DescribeImagesRequest.builder().imageIds(imageId).build());
return new AmazonMachineImageImpl<>(response.images().iterator().next(), region, this);
}
@Override
public AmazonMachineImage<ShardingKey, MetricsT> createImage(AwsInstance<ShardingKey, MetricsT> instance, String imageName, Optional<Tags> tags) {
public AmazonMachineImage<ShardingKey> createImage(AwsInstance<ShardingKey> instance, String imageName, Optional<Tags> tags) {
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
@@ -482,14 +481,14 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public AmazonMachineImage<ShardingKey, MetricsT> getLatestImageWithTag(com.sap.sse.landscape.Region region, String tagName, String tagValue) {
public AmazonMachineImage<ShardingKey> getLatestImageWithTag(com.sap.sse.landscape.Region region, String tagName, String tagValue) {
final DescribeImagesResponse response = getEc2Client(getRegion(region))
.describeImages(DescribeImagesRequest.builder().filters(Filter.builder().name("tag:"+tagName).values(tagValue).build()).build());
return new AmazonMachineImageImpl<>(response.images().stream().max(getMachineImageCreationDateComparator()).get(), region, this);
}
@Override
public Iterable<AmazonMachineImage<ShardingKey, MetricsT>> getAllImagesWithTag(com.sap.sse.landscape.Region region,
public Iterable<AmazonMachineImage<ShardingKey>> getAllImagesWithTag(com.sap.sse.landscape.Region region,
String tagName, String tagValue) {
final DescribeImagesResponse response = getEc2Client(getRegion(region))
.describeImages(DescribeImagesRequest.builder().filters(Filter.builder().name("tag:"+tagName).values(tagValue).build()).build());
@@ -519,7 +518,7 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public Iterable<AwsInstance<ShardingKey, MetricsT>> getHostsWithTagValue(com.sap.sse.landscape.Region region,
public Iterable<AwsInstance<ShardingKey>> getHostsWithTagValue(com.sap.sse.landscape.Region region,
String tagName, String tagValue) {
Filter filter = getHostWithTagValueFilter(tagName, tagValue).build();
return getHostsWithFilters(region, filter);
@@ -530,7 +529,7 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public Iterable<AwsInstance<ShardingKey, MetricsT>> getRunningHostsWithTagValue(com.sap.sse.landscape.Region region,
public Iterable<AwsInstance<ShardingKey>> getRunningHostsWithTagValue(com.sap.sse.landscape.Region region,
String tagName, String tagValue) {
return getHostsWithFilters(region, getRunningHostFilter());
}
@@ -539,8 +538,8 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
return Filter.builder().name("instance-state-name").values("running").build();
}
private Iterable<AwsInstance<ShardingKey, MetricsT>> getHostsWithFilters(com.sap.sse.landscape.Region region, Filter... filters) {
final List<AwsInstance<ShardingKey, MetricsT>> result = new ArrayList<>();
private Iterable<AwsInstance<ShardingKey>> getHostsWithFilters(com.sap.sse.landscape.Region region, Filter... filters) {
final List<AwsInstance<ShardingKey>> result = new ArrayList<>();
final DescribeInstancesResponse instanceResponse = getEc2Client(getRegion(region)).describeInstances(b->b.filters(filters));
for (final Reservation r : instanceResponse.reservations()) {
for (final Instance i : r.instances()) {
@@ -550,21 +549,21 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
return result;
}
private AwsInstance<ShardingKey, MetricsT> getHost(com.sap.sse.landscape.Region region, final Instance instance) {
return new AwsInstanceImpl<ShardingKey, MetricsT>(instance.instanceId(), getAvailabilityZoneByName(region, instance.placement().availabilityZone()), this);
private AwsInstance<ShardingKey> getHost(com.sap.sse.landscape.Region region, final Instance instance) {
return new AwsInstanceImpl<ShardingKey>(instance.instanceId(), getAvailabilityZoneByName(region, instance.placement().availabilityZone()), this);
}
private AwsInstance<ShardingKey, MetricsT> getHost(com.sap.sse.landscape.Region region, final String instanceId) {
private AwsInstance<ShardingKey> getHost(com.sap.sse.landscape.Region region, final String instanceId) {
return getHost(region, getInstance(instanceId, region));
}
@Override
public Iterable<AwsInstance<ShardingKey, MetricsT>> getRunningHostsWithTag(com.sap.sse.landscape.Region region, String tagName) {
public Iterable<AwsInstance<ShardingKey>> getRunningHostsWithTag(com.sap.sse.landscape.Region region, String tagName) {
return getHostsWithFilters(region, getFilterForHostWithTag(Filter.builder(), tagName), getRunningHostFilter());
}
@Override
public Iterable<AwsInstance<ShardingKey, MetricsT>> getHostsWithTag(com.sap.sse.landscape.Region region, String tagName) {
public Iterable<AwsInstance<ShardingKey>> getHostsWithTag(com.sap.sse.landscape.Region region, String tagName) {
return getHostsWithFilters(region, getFilterForHostWithTag(Filter.builder(), tagName));
}
@@ -652,13 +651,14 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public Map<Scope<ShardingKey>, ApplicationReplicaSet<ShardingKey, MetricsT, ProcessT>> getScopes() {
public <MetricsT extends ApplicationProcessMetrics, ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
Map<Scope<ShardingKey>, ApplicationReplicaSet<ShardingKey, MetricsT, ProcessT>> getScopes() {
// TODO Implement Landscape<ShardingKey,MetricsT>.getScopes(...)
return null;
}
@Override
public <HostT extends AwsInstance<ShardingKey, MetricsT>> Iterable<HostT> launchHosts(HostSupplier<ShardingKey, MetricsT, ProcessT, HostT> hostSupplier,
public <HostT extends AwsInstance<ShardingKey>> Iterable<HostT> launchHosts(HostSupplier<ShardingKey, HostT> hostSupplier,
int numberOfHostsToLaunch, MachineImage fromImage,
InstanceType instanceType, AwsAvailabilityZone az, String keyName, Iterable<SecurityGroup> securityGroups, Optional<Tags> tags, String... userData) {
if (!fromImage.getRegion().equals(az.getRegion())) {
@@ -695,7 +695,7 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public void terminate(AwsInstance<ShardingKey, MetricsT> host) {
public void terminate(AwsInstance<ShardingKey> host) {
logger.info("Terminating instance "+host);
getEc2Client(getRegion(host.getAvailabilityZone().getRegion())).terminateInstances(
TerminateInstancesRequest.builder().instanceIds(host.getInstanceId()).build());
@@ -712,7 +712,7 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public TargetGroup<ShardingKey, MetricsT> getTargetGroup(com.sap.sse.landscape.Region region, String targetGroupName) {
public TargetGroup<ShardingKey> getTargetGroup(com.sap.sse.landscape.Region region, String targetGroupName) {
final ElasticLoadBalancingV2Client loadBalancingClient = getLoadBalancingClient(getRegion(region));
final DescribeTargetGroupsResponse targetGroupResponse = loadBalancingClient.describeTargetGroups(b->b.names(targetGroupName));
return targetGroupResponse.hasTargetGroups()
@@ -722,7 +722,7 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public TargetGroup<ShardingKey, MetricsT> createTargetGroup(com.sap.sse.landscape.Region region, String targetGroupName, int port, String healthCheckPath, int healthCheckPort) {
public TargetGroup<ShardingKey> createTargetGroup(com.sap.sse.landscape.Region region, String targetGroupName, int port, String healthCheckPath, int healthCheckPort) {
final ElasticLoadBalancingV2Client loadBalancingClient = getLoadBalancingClient(getRegion(region));
final software.amazon.awssdk.services.elasticloadbalancingv2.model.TargetGroup targetGroup =
loadBalancingClient.createTargetGroup(CreateTargetGroupRequest.builder()
@@ -772,14 +772,14 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public <SK, MT extends ApplicationProcessMetrics> void deleteTargetGroup(TargetGroup<SK, MT> targetGroup) {
public <SK> void deleteTargetGroup(TargetGroup<SK> targetGroup) {
getLoadBalancingClient(getRegion(targetGroup.getRegion())).deleteTargetGroup(DeleteTargetGroupRequest.builder().targetGroupArn(
targetGroup.getTargetGroupArn()).build());
}
@Override
public Map<AwsInstance<ShardingKey, MetricsT>, TargetHealth> getTargetHealthDescriptions(TargetGroup<ShardingKey, MetricsT> targetGroup) {
final Map<AwsInstance<ShardingKey, MetricsT>, TargetHealth> result = new HashMap<>();
public Map<AwsInstance<ShardingKey>, TargetHealth> getTargetHealthDescriptions(TargetGroup<ShardingKey> targetGroup) {
final Map<AwsInstance<ShardingKey>, TargetHealth> result = new HashMap<>();
final Region region = getRegion(targetGroup.getRegion());
getLoadBalancingClient(region)
.describeTargetHealth(DescribeTargetHealthRequest.builder().targetGroupArn(targetGroup.getTargetGroupArn()).build())
@@ -790,9 +790,10 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public ReverseProxyCluster<ShardingKey, MetricsT, ProcessT, RotatingFileBasedLog> getCentralReverseProxy(com.sap.sse.landscape.Region region) {
public <MetricsT extends ApplicationProcessMetrics, ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
ReverseProxyCluster<ShardingKey, MetricsT, ProcessT, RotatingFileBasedLog> getCentralReverseProxy(com.sap.sse.landscape.Region region) {
ApacheReverseProxyCluster<ShardingKey, MetricsT, ProcessT, RotatingFileBasedLog> reverseProxyCluster = new ApacheReverseProxyCluster<>(this);
for (final AwsInstance<ShardingKey, MetricsT> reverseProxyHost : getRunningHostsWithTag(region, CENTRAL_REVERSE_PROXY_TAG_NAME)) {
for (final AwsInstance<ShardingKey> reverseProxyHost : getRunningHostsWithTag(region, CENTRAL_REVERSE_PROXY_TAG_NAME)) {
reverseProxyCluster.addHost(reverseProxyHost);
}
return reverseProxyCluster;
@@ -805,24 +806,24 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
@Override
public void addTargetsToTargetGroup(
TargetGroup<ShardingKey, MetricsT> targetGroup,
Iterable<AwsInstance<ShardingKey, MetricsT>> targets) {
TargetGroup<ShardingKey> targetGroup,
Iterable<AwsInstance<ShardingKey>> targets) {
getLoadBalancingClient(getRegion(targetGroup.getRegion())).registerTargets(getRegisterTargetsRequestBuilderConsumer(targetGroup, targets));
}
private TargetDescription[] getTargetDescriptions(Iterable<AwsInstance<ShardingKey, MetricsT>> targets) {
private TargetDescription[] getTargetDescriptions(Iterable<AwsInstance<ShardingKey>> targets) {
return Util.toArray(Util.map(targets, t->TargetDescription.builder().id(t.getInstanceId()).build()), new TargetDescription[0]);
}
@Override
public void removeTargetsFromTargetGroup(
TargetGroup<ShardingKey, MetricsT> targetGroup,
Iterable<AwsInstance<ShardingKey, MetricsT>> targets) {
TargetGroup<ShardingKey> targetGroup,
Iterable<AwsInstance<ShardingKey>> targets) {
getLoadBalancingClient(getRegion(targetGroup.getRegion())).deregisterTargets(getDeregisterTargetRequestBuilderConsumers(targetGroup, targets));
}
private Consumer<software.amazon.awssdk.services.elasticloadbalancingv2.model.RegisterTargetsRequest.Builder> getRegisterTargetsRequestBuilderConsumer(
TargetGroup<ShardingKey, MetricsT> targetGroup, Iterable<AwsInstance<ShardingKey, MetricsT>> targets) {
TargetGroup<ShardingKey> targetGroup, Iterable<AwsInstance<ShardingKey>> targets) {
final TargetDescription[] targetDescriptions = getTargetDescriptions(targets);
return b->b
.targetGroupArn(targetGroup.getTargetGroupArn())
@@ -830,7 +831,7 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
private Consumer<software.amazon.awssdk.services.elasticloadbalancingv2.model.DeregisterTargetsRequest.Builder> getDeregisterTargetRequestBuilderConsumers(
TargetGroup<ShardingKey, MetricsT> targetGroup, Iterable<AwsInstance<ShardingKey, MetricsT>> targets) {
TargetGroup<ShardingKey> targetGroup, Iterable<AwsInstance<ShardingKey>> targets) {
final TargetDescription[] targetDescriptions = getTargetDescriptions(targets);
return b->b
.targetGroupArn(targetGroup.getTargetGroupArn())
@@ -877,13 +878,13 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public ApplicationLoadBalancer<ShardingKey, MetricsT> getNonDNSMappedLoadBalancer(
public ApplicationLoadBalancer<ShardingKey> getNonDNSMappedLoadBalancer(
com.sap.sse.landscape.Region region, String wildcardDomain) {
return getLoadBalancerByName(getNonDNSMappedLoadBalancerName(wildcardDomain), region);
}
@Override
public ApplicationLoadBalancer<ShardingKey, MetricsT> createNonDNSMappedLoadBalancer(
public ApplicationLoadBalancer<ShardingKey> createNonDNSMappedLoadBalancer(
com.sap.sse.landscape.Region region, String wildcardDomain) {
return createLoadBalancer(getNonDNSMappedLoadBalancerName(wildcardDomain), region);
}
@@ -893,11 +894,11 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public ApplicationLoadBalancer<ShardingKey, MetricsT> getDNSMappedLoadBalancerFor(
public ApplicationLoadBalancer<ShardingKey> getDNSMappedLoadBalancerFor(
com.sap.sse.landscape.Region region, String hostname) {
final DescribeLoadBalancersResponse response = getLoadBalancingClient(getRegion(region)).describeLoadBalancers();
for (final LoadBalancer lb : response.loadBalancers()) {
final ApplicationLoadBalancer<ShardingKey, MetricsT> alb = new ApplicationLoadBalancerImpl<>(region, lb, this);
final ApplicationLoadBalancer<ShardingKey> alb = new ApplicationLoadBalancerImpl<>(region, lb, this);
for (final Rule rule : alb.getRules()) {
if (rule.conditions().stream().filter(r->r.hostHeaderConfig().values().contains(hostname)).findAny().isPresent()) {
return alb;
@@ -923,7 +924,7 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public Optional<String> getTag(AwsInstance<ShardingKey, MetricsT> host, String tagName) {
public Optional<String> getTag(AwsInstance<ShardingKey> host, String tagName) {
final DescribeTagsResponse tagResponse = getEc2Client(getRegion(host.getRegion())).describeTags(b->b.filters(
Filter.builder()
.name("resource-id").values(host.getInstanceId()).build(),
@@ -941,7 +942,7 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
@Override
public MongoReplicaSet getDatabaseConfigurationForReplicaSet(com.sap.sse.landscape.Region region, String mongoReplicaSetName) {
final MongoReplicaSet result = new MongoReplicaSetImpl(mongoReplicaSetName);
for (final AwsInstance<ShardingKey, MetricsT> host : getMongoDBHosts(region)) {
for (final AwsInstance<ShardingKey> host : getMongoDBHosts(region)) {
for (final Pair<String, Integer> replicaSetNameAndPort : getMongoEndpointSpecificationsAsReplicaSetNameAndPort(host)) {
if (replicaSetNameAndPort.getA().equals(mongoReplicaSetName)) {
result.addReplica(new MongoProcessInReplicaSetImpl(result, replicaSetNameAndPort.getB(), host));
@@ -951,7 +952,7 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
return result;
}
private Iterable<AwsInstance<ShardingKey, MetricsT>> getMongoDBHosts(com.sap.sse.landscape.Region region) {
private Iterable<AwsInstance<ShardingKey>> getMongoDBHosts(com.sap.sse.landscape.Region region) {
return getRunningHostsWithTag(region, MONGO_REPLICA_SETS_TAG_NAME);
}
@@ -960,7 +961,7 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
* assumed to be a host that has the {@link #MONGO_REPLICA_SETS_TAG_NAME} tag set
* @return the replica set name / port number pairs extracted from the tag value
*/
private Iterable<Pair<String, Integer>> getMongoEndpointSpecificationsAsReplicaSetNameAndPort(final AwsInstance<ShardingKey, MetricsT> host) {
private Iterable<Pair<String, Integer>> getMongoEndpointSpecificationsAsReplicaSetNameAndPort(final AwsInstance<ShardingKey> host) {
final List<Pair<String, Integer>> result = new ArrayList<>();
getTag(host, MONGO_REPLICA_SETS_TAG_NAME).ifPresent(tagValue->{
for (final String replicaNameWithOptionalPortColonSeparated : tagValue.split(",")) {
@@ -975,7 +976,7 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
public Iterable<MongoEndpoint> getMongoEndpoints(com.sap.sse.landscape.Region region) {
final Set<MongoEndpoint> result = new HashSet<>();
final Set<String> replicaSetsCreated = new HashSet<>();
for (final AwsInstance<ShardingKey, MetricsT> mongoDBHost : getMongoDBHosts(region)) {
for (final AwsInstance<ShardingKey> mongoDBHost : getMongoDBHosts(region)) {
for (final Pair<String, Integer> replicaSetNameAndPort : getMongoEndpointSpecificationsAsReplicaSetNameAndPort(mongoDBHost)) {
if (replicaSetNameAndPort.getA() != null && !replicaSetNameAndPort.getA().isEmpty()) { // non-empty replica set name
if (!replicaSetsCreated.contains(replicaSetNameAndPort.getA())) {
@@ -994,9 +995,9 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
@Override
public RabbitMQEndpoint getDefaultRabbitConfiguration(AwsRegion region) {
final RabbitMQEndpoint result;
final Iterable<AwsInstance<ShardingKey, MetricsT>> rabbitMQHostsInRegion = getRunningHostsWithTag(region, RABBITMQ_TAG_NAME);
final Iterable<AwsInstance<ShardingKey>> rabbitMQHostsInRegion = getRunningHostsWithTag(region, RABBITMQ_TAG_NAME);
if (rabbitMQHostsInRegion.iterator().hasNext()) {
final AwsInstance<ShardingKey, MetricsT> anyRabbitMQHost = rabbitMQHostsInRegion.iterator().next();
final AwsInstance<ShardingKey> anyRabbitMQHost = rabbitMQHostsInRegion.iterator().next();
result = new RabbitMQEndpoint() {
@Override
public int getPort() {
@@ -1033,10 +1034,11 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public Iterable<ApplicationProcessHost<ShardingKey, MetricsT, ProcessT>> getApplicationProcessHostsByTag(com.sap.sse.landscape.Region region, String tagName,
public <MetricsT extends ApplicationProcessMetrics, ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
Iterable<ApplicationProcessHost<ShardingKey, MetricsT, ProcessT>> getApplicationProcessHostsByTag(com.sap.sse.landscape.Region region, String tagName,
BiFunction<Host, String, ProcessT> processFactoryFromHostAndServerDirectory) {
final List<ApplicationProcessHost<ShardingKey, MetricsT, ProcessT>> result = new ArrayList<>();
for (final AwsInstance<ShardingKey, MetricsT> host : getRunningHostsWithTag(region, tagName)) {
for (final AwsInstance<ShardingKey> host : getRunningHostsWithTag(region, tagName)) {
final ApplicationProcessHost<ShardingKey, MetricsT, ProcessT> applicationProcessHost =
new ApplicationProcessHostImpl<ShardingKey, MetricsT, ProcessT>(
host.getInstanceId(), host.getAvailabilityZone(), this, processFactoryFromHostAndServerDirectory);
@@ -1046,7 +1048,8 @@ implements AwsLandscape<ShardingKey, MetricsT, ProcessT> {
}
@Override
public Iterable<ApplicationReplicaSet<ShardingKey, MetricsT, ProcessT>> getApplicationReplicaSetsByTag(com.sap.sse.landscape.Region region, String tagName,
public <MetricsT extends ApplicationProcessMetrics, ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
Iterable<ApplicationReplicaSet<ShardingKey, MetricsT, ProcessT>> getApplicationReplicaSetsByTag(com.sap.sse.landscape.Region region, String tagName,
BiFunction<Host, String, ProcessT> processFactoryFromHostAndServerDirectory, Optional<Duration> optionalTimeout, Optional<String> optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception {
final Iterable<ApplicationProcessHost<ShardingKey, MetricsT, ProcessT>> hosts = getApplicationProcessHostsByTag(region, tagName, processFactoryFromHostAndServerDirectory);
final Map<String, ProcessT> mastersByServerName = new HashMap<>();
@@ -6,7 +6,7 @@ import com.sap.sse.landscape.SecurityGroup;
import com.sap.sse.landscape.aws.AwsLandscape;
public class AwsRegion implements Region {
private AwsLandscape<?, ?, ?> landscape; // FIXME this is broken; it shall be final and has to be initialized by the constructors if getAvailabilityZones and getSecurityGroups is expected to do anything useful
private AwsLandscape<?> landscape; // FIXME this is broken; it shall be final and has to be initialized by the constructors if getAvailabilityZones and getSecurityGroups is expected to do anything useful
private final String id;
public AwsRegion(String id) {
@@ -4,8 +4,6 @@ import java.util.Map;
import com.sap.sse.common.impl.NamedImpl;
import com.sap.sse.landscape.Region;
import com.sap.sse.landscape.application.ApplicationProcess;
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
import com.sap.sse.landscape.aws.ApplicationLoadBalancer;
import com.sap.sse.landscape.aws.AwsInstance;
import com.sap.sse.landscape.aws.AwsLandscape;
@@ -13,15 +11,14 @@ import com.sap.sse.landscape.aws.TargetGroup;
import software.amazon.awssdk.services.elasticloadbalancingv2.model.TargetHealth;
public class AwsTargetGroupImpl<ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends NamedImpl implements TargetGroup<ShardingKey, MetricsT> {
public class AwsTargetGroupImpl<ShardingKey>
extends NamedImpl implements TargetGroup<ShardingKey> {
private static final long serialVersionUID = -5442598262397393201L;
private final String arn;
private final AwsLandscape<ShardingKey, MetricsT, ProcessT> landscape;
private final AwsLandscape<ShardingKey> landscape;
private final Region region;
public AwsTargetGroupImpl(AwsLandscape<ShardingKey, MetricsT, ProcessT> landscape, Region region, String targetGroupName, String arn) {
public AwsTargetGroupImpl(AwsLandscape<ShardingKey> landscape, Region region, String targetGroupName, String arn) {
super(targetGroupName);
this.arn = arn;
this.landscape = landscape;
@@ -37,14 +34,14 @@ extends NamedImpl implements TargetGroup<ShardingKey, MetricsT> {
}
@Override
public Map<AwsInstance<ShardingKey, MetricsT>, TargetHealth> getRegisteredTargets() {
public Map<AwsInstance<ShardingKey>, TargetHealth> getRegisteredTargets() {
return landscape.getTargetHealthDescriptions(this);
}
@Override
public ApplicationLoadBalancer<ShardingKey, MetricsT> getLoadBalancer() {
public ApplicationLoadBalancer<ShardingKey> getLoadBalancer() {
final software.amazon.awssdk.services.elasticloadbalancingv2.model.TargetGroup targetGroup = getAwsTargetGroup();
final ApplicationLoadBalancer<ShardingKey, MetricsT> result;
final ApplicationLoadBalancer<ShardingKey> result;
if (targetGroup.hasLoadBalancerArns() && !targetGroup.loadBalancerArns().isEmpty()) {
result = new ApplicationLoadBalancerImpl<>(getRegion(), landscape.getAwsLoadBalancer(
targetGroup.loadBalancerArns().iterator().next(), getRegion()), landscape);
@@ -55,12 +52,12 @@ extends NamedImpl implements TargetGroup<ShardingKey, MetricsT> {
}
@Override
public void addTargets(Iterable<AwsInstance<ShardingKey, MetricsT>> targets) {
public void addTargets(Iterable<AwsInstance<ShardingKey>> targets) {
landscape.addTargetsToTargetGroup(this, targets);
}
@Override
public void removeTargets(Iterable<AwsInstance<ShardingKey, MetricsT>> targets) {
public void removeTargets(Iterable<AwsInstance<ShardingKey>> targets) {
landscape.removeTargetsFromTargetGroup(this, targets);
}
@@ -1,39 +1,31 @@
package com.sap.sse.landscape.aws.orchestration;
import com.sap.sse.landscape.application.ApplicationProcess;
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
import com.sap.sse.landscape.aws.AwsLandscape;
import com.sap.sse.landscape.orchestration.AbstractProcedureImpl;
import com.sap.sse.landscape.orchestration.Procedure;
public abstract class AbstractAwsProcedureImpl<ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends AbstractProcedureImpl<ShardingKey, MetricsT, ProcessT> {
public abstract class AbstractAwsProcedureImpl<ShardingKey>
extends AbstractProcedureImpl<ShardingKey> {
public static interface Builder<BuilderT extends com.sap.sse.common.Builder<BuilderT, T>,
T extends Procedure<ShardingKey, MetricsT, ProcessT>, ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends Procedure.Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT> {
T extends Procedure<ShardingKey>, ShardingKey>
extends Procedure.Builder<BuilderT, T, ShardingKey> {
}
protected abstract static class BuilderImpl<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT>,
T extends Procedure<ShardingKey, MetricsT, ProcessT>, ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends AbstractProcedureImpl.BuilderImpl<BuilderT, T, ShardingKey, MetricsT, ProcessT>
implements Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT> {
protected AwsLandscape<ShardingKey, MetricsT, ProcessT> getLandscape() {
return (AwsLandscape<ShardingKey, MetricsT, ProcessT>) super.getLandscape();
protected abstract static class BuilderImpl<BuilderT extends Builder<BuilderT, T, ShardingKey>,
T extends Procedure<ShardingKey>, ShardingKey>
extends AbstractProcedureImpl.BuilderImpl<BuilderT, T, ShardingKey>
implements Builder<BuilderT, T, ShardingKey> {
protected AwsLandscape<ShardingKey> getLandscape() {
return (AwsLandscape<ShardingKey>) super.getLandscape();
}
}
public AbstractAwsProcedureImpl(BuilderImpl<?, ?, ShardingKey, MetricsT, ProcessT> builder) {
public AbstractAwsProcedureImpl(BuilderImpl<?, ?, ShardingKey> builder) {
super(builder);
}
@Override
public AwsLandscape<ShardingKey, MetricsT, ProcessT> getLandscape() {
return (AwsLandscape<ShardingKey, MetricsT, ProcessT>) super.getLandscape();
public AwsLandscape<ShardingKey> getLandscape() {
return (AwsLandscape<ShardingKey>) super.getLandscape();
}
}
@@ -71,7 +71,7 @@ implements UserDataProvider {
extends com.sap.sse.common.Builder<BuilderT, T> {
BuilderT setRegion(AwsRegion region);
BuilderT setLandscape(AwsLandscape<ShardingKey, MetricsT, ProcessT> landscape);
BuilderT setLandscape(AwsLandscape<ShardingKey> landscape);
BuilderT setRelease(Release release);
@@ -115,7 +115,7 @@ implements UserDataProvider {
private static final String DEFAULT_SMTP_HOSTNAME_PATTERN = "email-smtp.%s.amazonaws.com";
private static final String DEFAULT_SMTP_USER = "AKIAIHCQEFAZDLIK7SUQ";
private static final Integer DEFAULT_SMTP_PORT = 25;
private AwsLandscape<ShardingKey, MetricsT, ProcessT> landscape;
private AwsLandscape<ShardingKey> landscape;
private AwsRegion region;
private Optional<Release> release = Optional.empty();
private String serverName;
@@ -142,12 +142,12 @@ implements UserDataProvider {
}
@Override
public BuilderT setLandscape(AwsLandscape<ShardingKey, MetricsT, ProcessT> landscape) {
public BuilderT setLandscape(AwsLandscape<ShardingKey> landscape) {
this.landscape = landscape;
return self();
}
protected AwsLandscape<ShardingKey, MetricsT, ProcessT> getLandscape() {
protected AwsLandscape<ShardingKey> getLandscape() {
return landscape;
}
@@ -15,7 +15,6 @@ import com.sap.sse.landscape.Region;
import com.sap.sse.landscape.application.ApplicationProcess;
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
import com.sap.sse.landscape.aws.ApplicationLoadBalancer;
import com.sap.sse.landscape.aws.AwsInstance;
import com.sap.sse.landscape.aws.AwsLandscape;
import com.sap.sse.landscape.orchestration.Procedure;
@@ -30,31 +29,29 @@ import com.sap.sse.landscape.orchestration.Procedure;
* @author Axel Uhl (D043530)
*/
public class CreateDNSBasedLoadBalancerMapping<ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>,
HostT extends AwsInstance<ShardingKey, MetricsT>>
extends CreateLoadBalancerMapping<ShardingKey, MetricsT, ProcessT, HostT>
implements Procedure<ShardingKey, MetricsT, ProcessT> {
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends CreateLoadBalancerMapping<ShardingKey, MetricsT, ProcessT>
implements Procedure<ShardingKey> {
private static final String DNS_MAPPED_ALB_NAME_PREFIX = "DNSMapped-";
private static final Pattern ALB_NAME_PATTERN = Pattern.compile(DNS_MAPPED_ALB_NAME_PREFIX+"(.*)$");
public static interface Builder<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT>,
T extends CreateDNSBasedLoadBalancerMapping<ShardingKey, MetricsT, ProcessT, HostT>,
public static interface Builder<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT>,
T extends CreateDNSBasedLoadBalancerMapping<ShardingKey, MetricsT, ProcessT>,
ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>, HostT extends AwsInstance<ShardingKey, MetricsT>>
extends CreateLoadBalancerMapping.Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT> {
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends CreateLoadBalancerMapping.Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT> {
}
protected static class BuilderImpl<BuilderT extends Builder<BuilderT, CreateDNSBasedLoadBalancerMapping<ShardingKey, MetricsT, ProcessT, HostT>, ShardingKey, MetricsT, ProcessT, HostT>,
protected static class BuilderImpl<BuilderT extends Builder<BuilderT, CreateDNSBasedLoadBalancerMapping<ShardingKey, MetricsT, ProcessT>, ShardingKey, MetricsT, ProcessT>,
ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>,
HostT extends AwsInstance<ShardingKey, MetricsT>>
extends CreateLoadBalancerMapping.BuilderImpl<BuilderT, CreateDNSBasedLoadBalancerMapping<ShardingKey, MetricsT, ProcessT, HostT>, ShardingKey, MetricsT, ProcessT, HostT>
implements Builder<BuilderT, CreateDNSBasedLoadBalancerMapping<ShardingKey, MetricsT, ProcessT, HostT>, ShardingKey, MetricsT, ProcessT, HostT> {
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends CreateLoadBalancerMapping.BuilderImpl<BuilderT, CreateDNSBasedLoadBalancerMapping<ShardingKey, MetricsT, ProcessT>, ShardingKey, MetricsT, ProcessT>
implements Builder<BuilderT, CreateDNSBasedLoadBalancerMapping<ShardingKey, MetricsT, ProcessT>, ShardingKey, MetricsT, ProcessT> {
private static final Logger logger = Logger.getLogger(BuilderImpl.class.getName());
@Override
public ApplicationLoadBalancer<ShardingKey, MetricsT> getLoadBalancerUsed() throws InterruptedException {
final ApplicationLoadBalancer<ShardingKey, MetricsT> result;
public ApplicationLoadBalancer<ShardingKey> getLoadBalancerUsed() throws InterruptedException {
final ApplicationLoadBalancer<ShardingKey> result;
if (super.getLoadBalancerUsed() != null) {
result = super.getLoadBalancerUsed();
} else {
@@ -68,11 +65,11 @@ implements Procedure<ShardingKey, MetricsT, ProcessT> {
* at least the length of {@link #createRules()} additional rules available.
* @throws InterruptedException
*/
private ApplicationLoadBalancer<ShardingKey, MetricsT> getOrCreateDNSMappedLoadBalancer(
AwsLandscape<ShardingKey, MetricsT, ProcessT> landscape, Region region) throws InterruptedException {
ApplicationLoadBalancer<ShardingKey, MetricsT> result = null;
private ApplicationLoadBalancer<ShardingKey> getOrCreateDNSMappedLoadBalancer(
AwsLandscape<ShardingKey> landscape, Region region) throws InterruptedException {
ApplicationLoadBalancer<ShardingKey> result = null;
final Set<String> loadBalancerNames = new HashSet<>();
for (final ApplicationLoadBalancer<ShardingKey, MetricsT> loadBalancer : landscape.getLoadBalancers(region)) {
for (final ApplicationLoadBalancer<ShardingKey> loadBalancer : landscape.getLoadBalancers(region)) {
if (ALB_NAME_PATTERN.matcher(loadBalancer.getName()).matches()) {
loadBalancerNames.add(loadBalancer.getName());
if (Util.size(loadBalancer.getRules()) <= MAX_RULES_PER_ALB - NUMBER_OF_RULES_PER_REPLICA_SET) {
@@ -106,19 +103,19 @@ implements Procedure<ShardingKey, MetricsT, ProcessT> {
}
@Override
public CreateDNSBasedLoadBalancerMapping<ShardingKey, MetricsT, ProcessT, HostT> build() throws Exception {
return new CreateDNSBasedLoadBalancerMapping<ShardingKey, MetricsT, ProcessT, HostT>(this);
public CreateDNSBasedLoadBalancerMapping<ShardingKey, MetricsT, ProcessT> build() throws Exception {
return new CreateDNSBasedLoadBalancerMapping<ShardingKey, MetricsT, ProcessT>(this);
}
}
public static <ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>, HostT extends AwsInstance<ShardingKey, MetricsT>,
BuilderT extends Builder<BuilderT, CreateDNSBasedLoadBalancerMapping<ShardingKey, MetricsT, ProcessT, HostT>, ShardingKey, MetricsT, ProcessT, HostT>>
Builder<BuilderT, CreateDNSBasedLoadBalancerMapping<ShardingKey, MetricsT, ProcessT, HostT>, ShardingKey, MetricsT, ProcessT, HostT> builder() {
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>,
BuilderT extends Builder<BuilderT, CreateDNSBasedLoadBalancerMapping<ShardingKey, MetricsT, ProcessT>, ShardingKey, MetricsT, ProcessT>>
Builder<BuilderT, CreateDNSBasedLoadBalancerMapping<ShardingKey, MetricsT, ProcessT>, ShardingKey, MetricsT, ProcessT> builder() {
return new BuilderImpl<>();
}
protected CreateDNSBasedLoadBalancerMapping(BuilderImpl<?, ShardingKey, MetricsT, ProcessT, HostT> builder) throws Exception {
protected CreateDNSBasedLoadBalancerMapping(BuilderImpl<?, ShardingKey, MetricsT, ProcessT> builder) throws Exception {
super(builder);
}
@@ -130,7 +127,7 @@ implements Procedure<ShardingKey, MetricsT, ProcessT> {
private void createRoute53Mapping() {
final String hostname = this.getHostName();
final ApplicationLoadBalancer<ShardingKey, MetricsT> alb = getLoadBalancerUsed();
final ApplicationLoadBalancer<ShardingKey> alb = getLoadBalancerUsed();
getLandscape().setDNSRecordToApplicationLoadBalancer(getLandscape().getDNSHostedZoneId(
getHostedZoneName(hostname)), hostname, alb);
}
@@ -14,24 +14,24 @@ import com.sap.sse.landscape.orchestration.Procedure;
* @author Axel Uhl (D043530)
*/
public class CreateDynamicLoadBalancerMapping<ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>, HostT extends AwsInstance<ShardingKey, MetricsT>>
extends CreateLoadBalancerMapping<ShardingKey, MetricsT, ProcessT, HostT>
implements Procedure<ShardingKey, MetricsT, ProcessT> {
public static interface Builder<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, MasterProcessT, HostT>,
T extends CreateDynamicLoadBalancerMapping<ShardingKey, MetricsT, MasterProcessT, HostT>,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends CreateLoadBalancerMapping<ShardingKey, MetricsT, ProcessT>
implements Procedure<ShardingKey> {
public static interface Builder<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, MasterProcessT>,
T extends CreateDynamicLoadBalancerMapping<ShardingKey, MetricsT, MasterProcessT>,
ShardingKey, MetricsT extends ApplicationProcessMetrics,
MasterProcessT extends ApplicationProcess<ShardingKey, MetricsT, MasterProcessT>, HostT extends AwsInstance<ShardingKey, MetricsT>>
extends CreateLoadBalancerMapping.Builder<BuilderT, T, ShardingKey, MetricsT, MasterProcessT, HostT> {
MasterProcessT extends ApplicationProcess<ShardingKey, MetricsT, MasterProcessT>>
extends CreateLoadBalancerMapping.Builder<BuilderT, T, ShardingKey, MetricsT, MasterProcessT> {
}
protected static class BuilderImpl<BuilderT extends Builder<BuilderT, CreateDynamicLoadBalancerMapping<ShardingKey, MetricsT, ProcessT, HostT>, ShardingKey, MetricsT, ProcessT, HostT>,
protected static class BuilderImpl<BuilderT extends Builder<BuilderT, CreateDynamicLoadBalancerMapping<ShardingKey, MetricsT, ProcessT>, ShardingKey, MetricsT, ProcessT>,
ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>, HostT extends AwsInstance<ShardingKey, MetricsT>>
extends CreateLoadBalancerMapping.BuilderImpl<BuilderT, CreateDynamicLoadBalancerMapping<ShardingKey, MetricsT, ProcessT, HostT>, ShardingKey, MetricsT, ProcessT, HostT>
implements Builder<BuilderT, CreateDynamicLoadBalancerMapping<ShardingKey, MetricsT, ProcessT, HostT>, ShardingKey, MetricsT, ProcessT, HostT> {
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends CreateLoadBalancerMapping.BuilderImpl<BuilderT, CreateDynamicLoadBalancerMapping<ShardingKey, MetricsT, ProcessT>, ShardingKey, MetricsT, ProcessT>
implements Builder<BuilderT, CreateDynamicLoadBalancerMapping<ShardingKey, MetricsT, ProcessT>, ShardingKey, MetricsT, ProcessT> {
@Override
public ApplicationLoadBalancer<ShardingKey, MetricsT> getLoadBalancerUsed() throws InterruptedException {
final ApplicationLoadBalancer<ShardingKey, MetricsT> result;
public ApplicationLoadBalancer<ShardingKey> getLoadBalancerUsed() throws InterruptedException {
final ApplicationLoadBalancer<ShardingKey> result;
if (super.getLoadBalancerUsed() != null) {
result = super.getLoadBalancerUsed();
} else {
@@ -40,11 +40,11 @@ implements Procedure<ShardingKey, MetricsT, ProcessT> {
return result;
}
private ApplicationLoadBalancer<ShardingKey, MetricsT> getOrCreateNonDNSMappedLoadBalancer(
Region region, String hostname, AwsLandscape<ShardingKey, MetricsT, ProcessT> landscape) throws InterruptedException {
private ApplicationLoadBalancer<ShardingKey> getOrCreateNonDNSMappedLoadBalancer(
Region region, String hostname, AwsLandscape<ShardingKey> landscape) throws InterruptedException {
final String domainName = getHostedZoneName(hostname);
final ApplicationLoadBalancer<ShardingKey, MetricsT> existingLoadBalancer = landscape.getNonDNSMappedLoadBalancer(region, domainName);
final ApplicationLoadBalancer<ShardingKey, MetricsT> result;
final ApplicationLoadBalancer<ShardingKey> existingLoadBalancer = landscape.getNonDNSMappedLoadBalancer(region, domainName);
final ApplicationLoadBalancer<ShardingKey> result;
if (existingLoadBalancer != null) {
result = existingLoadBalancer;
} else {
@@ -56,28 +56,28 @@ implements Procedure<ShardingKey, MetricsT, ProcessT> {
}
private void createWildcardRoute53Mapping(
AwsLandscape<ShardingKey, MetricsT, ProcessT> landscape,
ApplicationLoadBalancer<ShardingKey, MetricsT> loadBalancer, String domainName) {
AwsLandscape<ShardingKey> landscape,
ApplicationLoadBalancer<ShardingKey> loadBalancer, String domainName) {
final String hostname = "*." + domainName;
landscape.setDNSRecordToApplicationLoadBalancer(landscape.getDNSHostedZoneId(domainName), hostname, loadBalancer);
}
@Override
public CreateDynamicLoadBalancerMapping<ShardingKey, MetricsT, ProcessT, HostT> build() throws Exception {
return new CreateDynamicLoadBalancerMapping<ShardingKey, MetricsT, ProcessT, HostT>(this);
public CreateDynamicLoadBalancerMapping<ShardingKey, MetricsT, ProcessT> build() throws Exception {
return new CreateDynamicLoadBalancerMapping<ShardingKey, MetricsT, ProcessT>(this);
}
}
public static <MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>,
HostT extends AwsInstance<ShardingKey, MetricsT>,
BuilderT extends Builder<BuilderT, CreateDynamicLoadBalancerMapping<ShardingKey, MetricsT, ProcessT, HostT>, ShardingKey, MetricsT, ProcessT, HostT>,
HostT extends AwsInstance<ShardingKey>,
BuilderT extends Builder<BuilderT, CreateDynamicLoadBalancerMapping<ShardingKey, MetricsT, ProcessT>, ShardingKey, MetricsT, ProcessT>,
ShardingKey>
Builder<BuilderT, CreateDynamicLoadBalancerMapping<ShardingKey, MetricsT, ProcessT, HostT>, ShardingKey, MetricsT, ProcessT, HostT> builder() {
return new BuilderImpl<BuilderT, ShardingKey, MetricsT, ProcessT, HostT>();
Builder<BuilderT, CreateDynamicLoadBalancerMapping<ShardingKey, MetricsT, ProcessT>, ShardingKey, MetricsT, ProcessT> builder() {
return new BuilderImpl<BuilderT, ShardingKey, MetricsT, ProcessT>();
}
protected CreateDynamicLoadBalancerMapping(BuilderImpl<?, ShardingKey, MetricsT, ProcessT, HostT> builder) throws Exception {
protected CreateDynamicLoadBalancerMapping(BuilderImpl<?, ShardingKey, MetricsT, ProcessT> builder) throws Exception {
super(builder);
}
}
@@ -71,15 +71,15 @@ import software.amazon.awssdk.services.elasticloadbalancingv2.model.TargetGroupT
* @author Axel Uhl (D043530)
*/
public abstract class CreateLoadBalancerMapping<ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>, HostT extends AwsInstance<ShardingKey, MetricsT>>
extends ProcedureWithTargetGroup<ShardingKey, MetricsT, ProcessT, HostT> {
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends ProcedureWithTargetGroup<ShardingKey> {
protected static int NUMBER_OF_RULES_PER_REPLICA_SET = 4;
protected static final int MAX_RULES_PER_ALB = 100;
protected static final int MAX_ALBS_PER_REGION = 20;
private final ProcessT process;
private final String hostname;
private TargetGroup<ShardingKey, MetricsT> masterTargetGroupCreated;
private TargetGroup<ShardingKey, MetricsT> publicTargetGroupCreated;
private TargetGroup<ShardingKey> masterTargetGroupCreated;
private TargetGroup<ShardingKey> publicTargetGroupCreated;
private Iterable<Rule> rulesAdded;
/**
@@ -95,12 +95,11 @@ extends ProcedureWithTargetGroup<ShardingKey, MetricsT, ProcessT, HostT> {
*
* @author Axel Uhl (D043530)
*/
public static interface Builder<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT>,
T extends CreateLoadBalancerMapping<ShardingKey, MetricsT, ProcessT, HostT>,
public static interface Builder<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT>,
T extends CreateLoadBalancerMapping<ShardingKey, MetricsT, ProcessT>,
ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>,
HostT extends AwsInstance<ShardingKey, MetricsT>>
extends ProcedureWithTargetGroup.Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT> {
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends ProcedureWithTargetGroup.Builder<BuilderT, T, ShardingKey> {
BuilderT setProcess(ProcessT process);
BuilderT setHostname(String hostname);
BuilderT setTimeout(Duration timeout);
@@ -108,12 +107,12 @@ extends ProcedureWithTargetGroup<ShardingKey, MetricsT, ProcessT, HostT> {
BuilderT setPrivateKeyEncryptionPassphrase(byte[] privateKeyEncryptionPassphrase);
}
protected abstract static class BuilderImpl<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT>,
T extends CreateLoadBalancerMapping<ShardingKey, MetricsT, ProcessT, HostT>,
protected abstract static class BuilderImpl<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT>,
T extends CreateLoadBalancerMapping<ShardingKey, MetricsT, ProcessT>,
ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>, HostT extends AwsInstance<ShardingKey, MetricsT>>
extends ProcedureWithTargetGroup.BuilderImpl<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT>
implements Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT> {
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends ProcedureWithTargetGroup.BuilderImpl<BuilderT, T, ShardingKey>
implements Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT> {
private static final Logger logger = Logger.getLogger(BuilderImpl.class.getName());
private String hostname;
private ProcessT process;
@@ -178,7 +177,7 @@ extends ProcedureWithTargetGroup<ShardingKey, MetricsT, ProcessT, HostT> {
return result;
}
protected void waitUntilLoadBalancerProvisioned(AwsLandscape<ShardingKey, MetricsT, ProcessT> landscape, ApplicationLoadBalancer<ShardingKey, MetricsT> loadBalancer) throws InterruptedException {
protected void waitUntilLoadBalancerProvisioned(AwsLandscape<ShardingKey> landscape, ApplicationLoadBalancer<ShardingKey> loadBalancer) throws InterruptedException {
final TimePoint startingToPollForReady = TimePoint.now();
while (landscape.getApplicationLoadBalancerStatus(loadBalancer).code() == LoadBalancerStateEnum.PROVISIONING
&& (!getOptionalTimeout().isPresent() || startingToPollForReady.until(TimePoint.now()).compareTo(getOptionalTimeout().get()) <= 0)) {
@@ -188,15 +187,15 @@ extends ProcedureWithTargetGroup<ShardingKey, MetricsT, ProcessT, HostT> {
}
}
protected CreateLoadBalancerMapping(BuilderImpl<?, ?, ShardingKey, MetricsT, ProcessT, HostT> builder) throws Exception {
protected CreateLoadBalancerMapping(BuilderImpl<?, ?, ShardingKey, MetricsT, ProcessT> builder) throws Exception {
super(builder);
this.process = builder.getProcess();
this.hostname = builder.getHostname();
}
@Override
public AwsLandscape<ShardingKey, MetricsT, ProcessT> getLandscape() {
return (AwsLandscape<ShardingKey, MetricsT, ProcessT>) super.getLandscape();
public AwsLandscape<ShardingKey> getLandscape() {
return (AwsLandscape<ShardingKey>) super.getLandscape();
}
@Override
@@ -238,17 +237,17 @@ extends ProcedureWithTargetGroup<ShardingKey, MetricsT, ProcessT, HostT> {
return hostname;
}
private AwsInstance<ShardingKey, MetricsT> getHost() {
private AwsInstance<ShardingKey> getHost() {
@SuppressWarnings("unchecked")
final AwsInstance<ShardingKey, MetricsT> result = (AwsInstance<ShardingKey, MetricsT>) getProcess().getHost();
final AwsInstance<ShardingKey> result = (AwsInstance<ShardingKey>) getProcess().getHost();
return result;
}
public TargetGroup<ShardingKey, MetricsT> getMasterTargetGroupCreated() {
public TargetGroup<ShardingKey> getMasterTargetGroupCreated() {
return masterTargetGroupCreated;
}
public TargetGroup<ShardingKey, MetricsT> getPublicTargetGroupCreated() {
public TargetGroup<ShardingKey> getPublicTargetGroupCreated() {
return publicTargetGroupCreated;
}
@@ -8,7 +8,6 @@ import com.sap.sse.landscape.Region;
import com.sap.sse.landscape.application.ApplicationProcess;
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
import com.sap.sse.landscape.aws.ApplicationLoadBalancer;
import com.sap.sse.landscape.aws.AwsInstance;
import com.sap.sse.landscape.aws.AwsLandscape;
import com.sap.sse.landscape.aws.TargetGroup;
@@ -21,11 +20,10 @@ import software.amazon.awssdk.services.elasticloadbalancingv2.model.Rule;
*
* @author Axel Uhl (D043530)
*/
public abstract class ProcedureWithTargetGroup<ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>, HostT extends AwsInstance<ShardingKey, MetricsT>>
extends AbstractAwsProcedureImpl<ShardingKey, MetricsT, ProcessT> {
public abstract class ProcedureWithTargetGroup<ShardingKey>
extends AbstractAwsProcedureImpl<ShardingKey> {
private static final String MASTER_TARGET_GROUP_SUFFIX = "-m";
private final ApplicationLoadBalancer<ShardingKey, MetricsT> loadBalancerUsed;
private final ApplicationLoadBalancer<ShardingKey> loadBalancerUsed;
private final String targetGroupNamePrefix;
private final String serverName;
private Iterable<Rule> rulesAdded;
@@ -36,29 +34,25 @@ extends AbstractAwsProcedureImpl<ShardingKey, MetricsT, ProcessT> {
*
* @author Axel Uhl (D043530)
*/
public static interface Builder<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT>,
T extends ProcedureWithTargetGroup<ShardingKey, MetricsT, ProcessT, HostT>,
ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>, HostT extends AwsInstance<ShardingKey, MetricsT>>
extends AbstractAwsProcedureImpl.Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT> {
BuilderT setLoadBalancerUsed(ApplicationLoadBalancer<ShardingKey, MetricsT> loadBalancerUsed);
public static interface Builder<BuilderT extends Builder<BuilderT, T, ShardingKey>,
T extends ProcedureWithTargetGroup<ShardingKey>, ShardingKey>
extends AbstractAwsProcedureImpl.Builder<BuilderT, T, ShardingKey> {
BuilderT setLoadBalancerUsed(ApplicationLoadBalancer<ShardingKey> loadBalancerUsed);
BuilderT setTargetGroupNamePrefix(String targetGroupNamePrefix);
BuilderT setServerName(String serverName);
}
protected abstract static class BuilderImpl<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT>,
T extends ProcedureWithTargetGroup<ShardingKey, MetricsT, ProcessT, HostT>,
ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>, HostT extends AwsInstance<ShardingKey, MetricsT>>
extends AbstractAwsProcedureImpl.BuilderImpl<BuilderT, T, ShardingKey, MetricsT, ProcessT>
implements Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT> {
private ApplicationLoadBalancer<ShardingKey, MetricsT> loadBalancerUsed;
protected abstract static class BuilderImpl<BuilderT extends Builder<BuilderT, T, ShardingKey>,
T extends ProcedureWithTargetGroup<ShardingKey>, ShardingKey>
extends AbstractAwsProcedureImpl.BuilderImpl<BuilderT, T, ShardingKey>
implements Builder<BuilderT, T, ShardingKey> {
private ApplicationLoadBalancer<ShardingKey> loadBalancerUsed;
private String targetGroupNamePrefix;
private String serverName;
@Override
public BuilderT setLoadBalancerUsed(
ApplicationLoadBalancer<ShardingKey, MetricsT> loadBalancerUsed) {
ApplicationLoadBalancer<ShardingKey> loadBalancerUsed) {
this.loadBalancerUsed = loadBalancerUsed;
return self();
}
@@ -76,7 +70,7 @@ extends AbstractAwsProcedureImpl<ShardingKey, MetricsT, ProcessT> {
return self();
}
protected ApplicationLoadBalancer<ShardingKey, MetricsT> getLoadBalancerUsed() throws InterruptedException {
protected ApplicationLoadBalancer<ShardingKey> getLoadBalancerUsed() throws InterruptedException {
return loadBalancerUsed;
}
@@ -88,34 +82,35 @@ extends AbstractAwsProcedureImpl<ShardingKey, MetricsT, ProcessT> {
return serverName;
}
protected AwsLandscape<ShardingKey, MetricsT, ProcessT> getLandscape() {
return (AwsLandscape<ShardingKey, MetricsT, ProcessT>) super.getLandscape();
protected AwsLandscape<ShardingKey> getLandscape() {
return (AwsLandscape<ShardingKey>) super.getLandscape();
}
}
protected ProcedureWithTargetGroup(BuilderImpl<?, ?, ShardingKey, MetricsT, ProcessT, HostT> builder) throws Exception {
protected ProcedureWithTargetGroup(BuilderImpl<?, ?, ShardingKey> builder) throws Exception {
super(builder);
this.loadBalancerUsed = builder.getLoadBalancerUsed();
this.targetGroupNamePrefix = builder.getTargetGroupNamePrefix();
this.serverName = builder.getServerName();
}
protected TargetGroup<ShardingKey, MetricsT> createTargetGroup(Region region, String targetGroupName, ProcessT process) {
protected <ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>, MetricsT extends ApplicationProcessMetrics>
TargetGroup<ShardingKey> createTargetGroup(Region region, String targetGroupName, ProcessT process) {
return getLandscape().createTargetGroup(getLoadBalancerUsed().getRegion(), targetGroupName,
process.getPort(), process.getHealthCheckPath(),
/* use traffic port as health check port, too */ process.getPort()); // TODO this doesn't health-check the reverse proxy running on the instance for default set-ups with only one process running on the instance; but how do we know?
}
@Override
public AwsLandscape<ShardingKey, MetricsT, ProcessT> getLandscape() {
return (AwsLandscape<ShardingKey, MetricsT, ProcessT>) super.getLandscape();
public AwsLandscape<ShardingKey> getLandscape() {
return (AwsLandscape<ShardingKey>) super.getLandscape();
}
protected String getMasterTargetGroupName() {
return getPublicTargetGroupName()+MASTER_TARGET_GROUP_SUFFIX;
}
protected TargetGroup<ShardingKey, MetricsT> getMasterTargetGroup() throws JSchException, IOException, InterruptedException, SftpException {
protected TargetGroup<ShardingKey> getMasterTargetGroup() throws JSchException, IOException, InterruptedException, SftpException {
return getLandscape().getTargetGroup(loadBalancerUsed.getRegion(), getMasterTargetGroupName());
}
@@ -123,11 +118,11 @@ extends AbstractAwsProcedureImpl<ShardingKey, MetricsT, ProcessT> {
return targetGroupNamePrefix+serverName;
}
protected TargetGroup<ShardingKey, MetricsT> getPublicTargetGroup() throws JSchException, IOException, InterruptedException, SftpException {
protected TargetGroup<ShardingKey> getPublicTargetGroup() throws JSchException, IOException, InterruptedException, SftpException {
return getLandscape().getTargetGroup(loadBalancerUsed.getRegion(), getPublicTargetGroupName());
}
public ApplicationLoadBalancer<ShardingKey, MetricsT> getLoadBalancerUsed() {
public ApplicationLoadBalancer<ShardingKey> getLoadBalancerUsed() {
return loadBalancerUsed;
}
@@ -21,8 +21,8 @@ import com.sap.sse.landscape.aws.impl.AwsRegion;
public class StartAwsApplicationHost<ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>,
HostT extends AwsInstance<ShardingKey, MetricsT>>
extends StartAwsHost<ShardingKey, MetricsT, ProcessT, HostT> {
HostT extends AwsInstance<ShardingKey>>
extends StartAwsHost<ShardingKey, HostT> {
/**
* When setting the {@link #setLandscape(Landscape) landscape} or the {@link #setRegion(AwsRegion) region}, these
* settings are also copied to the {@link AwsApplicationConfiguration.Builder application configuration builder}.
@@ -30,19 +30,19 @@ extends StartAwsHost<ShardingKey, MetricsT, ProcessT, HostT> {
* @author Axel Uhl (D043530)
*/
public static interface Builder<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT>,
T extends StartAwsHost<ShardingKey, MetricsT, ProcessT, HostT>, ShardingKey,
T extends StartAwsHost<ShardingKey, HostT>, ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>,
HostT extends AwsInstance<ShardingKey, MetricsT>>
extends StartAwsHost.Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT> {
HostT extends AwsInstance<ShardingKey>>
extends StartAwsHost.Builder<BuilderT, T, ShardingKey, HostT> {
}
protected abstract static class BuilderImpl<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT>,
T extends StartAwsHost<ShardingKey, MetricsT, ProcessT, HostT>, ShardingKey,
T extends StartAwsHost<ShardingKey, HostT>, ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>,
HostT extends AwsInstance<ShardingKey, MetricsT>>
extends StartAwsHost.BuilderImpl<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT>
HostT extends AwsInstance<ShardingKey>>
extends StartAwsHost.BuilderImpl<BuilderT, T, ShardingKey, HostT>
implements Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT> {
private final AwsApplicationConfiguration.Builder<?, ?, ShardingKey, MetricsT, ProcessT> applicationConfigurationBuilder;
@@ -62,8 +62,8 @@ extends StartAwsHost<ShardingKey, MetricsT, ProcessT, HostT> {
}
@Override
public BuilderT setLandscape(Landscape<ShardingKey, MetricsT, ProcessT> landscape) {
getApplicationConfigurationBuilder().setLandscape((AwsLandscape<ShardingKey, MetricsT, ProcessT>) landscape);
public BuilderT setLandscape(Landscape<ShardingKey> landscape) {
getApplicationConfigurationBuilder().setLandscape((AwsLandscape<ShardingKey>) landscape);
return super.setLandscape(landscape);
}
@@ -74,13 +74,12 @@ extends StartAwsHost<ShardingKey, MetricsT, ProcessT, HostT> {
protected Optional<Duration> getOptionalTimeout() {
return super.getOptionalTimeout();
}
}
private final AwsApplicationConfiguration<ShardingKey, MetricsT, ProcessT> applicationConfiguration;
private final Optional<Duration> optionalTimeout;
protected StartAwsApplicationHost(BuilderImpl<?, ? extends StartAwsHost<ShardingKey, MetricsT, ProcessT, HostT>, ShardingKey, MetricsT, ProcessT, HostT> builder) throws Exception {
protected StartAwsApplicationHost(BuilderImpl<?, ? extends StartAwsHost<ShardingKey, HostT>, ShardingKey, MetricsT, ProcessT, HostT> builder) throws Exception {
super(builder);
this.optionalTimeout = builder.getOptionalTimeout();
applicationConfiguration = builder.getApplicationConfigurationBuilder().build();
@@ -36,11 +36,8 @@ import software.amazon.awssdk.services.ec2.model.InstanceType;
*
* @author Axel Uhl (D043530)
*/
public abstract class StartAwsHost<ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>,
HostT extends AwsInstance<ShardingKey, MetricsT>>
extends StartHost<ShardingKey, MetricsT, ProcessT, HostT> {
public abstract class StartAwsHost<ShardingKey, HostT extends AwsInstance<ShardingKey>>
extends StartHost<ShardingKey, HostT> {
protected static final String NAME_TAG_NAME = "Name";
private final List<String> userData;
@@ -49,7 +46,7 @@ extends StartHost<ShardingKey, MetricsT, ProcessT, HostT> {
private final String keyName;
private final Iterable<SecurityGroup> securityGroups;
private final Optional<Tags> tags;
private final HostSupplier<ShardingKey, MetricsT, ProcessT, HostT> hostSupplier;
private final HostSupplier<ShardingKey, HostT> hostSupplier;
private final byte[] privateKeyEncryptionPassphrase;
private HostT host;
@@ -74,12 +71,10 @@ extends StartHost<ShardingKey, MetricsT, ProcessT, HostT> {
*
* @author Axel Uhl (D043530)
*/
public static interface Builder<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT>,
T extends StartAwsHost<ShardingKey, MetricsT, ProcessT, HostT>, ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>,
HostT extends AwsInstance<ShardingKey, MetricsT>>
extends StartHost.Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT> {
public static interface Builder<BuilderT extends Builder<BuilderT, T, ShardingKey, HostT>,
T extends StartAwsHost<ShardingKey, HostT>, ShardingKey,
HostT extends AwsInstance<ShardingKey>>
extends StartHost.Builder<BuilderT, T, ShardingKey, HostT> {
BuilderT setInstanceType(InstanceType instanceType);
BuilderT setAvailabilityZone(AwsAvailabilityZone availabilityZone);
@@ -108,16 +103,14 @@ extends StartHost<ShardingKey, MetricsT, ProcessT, HostT> {
BuilderT setInstanceName(String name);
BuilderT setHostSupplier(HostSupplier<ShardingKey, MetricsT, ProcessT, HostT> hostSupplier);
BuilderT setHostSupplier(HostSupplier<ShardingKey, HostT> hostSupplier);
}
protected abstract static class BuilderImpl<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT>,
T extends StartAwsHost<ShardingKey, MetricsT, ProcessT, HostT>, ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>,
HostT extends AwsInstance<ShardingKey, MetricsT>>
extends StartHost.BuilderImpl<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT>
implements Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT> {
protected abstract static class BuilderImpl<BuilderT extends Builder<BuilderT, T, ShardingKey, HostT>,
T extends StartAwsHost<ShardingKey, HostT>, ShardingKey,
HostT extends AwsInstance<ShardingKey>>
extends StartHost.BuilderImpl<BuilderT, T, ShardingKey, HostT>
implements Builder<BuilderT, T, ShardingKey, HostT> {
private InstanceType instanceType;
private AwsAvailabilityZone availabilityZone;
private String keyName;
@@ -126,11 +119,11 @@ extends StartHost<ShardingKey, MetricsT, ProcessT, HostT> {
private List<String> userData = new ArrayList<>();
private AwsRegion region;
private String instanceName;
private HostSupplier<ShardingKey, MetricsT, ProcessT, HostT> hostSupplier;
private HostSupplier<ShardingKey, HostT> hostSupplier;
private byte[] privateKeyEncryptionPassphrase;
protected AwsLandscape<ShardingKey, MetricsT, ProcessT> getLandscape() {
return (AwsLandscape<ShardingKey, MetricsT, ProcessT>) super.getLandscape();
protected AwsLandscape<ShardingKey> getLandscape() {
return (AwsLandscape<ShardingKey>) super.getLandscape();
}
protected InstanceType getInstanceType() {
@@ -138,8 +131,7 @@ extends StartHost<ShardingKey, MetricsT, ProcessT, HostT> {
}
@Override
public BuilderT setInstanceType(
InstanceType instanceType) {
public BuilderT setInstanceType(InstanceType instanceType) {
this.instanceType = instanceType;
return self();
}
@@ -232,12 +224,12 @@ extends StartHost<ShardingKey, MetricsT, ProcessT, HostT> {
return self();
}
protected HostSupplier<ShardingKey, MetricsT, ProcessT, HostT> getHostSupplier() {
protected HostSupplier<ShardingKey, HostT> getHostSupplier() {
return hostSupplier;
}
@Override
public BuilderT setHostSupplier(HostSupplier<ShardingKey, MetricsT, ProcessT, HostT> hostSupplier) {
public BuilderT setHostSupplier(HostSupplier<ShardingKey, HostT> hostSupplier) {
this.hostSupplier = hostSupplier;
return self();
}
@@ -253,7 +245,7 @@ extends StartHost<ShardingKey, MetricsT, ProcessT, HostT> {
}
}
protected StartAwsHost(BuilderImpl<?, ? extends StartAwsHost<ShardingKey, MetricsT, ProcessT, HostT>, ShardingKey, MetricsT, ProcessT, HostT> builder) {
protected StartAwsHost(BuilderImpl<?, ? extends StartAwsHost<ShardingKey, HostT>, ShardingKey, HostT> builder) {
super(builder);
this.userData = new ArrayList<>();
for (final String ud : builder.getUserData()) {
@@ -271,14 +263,14 @@ extends StartHost<ShardingKey, MetricsT, ProcessT, HostT> {
protected static <ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
AmazonMachineImage<ShardingKey, MetricsT> getLatestImageOfType(String imageType, AwsLandscape<ShardingKey, MetricsT, ProcessT> landscape, Region region) {
AmazonMachineImage<ShardingKey> getLatestImageOfType(String imageType, AwsLandscape<ShardingKey> landscape, Region region) {
return landscape.getLatestImageWithType(region, imageType);
}
protected static <ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
AwsAvailabilityZone getRandomAvailabilityZone(AwsRegion region, AwsLandscape<ShardingKey, MetricsT, ProcessT> landscape) {
AwsAvailabilityZone getRandomAvailabilityZone(AwsRegion region, AwsLandscape<ShardingKey> landscape) {
final Iterable<AvailabilityZone> azs = landscape.getAvailabilityZones(region);
return (AwsAvailabilityZone) Util.get(azs, new Random().nextInt(Util.size(azs)));
}
@@ -286,13 +278,13 @@ extends StartHost<ShardingKey, MetricsT, ProcessT, HostT> {
protected static <ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
Set<SecurityGroup> getDefaultSecurityGroupForApplicationHosts(Landscape<ShardingKey, MetricsT, ProcessT> landscape, Region region) {
Set<SecurityGroup> getDefaultSecurityGroupForApplicationHosts(Landscape<ShardingKey> landscape, Region region) {
return Collections.singleton(landscape.getDefaultSecurityGroupForApplicationHosts(region));
}
@Override
public AwsLandscape<ShardingKey, MetricsT, ProcessT> getLandscape() {
return (AwsLandscape<ShardingKey, MetricsT, ProcessT>) super.getLandscape();
public AwsLandscape<ShardingKey> getLandscape() {
return (AwsLandscape<ShardingKey>) super.getLandscape();
}
@Override
@@ -2,8 +2,6 @@ package com.sap.sse.landscape.aws.orchestration;
import java.util.Collections;
import com.sap.sse.landscape.application.ApplicationProcess;
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
import com.sap.sse.landscape.aws.AwsInstance;
import com.sap.sse.landscape.orchestration.Procedure;
@@ -19,12 +17,10 @@ import com.sap.sse.landscape.orchestration.Procedure;
* @param <ShardingKey>
* @param <HostT>
*/
public abstract class StartEmptyServer<T extends StartEmptyServer<T, ShardingKey, MetricsT, ProcessT, HostT>,
ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>,
HostT extends AwsInstance<ShardingKey, MetricsT>>
extends StartAwsHost<ShardingKey, MetricsT, ProcessT, HostT>
implements Procedure<ShardingKey, MetricsT, ProcessT> {
public abstract class StartEmptyServer<T extends StartEmptyServer<T, ShardingKey, HostT>,
ShardingKey, HostT extends AwsInstance<ShardingKey>>
extends StartAwsHost<ShardingKey, HostT>
implements Procedure<ShardingKey> {
private static final String IMAGE_UPGRADE_USER_DATA = "image-upgrade";
private static final String NO_SHUTDOWN_USER_DATA = "no-shutdown";
@@ -41,22 +37,18 @@ implements Procedure<ShardingKey, MetricsT, ProcessT> {
* </ul>
* @author Axel Uhl (D043530)
*/
public static interface Builder<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT>,
T extends StartEmptyServer<T, ShardingKey, MetricsT, ProcessT, HostT>,
ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>,
HostT extends AwsInstance<ShardingKey, MetricsT>>
extends StartAwsHost.Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT> {
public static interface Builder<BuilderT extends Builder<BuilderT, T, ShardingKey, HostT>,
T extends StartEmptyServer<T, ShardingKey, HostT>,
ShardingKey, HostT extends AwsInstance<ShardingKey>>
extends StartAwsHost.Builder<BuilderT, T, ShardingKey, HostT> {
BuilderT setNoShutdown(boolean noShutdown);
}
protected abstract static class BuilderImpl<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT>,
T extends StartEmptyServer<T, ShardingKey, MetricsT, ProcessT, HostT>,
ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>,
HostT extends AwsInstance<ShardingKey, MetricsT>>
extends StartAwsHost.BuilderImpl<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT>
implements Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT> {
protected abstract static class BuilderImpl<BuilderT extends Builder<BuilderT, T, ShardingKey, HostT>,
T extends StartEmptyServer<T, ShardingKey, HostT>,
ShardingKey, HostT extends AwsInstance<ShardingKey>>
extends StartAwsHost.BuilderImpl<BuilderT, T, ShardingKey, HostT>
implements Builder<BuilderT, T, ShardingKey, HostT> {
private boolean noShutdown = true;
protected boolean isNoShutdown() {
@@ -74,7 +66,7 @@ implements Procedure<ShardingKey, MetricsT, ProcessT> {
}
}
public StartEmptyServer(BuilderImpl<?, T, ShardingKey, MetricsT, ProcessT, HostT> builder) {
public StartEmptyServer(BuilderImpl<?, T, ShardingKey, HostT> builder) {
super(builder);
addUserData(Collections.singleton(IMAGE_UPGRADE_USER_DATA));
if (builder.isNoShutdown()) {
@@ -11,8 +11,6 @@ import com.sap.sse.common.Duration;
import com.sap.sse.common.Util;
import com.sap.sse.landscape.Host;
import com.sap.sse.landscape.ProcessConfigurationVariable;
import com.sap.sse.landscape.application.ApplicationProcess;
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
import com.sap.sse.landscape.aws.AwsInstance;
import com.sap.sse.landscape.aws.AwsLandscape;
import com.sap.sse.landscape.aws.HostSupplier;
@@ -49,18 +47,15 @@ import software.amazon.awssdk.services.ec2.model.InstanceType;
* In this case no other node tagged for the desired replica set will be found, and the new instance will become the
* first primary of the new replica set.<p>
*
* TODO Why is the MetricsT parameter necessary when there is MongoMetrics?
*
* @author Axel Uhl (D043530)
*/
public class StartMongoDBServer<ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends StartAwsHost<ShardingKey, MetricsT, ProcessT, AwsInstance<ShardingKey, MetricsT>> {
public class StartMongoDBServer<ShardingKey, ProcessT extends MongoProcess>
extends StartAwsHost<ShardingKey, AwsInstance<ShardingKey>> {
private static enum MongoDBReplicaSetUserData implements ProcessConfigurationVariable {
REPLICA_SET_NAME, REPLICA_SET_PRIMARY, REPLICA_SET_PRIORITY, REPLICA_SET_VOTES;
}
private MongoProcess mongoProcess;
private ProcessT mongoProcess;
private final String replicaSetName;
@@ -95,10 +90,9 @@ extends StartAwsHost<ShardingKey, MetricsT, ProcessT, AwsInstance<ShardingKey, M
*
* @author Axel Uhl (D043530)
*/
public static interface Builder<BuilderT extends Builder<BuilderT, ShardingKey, MetricsT, ProcessT>,
ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends StartAwsHost.Builder<BuilderT, StartMongoDBServer<ShardingKey, MetricsT, ProcessT>, ShardingKey, MetricsT, ProcessT, AwsInstance<ShardingKey, MetricsT>> {
public static interface Builder<BuilderT extends Builder<BuilderT, ShardingKey, ProcessT>,
ShardingKey, ProcessT extends MongoProcess>
extends StartAwsHost.Builder<BuilderT, StartMongoDBServer<ShardingKey, ProcessT>, ShardingKey, AwsInstance<ShardingKey>> {
/**
* The default {@link #setImageType(String) image type} used for launching a MongoDB server.
*/
@@ -113,11 +107,10 @@ extends StartAwsHost<ShardingKey, MetricsT, ProcessT, AwsInstance<ShardingKey, M
BuilderT setReplicaSetVotes(int replicaSetVotes);
}
protected static class BuilderImpl<BuilderT extends Builder<BuilderT, ShardingKey, MetricsT, ProcessT>,
ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends StartAwsHost.BuilderImpl<BuilderT, StartMongoDBServer<ShardingKey, MetricsT, ProcessT>, ShardingKey, MetricsT, ProcessT, AwsInstance<ShardingKey, MetricsT>>
implements Builder<BuilderT, ShardingKey, MetricsT, ProcessT> {
protected static class BuilderImpl<BuilderT extends Builder<BuilderT, ShardingKey, ProcessT>,
ShardingKey, ProcessT extends MongoProcess>
extends StartAwsHost.BuilderImpl<BuilderT, StartMongoDBServer<ShardingKey, ProcessT>, ShardingKey, AwsInstance<ShardingKey>>
implements Builder<BuilderT, ShardingKey, ProcessT> {
private String replicaSetName = AwsLandscape.MONGO_DEFAULT_REPLICA_SET_NAME;
private String replicaSetPrimary;
private boolean replicaSetPrimaryWasSetExplicitly = false;
@@ -129,7 +122,7 @@ extends StartAwsHost<ShardingKey, MetricsT, ProcessT, AwsInstance<ShardingKey, M
}
@Override
public HostSupplier<ShardingKey, MetricsT, ProcessT, AwsInstance<ShardingKey, MetricsT>> getHostSupplier() {
public HostSupplier<ShardingKey, AwsInstance<ShardingKey>> getHostSupplier() {
return AwsInstanceImpl::new;
}
@@ -221,7 +214,7 @@ extends StartAwsHost<ShardingKey, MetricsT, ProcessT, AwsInstance<ShardingKey, M
}
@Override
public StartMongoDBServer<ShardingKey, MetricsT, ProcessT> build() throws URISyntaxException, JSchException, IOException, InterruptedException {
public StartMongoDBServer<ShardingKey, ProcessT> build() throws URISyntaxException, JSchException, IOException, InterruptedException {
setTags(getLandscape().getTagForMongoProcess(getTags().orElse(Tags.empty()), getReplicaSetName(), MongoDBConstants.DEFAULT_PORT));
if (!isSecurityGroupsSet()) {
setSecurityGroups(Collections.singleton(getLandscape().getDefaultSecurityGroupForMongoDBHosts(getRegion())));
@@ -238,13 +231,12 @@ extends StartAwsHost<ShardingKey, MetricsT, ProcessT, AwsInstance<ShardingKey, M
}
}
public static <BuilderT extends Builder<BuilderT, ShardingKey, MetricsT, ProcessT>,ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
Builder<BuilderT, ShardingKey, MetricsT, ProcessT> builder() {
public static <BuilderT extends Builder<BuilderT, ShardingKey, ProcessT>, ShardingKey, ProcessT extends MongoProcess>
Builder<BuilderT, ShardingKey, ProcessT> builder() {
return new BuilderImpl<>();
}
protected StartMongoDBServer(BuilderImpl<?, ShardingKey, MetricsT, ProcessT> builder) throws URISyntaxException, JSchException, IOException, InterruptedException {
protected StartMongoDBServer(BuilderImpl<?, ShardingKey, ProcessT> builder) throws URISyntaxException, JSchException, IOException, InterruptedException {
super(builder);
this.replicaSetName = builder.getReplicaSetName();
if (builder.getReplicaSetName() != null) {
@@ -261,7 +253,7 @@ extends StartAwsHost<ShardingKey, MetricsT, ProcessT, AwsInstance<ShardingKey, M
/**
* The process launched by this procedure. {@link MongoProcess#getHost()} is expected to match {@link #getHost()}.
*/
public MongoProcess getMongoProcess() {
public ProcessT getMongoProcess() {
return mongoProcess;
}
@@ -269,7 +261,9 @@ extends StartAwsHost<ShardingKey, MetricsT, ProcessT, AwsInstance<ShardingKey, M
public void run() throws Exception {
super.run();
if (replicaSetName == null) {
mongoProcess = new MongoProcessImpl(getHost());
@SuppressWarnings("unchecked")
final ProcessT mongoProcessCast = (ProcessT) new MongoProcessImpl(getHost());
mongoProcess = mongoProcessCast;
} else {
// the host may not yet be in state RUNNING; we'd like to wait for this:
boolean running = Wait.wait(()->getLandscape().getInstance(getHost().getInstanceId(), getHost().getRegion()).state().name() == InstanceStateName.RUNNING,
@@ -279,7 +273,9 @@ extends StartAwsHost<ShardingKey, MetricsT, ProcessT, AwsInstance<ShardingKey, M
}
final MongoReplicaSet replicaSet = getLandscape().getDatabaseConfigurationForReplicaSet(getHost().getRegion(), replicaSetName);
final Host instance = Util.stream(replicaSet.getInstances()).filter(replica->replica.getHost().equals(getHost())).map(replica->replica.getHost()).findAny().get();
mongoProcess = new MongoProcessInReplicaSetImpl(replicaSet, MongoDBConstants.DEFAULT_PORT, instance);
@SuppressWarnings("unchecked")
final ProcessT mongoProcessCast = (ProcessT) new MongoProcessInReplicaSetImpl(replicaSet, MongoDBConstants.DEFAULT_PORT, instance);
mongoProcess = mongoProcessCast;
}
}
}
@@ -8,8 +8,7 @@ import com.sap.sse.landscape.application.ApplicationReplicaSet;
import com.sap.sse.landscape.application.Scope;
import com.sap.sse.landscape.rabbitmq.RabbitMQEndpoint;
public interface Landscape<ShardingKey, MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>> {
public interface Landscape<ShardingKey> {
/**
* The {@link Landscape#getLatestImageWithTag(Region, String, String)} method is
* used to obtain default images for specific host starting procedures that subclass this class. The
@@ -21,7 +20,8 @@ ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>> {
/**
* Tells which scope currently lives where
*/
Map<Scope<ShardingKey>, ApplicationReplicaSet<ShardingKey, MetricsT, ProcessT>> getScopes();
<ApplicationProcessMetricsT extends ApplicationProcessMetrics, ApplicationProcessT extends ApplicationProcess<ShardingKey, ApplicationProcessMetricsT, ApplicationProcessT>>
Map<Scope<ShardingKey>, ApplicationReplicaSet<ShardingKey, ApplicationProcessMetricsT, ApplicationProcessT>> getScopes();
/**
* @return the security group that shall be assigned by default to any application server host, whether master or
@@ -29,7 +29,6 @@ extends Process<RotatingFileBasedLog, MetricsT> {
* @param releaseRepository
* mandatory parameter required to enable resolving the release and enabling the download of its
* artifacts, including its release notes
* @param optionalKeyName TODO
* @return the release that this process is currently running
*/
Release getRelease(ReleaseRepository releaseRepository, Optional<Duration> optionalTimeout, Optional<String> optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception;
@@ -63,7 +62,6 @@ extends Process<RotatingFileBasedLog, MetricsT> {
* as the base name of the {@link #getServerDirectory() server's directory}. Often, it is also used as the name of
* the {@link Database}, at least when this is a master node, and the name of the RabbitMQ fan-out exchange used
* for replication.
* @param optionalKeyName TODO
*/
String getServerName(Optional<Duration> optionalTimeout, Optional<String> optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception;
@@ -82,7 +80,6 @@ extends Process<RotatingFileBasedLog, MetricsT> {
/**
* Obtains the last definition of the process configuration variable specified, or {@code null} if that variable cannot be found
* in the evaluated {@code env.sh} file.
* @param optionalKeyName TODO
* @throws Exception
*/
String getEnvShValueFor(ProcessConfigurationVariable variable, Optional<Duration> optionalTimeout, Optional<String> optionalKeyName, byte[] privateKeyEncryptionPassphrase)
@@ -4,27 +4,21 @@ import java.util.Optional;
import com.sap.sse.common.Duration;
import com.sap.sse.landscape.Landscape;
import com.sap.sse.landscape.application.ApplicationProcess;
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
public abstract class AbstractProcedureImpl<ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
implements Procedure<ShardingKey, MetricsT, ProcessT> {
protected abstract static class BuilderImpl<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT>,
T extends Procedure<ShardingKey, MetricsT, ProcessT>, ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
implements Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT> {
private Landscape<ShardingKey, MetricsT, ProcessT> landscape;
public abstract class AbstractProcedureImpl<ShardingKey>
implements Procedure<ShardingKey> {
protected abstract static class BuilderImpl<BuilderT extends Builder<BuilderT, T, ShardingKey>,
T extends Procedure<ShardingKey>, ShardingKey>
implements Builder<BuilderT, T, ShardingKey> {
private Landscape<ShardingKey> landscape;
private Optional<Duration> optionalTimeout;
protected Landscape<ShardingKey, MetricsT, ProcessT> getLandscape() {
protected Landscape<ShardingKey> getLandscape() {
return landscape;
}
@Override
public BuilderT setLandscape(Landscape<ShardingKey, MetricsT, ProcessT> landscape) {
public BuilderT setLandscape(Landscape<ShardingKey> landscape) {
this.landscape = landscape;
return self();
}
@@ -45,14 +39,14 @@ implements Procedure<ShardingKey, MetricsT, ProcessT> {
}
}
private final Landscape<ShardingKey, MetricsT, ProcessT> landscape;
private final Landscape<ShardingKey> landscape;
protected AbstractProcedureImpl(BuilderImpl<?, ?, ShardingKey, MetricsT, ProcessT> builder) {
protected AbstractProcedureImpl(BuilderImpl<?, ?, ShardingKey> builder) {
this.landscape = builder.getLandscape();
}
@Override
public Landscape<ShardingKey, MetricsT, ProcessT> getLandscape() {
public Landscape<ShardingKey> getLandscape() {
return landscape;
}
}
@@ -5,8 +5,6 @@ import java.util.Optional;
import com.sap.sse.common.Duration;
import com.sap.sse.concurrent.RunnableWithException;
import com.sap.sse.landscape.Landscape;
import com.sap.sse.landscape.application.ApplicationProcess;
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
/**
* Encodes a potentially compound sequence of actions that transform the landscape from one state to another, trying to
@@ -39,9 +37,7 @@ import com.sap.sse.landscape.application.ApplicationProcessMetrics;
* @author Axel Uhl (D043530)
*
*/
public interface Procedure<ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
public interface Procedure<ShardingKey>
extends RunnableWithException<Exception> {
/**
* The following defaults apply:
@@ -52,15 +48,12 @@ extends RunnableWithException<Exception> {
*
* @author Axel Uhl (D043530)
*/
public static interface Builder<BuilderT extends com.sap.sse.common.Builder<BuilderT, T>,
T extends Procedure<ShardingKey, MetricsT, ProcessT>, ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
public static interface Builder<BuilderT extends com.sap.sse.common.Builder<BuilderT, T>, T extends Procedure<ShardingKey>, ShardingKey>
extends com.sap.sse.common.Builder<BuilderT, T> {
BuilderT setLandscape(Landscape<ShardingKey, MetricsT, ProcessT> landscape);
BuilderT setLandscape(Landscape<ShardingKey> landscape);
BuilderT setOptionalTimeout(Optional<Duration> optionalTimeout);
}
Landscape<ShardingKey, MetricsT, ProcessT> getLandscape();
Landscape<ShardingKey> getLandscape();
}
@@ -3,15 +3,10 @@ package com.sap.sse.landscape.orchestration;
import com.sap.sse.landscape.Host;
import com.sap.sse.landscape.MachineImage;
import com.sap.sse.landscape.Region;
import com.sap.sse.landscape.application.ApplicationProcess;
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
public abstract class StartHost<ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>,
HostT extends Host>
extends AbstractProcedureImpl<ShardingKey, MetricsT, ProcessT>
implements Procedure<ShardingKey, MetricsT, ProcessT> {
public abstract class StartHost<ShardingKey, HostT extends Host>
extends AbstractProcedureImpl<ShardingKey>
implements Procedure<ShardingKey> {
private final MachineImage machineImage;
/**
@@ -25,23 +20,19 @@ implements Procedure<ShardingKey, MetricsT, ProcessT> {
*
* @author Axel Uhl (D043530)
*/
public static interface Builder<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT>,
T extends StartHost<ShardingKey, MetricsT, ProcessT, HostT>, ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>,
public static interface Builder<BuilderT extends Builder<BuilderT, T, ShardingKey, HostT>,
T extends StartHost<ShardingKey, HostT>, ShardingKey,
HostT extends Host>
extends Procedure.Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT> {
extends Procedure.Builder<BuilderT, T, ShardingKey> {
BuilderT setImageType(String imageType);
BuilderT setMachineImage(MachineImage machineImage);
}
protected abstract static class BuilderImpl<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT>,
T extends StartHost<ShardingKey, MetricsT, ProcessT, HostT>, ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>,
protected abstract static class BuilderImpl<BuilderT extends Builder<BuilderT, T, ShardingKey, HostT>,
T extends StartHost<ShardingKey, HostT>, ShardingKey,
HostT extends Host>
extends AbstractProcedureImpl.BuilderImpl<BuilderT, T, ShardingKey, MetricsT, ProcessT>
implements Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT, HostT> {
extends AbstractProcedureImpl.BuilderImpl<BuilderT, T, ShardingKey>
implements Builder<BuilderT, T, ShardingKey, HostT> {
private MachineImage machineImage;
private String imageType;
@@ -68,7 +59,7 @@ implements Procedure<ShardingKey, MetricsT, ProcessT> {
}
}
protected StartHost(BuilderImpl<?, ? extends StartHost<ShardingKey, MetricsT, ProcessT, HostT>, ShardingKey, MetricsT, ProcessT, HostT> builder) {
protected StartHost(BuilderImpl<?, ? extends StartHost<ShardingKey,HostT>, ShardingKey, HostT> builder) {
super(builder);
this.machineImage = builder.getMachineImage();
}
@@ -10,69 +10,62 @@ import com.sap.sse.landscape.application.ApplicationProcessMetrics;
import com.sap.sse.landscape.orchestration.AbstractProcedureImpl;
import com.sap.sse.landscape.orchestration.Procedure;
public class ProcedureSequence<ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends AbstractProcedureImpl<ShardingKey,MetricsT,ProcessT>
implements Procedure<ShardingKey, MetricsT, ProcessT>, Iterable<Procedure<ShardingKey, MetricsT, ProcessT>> {
public static interface Builder<BuilderT extends Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT>,
T extends ProcedureSequence<ShardingKey, MetricsT, ProcessT>, ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends Procedure.Builder<BuilderT, T, ShardingKey, MetricsT, ProcessT> {
public class ProcedureSequence<ShardingKey>
extends AbstractProcedureImpl<ShardingKey>
implements Procedure<ShardingKey>, Iterable<Procedure<ShardingKey>> {
public static interface Builder<BuilderT extends Builder<BuilderT, T, ShardingKey>,
T extends ProcedureSequence<ShardingKey>, ShardingKey>
extends Procedure.Builder<BuilderT, T, ShardingKey> {
/**
* An alias for {@link #then(com.sap.sse.landscape.orchestration.Procedure.Builder)} which makes writing
* a procedure sequence a bit more human-readable.
*/
default BuilderT first(Procedure.Builder<?, ?, ShardingKey, MetricsT, ProcessT> firstStepBuilder) {
default BuilderT first(Procedure.Builder<?, ?, ShardingKey> firstStepBuilder) {
return then(firstStepBuilder);
}
/**
* When building the procedure sequence, the next step is built with {@code stepBuilder}.
*/
BuilderT then(Procedure.Builder<?, ?, ShardingKey, MetricsT, ProcessT> stepBuilder);
BuilderT then(Procedure.Builder<?, ?, ShardingKey> stepBuilder);
}
protected static class BuilderImpl<BuilderT extends Builder<BuilderT, ProcedureSequence<ShardingKey, MetricsT, ProcessT>, ShardingKey, MetricsT, ProcessT>,
ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>>
extends AbstractProcedureImpl.BuilderImpl<BuilderT, ProcedureSequence<ShardingKey, MetricsT, ProcessT>, ShardingKey, MetricsT, ProcessT>
implements Builder<BuilderT, ProcedureSequence<ShardingKey, MetricsT, ProcessT>, ShardingKey, MetricsT, ProcessT> {
final List<Procedure.Builder<?, ?, ShardingKey, MetricsT, ProcessT>> stepBuilders = new ArrayList<>();
protected static class BuilderImpl<BuilderT extends Builder<BuilderT, ProcedureSequence<ShardingKey>, ShardingKey>, ShardingKey>
extends AbstractProcedureImpl.BuilderImpl<BuilderT, ProcedureSequence<ShardingKey>, ShardingKey>
implements Builder<BuilderT, ProcedureSequence<ShardingKey>, ShardingKey> {
final List<Procedure.Builder<?, ?, ShardingKey>> stepBuilders = new ArrayList<>();
@Override
public ProcedureSequence<ShardingKey, MetricsT, ProcessT> build() throws Exception {
public ProcedureSequence<ShardingKey> build() throws Exception {
return new ProcedureSequence<>(this);
}
@Override
public BuilderT then(
com.sap.sse.landscape.orchestration.Procedure.Builder<?, ?, ShardingKey, MetricsT, ProcessT> stepBuilder) {
com.sap.sse.landscape.orchestration.Procedure.Builder<?, ?, ShardingKey> stepBuilder) {
stepBuilders.add(stepBuilder);
return self();
}
protected Iterable<Procedure.Builder<?, ?, ShardingKey, MetricsT, ProcessT>> getStepBuilders() {
protected Iterable<Procedure.Builder<?, ?, ShardingKey>> getStepBuilders() {
return stepBuilders;
}
}
private final Iterable<Procedure<ShardingKey, MetricsT, ProcessT>> steps;
private final Iterable<Procedure<ShardingKey>> steps;
public static <ShardingKey,
MetricsT extends ApplicationProcessMetrics,
ProcessT extends ApplicationProcess<ShardingKey, MetricsT, ProcessT>,
BuilderT extends Builder<BuilderT, ProcedureSequence<ShardingKey, MetricsT, ProcessT>, ShardingKey, MetricsT, ProcessT>>
Builder<BuilderT, ProcedureSequence<ShardingKey, MetricsT, ProcessT>, ShardingKey, MetricsT, ProcessT> builder() {
return new BuilderImpl<BuilderT, ShardingKey, MetricsT, ProcessT>();
BuilderT extends Builder<BuilderT, ProcedureSequence<ShardingKey>, ShardingKey>>
Builder<BuilderT, ProcedureSequence<ShardingKey>, ShardingKey> builder() {
return new BuilderImpl<BuilderT, ShardingKey>();
}
protected ProcedureSequence(BuilderImpl<?, ShardingKey, MetricsT, ProcessT> builder) throws Exception {
protected ProcedureSequence(BuilderImpl<?, ShardingKey> builder) throws Exception {
super(builder);
final List<Procedure<ShardingKey, MetricsT, ProcessT>> mySteps = new ArrayList<>();
for (final com.sap.sse.landscape.orchestration.Procedure.Builder<?, ?, ShardingKey, MetricsT, ProcessT> stepBuilder : builder.getStepBuilders()) {
final List<Procedure<ShardingKey>> mySteps = new ArrayList<>();
for (final com.sap.sse.landscape.orchestration.Procedure.Builder<?, ?, ShardingKey> stepBuilder : builder.getStepBuilders()) {
mySteps.add(stepBuilder.build());
}
this.steps = Collections.unmodifiableList(mySteps);
@@ -80,13 +73,13 @@ implements Procedure<ShardingKey, MetricsT, ProcessT>, Iterable<Procedure<Shardi
@Override
public void run() throws Exception {
for (final Procedure<ShardingKey, MetricsT, ProcessT> s : this) {
for (final Procedure<ShardingKey> s : this) {
s.run();
}
}
@Override
public Iterator<Procedure<ShardingKey, MetricsT, ProcessT>> iterator() {
public Iterator<Procedure<ShardingKey>> iterator() {
return steps.iterator();
}
}