mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-15 06:49:56 +00:00
bug4811: added mongo server startup procedure with fist tests; still a way to go
This commit is contained in:
1 parent
d561ee276c
commit
8a150634ed
17 files changed
+735
-236
No files matched your search
@@ -1,21 +1,20 @@
|
||||
#!/bin/bash
|
||||
REPLICA_SET_NAME=$(ec2-metadata | grep REPLICA_SET_NAME | sed -e 's/^user-data: //' | sed -e 's/^REPLICA_SET_NAME=//')
|
||||
eval $( ec2-metadata -d | sed -e 's/^user-data: //' )
|
||||
if [ -z "$REPLICA_SET_NAME" ]; then
|
||||
REPLICA_SET_NAME=live
|
||||
fi
|
||||
REPLICA_SET_PRIMARY=$(ec2-metadata | grep REPLICA_SET_PRIMARY | sed -e 's/^user-data: //' | sed -e 's/^REPLICA_SET_PRIMARY=//')
|
||||
if [ -z "$REPLICA_SET_PRIMARY" ]; then
|
||||
REPLICA_SET_PRIMARY=mongo0.internal.sapsailing.com:27017
|
||||
fi
|
||||
REPLICA_SET_PRIORITY=$(ec2-metadata | grep REPLICA_SET_PRIORITY | sed -e 's/^user-data: //' | sed -e 's/^REPLICA_SET_PRIORITY=//')
|
||||
if [ -z "$REPLICA_SET_PRIORITY" ]; then
|
||||
REPLICA_SET_PRIORITY=1
|
||||
fi
|
||||
REPLICA_SET_VOTES=$(ec2-metadata | grep REPLICA_SET_VOTES | sed -e 's/^user-data: //' | sed -e 's/^REPLICA_SET_VOTES=//')
|
||||
if [ -z "$REPLICA_SET_VOTES" ]; then
|
||||
REPLICA_SET_VOTES=0
|
||||
fi
|
||||
if [ \! -z "REPLICA_SET_PRIMARY" ]; then
|
||||
IP=$(ec2-metadata -o | sed -e 's/^local-ipv4: //')
|
||||
echo "rs.add({host: \"$IP:27017\", priority: $REPLICA_SET_PRIORITY, votes: $REPLICA_SET_VOTES})" | mongo "mongodb://$REPLICA_SET_PRIMARY/?replicaSet=$REPLICA_SET_NAME&retryWrites=true"
|
||||
else
|
||||
echo "rs.initiate()" | mongo
|
||||
fi
|
||||
@@ -11,4 +11,4 @@ Type=oneshot
|
||||
RemainAfterExit=true
|
||||
ExecStart=/usr/local/bin/add-as-replica
|
||||
ExecStop=/usr/local/bin/remove-as-replica
|
||||
TimeoutStopSpec=120s
|
||||
TimeoutStopSec=120s
|
||||
+29
@@ -39,6 +39,8 @@ import com.sap.sse.landscape.aws.orchestration.CreateDynamicLoadBalancerMapping;
|
||||
import com.sap.sse.landscape.aws.orchestration.StartMongoDBServer;
|
||||
import com.sap.sse.landscape.aws.orchestration.StartMongoDBServer.Builder;
|
||||
import com.sap.sse.landscape.mongodb.MongoEndpoint;
|
||||
import com.sap.sse.landscape.mongodb.MongoProcess;
|
||||
import com.sap.sse.landscape.mongodb.MongoProcessInReplicaSet;
|
||||
|
||||
import software.amazon.awssdk.regions.Region;
|
||||
import software.amazon.awssdk.services.ec2.model.Instance;
|
||||
@@ -70,6 +72,33 @@ public class TestProcedures {
|
||||
securityServiceReplicationBearerToken = System.getProperty(SECURITY_SERVICE_REPLICATION_BEARER_TOKEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddMongoReplica() throws Exception {
|
||||
final String keyName = "MyKey-"+UUID.randomUUID();
|
||||
landscape.createKeyPair(region, keyName);
|
||||
final StartMongoDBServer.Builder<String, SailingAnalyticsMetrics, SailingAnalyticsMaster<String>, SailingAnalyticsReplica<String>> builder = StartMongoDBServer.builder();
|
||||
final StartMongoDBServer<String, SailingAnalyticsMetrics, SailingAnalyticsMaster<String>, SailingAnalyticsReplica<String>> startMongoDBServerProcedure = builder
|
||||
.setLandscape(landscape)
|
||||
.setKeyName(keyName)
|
||||
.setOptionalTimeout(optionalTimeout)
|
||||
.build();
|
||||
try {
|
||||
// this is expected to have connected to the default "live" replica set.
|
||||
startMongoDBServerProcedure.run();
|
||||
final MongoProcess result = startMongoDBServerProcedure.getMongoProcess();
|
||||
assertTrue(result.isInReplicaSet());
|
||||
final MongoProcessInReplicaSet inRs = result.asMongoProcessInReplicaSet();
|
||||
assertEquals(AwsLandscape.MONGO_DEFAULT_REPLICA_SET_NAME, inRs.getReplicaSet().getName());
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Exception while trying to create a MongoDB replica", e);
|
||||
} finally {
|
||||
if (startMongoDBServerProcedure.getHost() != null) {
|
||||
startMongoDBServerProcedure.getHost().terminate();
|
||||
}
|
||||
landscape.deleteKeyPair(region, keyName);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImageUpgrade() throws Exception {
|
||||
final String keyName = "MyKey-"+UUID.randomUUID();
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ import software.amazon.awssdk.services.ec2.model.InstanceType;
|
||||
* after successfully launching, that directory will be removed. A {@link DeployProcessOnMultiServer} procedure needs to
|
||||
* be run with the {@link #getHost()} of this procedure telling the host on which to deploy the process.<p>
|
||||
*
|
||||
* The implementation specializes the {@link UpgradeAmi} procedure in {@link Builder#setNoShutdown(boolean) no-shutdown} mode.
|
||||
* The implementation specializes the {@link StartEmptyServer} procedure in {@link Builder#setNoShutdown(boolean) no-shutdown} mode.
|
||||
* After running that part, the {@code httpd} service is launched.<p>
|
||||
*
|
||||
* You want to at least specify an {@link Builder#setInstanceName(String) instance name} and {@link Builder#setInstanceType(InstanceType)}.
|
||||
|
||||
+4
-3
@@ -14,6 +14,7 @@ import com.sap.sse.landscape.ProcessConfigurationVariable;
|
||||
import com.sap.sse.landscape.Release;
|
||||
import com.sap.sse.landscape.aws.AmazonMachineImage;
|
||||
import com.sap.sse.landscape.aws.HostSupplier;
|
||||
import com.sap.sse.landscape.aws.orchestration.StartAwsApplicationHost;
|
||||
import com.sap.sse.landscape.aws.orchestration.StartAwsHost;
|
||||
import com.sap.sse.landscape.orchestration.Procedure;
|
||||
|
||||
@@ -28,7 +29,7 @@ import com.sap.sse.landscape.orchestration.Procedure;
|
||||
* @param <ShardingKey>
|
||||
*/
|
||||
public abstract class StartSailingAnalyticsHost<ShardingKey, ProcessT extends SailingAnalyticsProcess<ShardingKey>>
|
||||
extends StartAwsHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsMaster<ShardingKey>, SailingAnalyticsReplica<ShardingKey>, SailingAnalyticsHost<ShardingKey>>
|
||||
extends StartAwsApplicationHost<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsMaster<ShardingKey>, SailingAnalyticsReplica<ShardingKey>, SailingAnalyticsHost<ShardingKey>>
|
||||
implements Procedure<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsMaster<ShardingKey>, SailingAnalyticsReplica<ShardingKey>>,
|
||||
StartFromSailingAnalyticsImage {
|
||||
private final static String INSTANCE_NAME_DEFAULT_PREFIX = "SL ";
|
||||
@@ -55,7 +56,7 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsMaste
|
||||
* @author Axel Uhl (D043530)
|
||||
*/
|
||||
public static interface Builder<T extends StartSailingAnalyticsHost<ShardingKey, ProcessT>, ShardingKey, ProcessT extends SailingAnalyticsProcess<ShardingKey>>
|
||||
extends StartAwsHost.Builder<T, ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsMaster<ShardingKey>, SailingAnalyticsReplica<ShardingKey>, SailingAnalyticsHost<ShardingKey>> {
|
||||
extends StartAwsApplicationHost.Builder<T, ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsMaster<ShardingKey>, SailingAnalyticsReplica<ShardingKey>, SailingAnalyticsHost<ShardingKey>> {
|
||||
Builder<T, ShardingKey, ProcessT> setPort(int port);
|
||||
|
||||
Builder<T, ShardingKey, ProcessT> setTelnetPort(int telnetPort);
|
||||
@@ -66,7 +67,7 @@ implements Procedure<ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsMaste
|
||||
}
|
||||
|
||||
protected abstract static class BuilderImpl<T extends StartSailingAnalyticsHost<ShardingKey, ProcessT>, ShardingKey, ProcessT extends SailingAnalyticsProcess<ShardingKey>>
|
||||
extends StartAwsHost.BuilderImpl<T, ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsMaster<ShardingKey>, SailingAnalyticsReplica<ShardingKey>, SailingAnalyticsHost<ShardingKey>>
|
||||
extends StartAwsApplicationHost.BuilderImpl<T, ShardingKey, SailingAnalyticsMetrics, SailingAnalyticsMaster<ShardingKey>, SailingAnalyticsReplica<ShardingKey>, SailingAnalyticsHost<ShardingKey>>
|
||||
implements Builder<T, ShardingKey, ProcessT> {
|
||||
private Integer port;
|
||||
private Integer telnetPort;
|
||||
|
||||
@@ -31,40 +31,69 @@
|
||||
<stringAttribute key="profilingTraceType-PERFORMANCE_HOTSPOT_TRACE" value="KEY_IGNORE_SLEEPING_THREADS%CTX_KEY%true%CTX_ENTRY%KEY_APPLICATION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_SESSION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ENABLEMENT%CTX_KEY%false%CTX_ENTRY%KEY_USER_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_REQUEST_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_TENANT_FILTER%CTX_KEY%*%CTX_ENTRY%"/>
|
||||
<stringAttribute key="profilingTraceType-SYNCHRONIZATION_TRACE" value="KEY_APPLICATION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_SESSION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ENABLEMENT%CTX_KEY%false%CTX_ENTRY%KEY_USER_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_REQUEST_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_TENANT_FILTER%CTX_KEY%*%CTX_ENTRY%"/>
|
||||
<setAttribute key="selected_target_bundles">
|
||||
<setEntry value="routeconverter@default:default"/>
|
||||
<setEntry value="org.apache.commons.codec@default:default"/>
|
||||
<setEntry value="org.apache.poi@default:default"/>
|
||||
<setEntry value="org.apache.poi.ooxml@default:default"/>
|
||||
<setEntry value="org.apache.poi.ooxml.schemas@default:default"/>
|
||||
<setEntry value="org.dom4j@default:default"/>
|
||||
<setEntry value="org.apache.xmlbeans@default:default"/>
|
||||
<setEntry value="org.apache.commons.math@default:default"/>
|
||||
<setEntry value="org.apache.httpcomponents.httpclient@default:default"/>
|
||||
<setEntry value="org.apache.httpcomponents.httpcore@default:default"/>
|
||||
<setEntry value="org.objectweb.asm@default:default"/>
|
||||
<setEntry value="org.hyperic.sigar@default:default"/>
|
||||
<setEntry value="com.amazon.aws.aws-java-api@default:default"/>
|
||||
<setEntry value="com.jcraft.jsch@default:default"/>
|
||||
<setEntry value="com.rabbitmq.client@default:default"/>
|
||||
<setEntry value="com.sun.activation.javax.activation@default:default"/>
|
||||
<setEntry value="com.sun.istack.commons-runtime@default:default"/>
|
||||
<setEntry value="com.sun.jersey.contribs.jersey-multipart@default:default"/>
|
||||
<setEntry value="javax.validation@default:default"/>
|
||||
<setEntry value="org.apache.commons.fileupload@default:default"/>
|
||||
<setEntry value="org.jdom@default:default"/>
|
||||
<setEntry value="org.jvnet.mimepull@default:default"/>
|
||||
<setEntry value="org.apache.commons.math3@default:default"/>
|
||||
<setEntry value="org.mongodb.mongo-java-driver@default:default"/>
|
||||
<setEntry value="org.mongodb.mongo-java-driver.source@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.osgi.boot@3:true"/>
|
||||
<setEntry value="org.eclipse.jetty.osgi.boot.warurl@default:default"/>
|
||||
<setEntry value="slf4j.jdk14@default:default"/>
|
||||
<setEntry value="org.apache.felix.shell@0:true"/>
|
||||
<setEntry value="org.apache.felix.shell.remote@0:true"/>
|
||||
<setEntry value="lz4-java@default:default"/>
|
||||
<setEntry value="com.sun.jersey@default:default"/>
|
||||
<setEntry value="com.sun.mail.javax.mail@default:default"/>
|
||||
<setEntry value="com.sun.xml.bind.jaxb-impl@default:default"/>
|
||||
<setEntry value="jackson-core-asl@default:default"/>
|
||||
<setEntry value="jackson-jaxrs@default:default"/>
|
||||
<setEntry value="jackson-mapper-asl@default:default"/>
|
||||
<setEntry value="javax.servlet@default:default"/>
|
||||
<setEntry value="javax.validation@default:default"/>
|
||||
<setEntry value="javax.ws.rs@default:default"/>
|
||||
<setEntry value="javax.xml.stream@default:default"/>
|
||||
<setEntry value="javax.xml.ws@default:default"/>
|
||||
<setEntry value="javax.xml@default:default"/>
|
||||
<setEntry value="jaxb-api@default:default"/>
|
||||
<setEntry value="jcl.over.slf4j@default:default"/>
|
||||
<setEntry value="lz4-java@default:default"/>
|
||||
<setEntry value="org.apache.commons.beanutils@default:default"/>
|
||||
<setEntry value="org.apache.commons.codec@default:default"/>
|
||||
<setEntry value="org.apache.commons.collections@default:default"/>
|
||||
<setEntry value="org.apache.commons.fileupload@default:default"/>
|
||||
<setEntry value="org.apache.commons.io@default:default"/>
|
||||
<setEntry value="org.apache.commons.lang@default:default"/>
|
||||
<setEntry value="org.apache.commons.logging@default:default"/>
|
||||
<setEntry value="org.apache.commons.math3@default:default"/>
|
||||
<setEntry value="org.apache.commons.math@default:default"/>
|
||||
<setEntry value="org.apache.felix.gogo.command@default:default"/>
|
||||
<setEntry value="org.apache.felix.gogo.runtime@default:default"/>
|
||||
<setEntry value="org.apache.felix.gogo.shell@default:default"/>
|
||||
<setEntry value="org.apache.felix.shell.remote@0:true"/>
|
||||
<setEntry value="org.apache.felix.shell@0:true"/>
|
||||
<setEntry value="org.apache.httpcomponents.httpclient@default:default"/>
|
||||
<setEntry value="org.apache.httpcomponents.httpcore@default:default"/>
|
||||
<setEntry value="org.apache.poi.ooxml.schemas@default:default"/>
|
||||
<setEntry value="org.apache.poi.ooxml@default:default"/>
|
||||
<setEntry value="org.apache.poi@default:default"/>
|
||||
<setEntry value="org.apache.servicemix.bundles.ehcache@default:default"/>
|
||||
<setEntry value="org.apache.servicemix.bundles.scribe@default:default"/>
|
||||
<setEntry value="org.apache.servicemix.bundles.zxing@default:default"/>
|
||||
<setEntry value="org.apache.shiro.core.source"/>
|
||||
<setEntry value="org.apache.shiro.core@default:default"/>
|
||||
<setEntry value="org.apache.shiro.ehcache.source"/>
|
||||
<setEntry value="org.apache.shiro.ehcache@default:default"/>
|
||||
<setEntry value="org.apache.shiro.web.source"/>
|
||||
<setEntry value="org.apache.shiro.web@default:default"/>
|
||||
<setEntry value="org.apache.xmlbeans@default:default"/>
|
||||
<setEntry value="org.dom4j@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.cm@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.common@2:true"/>
|
||||
<setEntry value="org.eclipse.equinox.console@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.launcher@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.simpleconfigurator@2:true"/>
|
||||
<setEntry value="org.eclipse.jetty.client@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.deploy@4:true"/>
|
||||
<setEntry value="org.eclipse.jetty.http@4:true"/>
|
||||
<setEntry value="org.eclipse.jetty.io@4:true"/>
|
||||
<setEntry value="org.eclipse.jetty.jmx@4:true"/>
|
||||
<setEntry value="org.eclipse.jetty.osgi.boot.warurl@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.osgi.boot@3:true"/>
|
||||
<setEntry value="org.eclipse.jetty.security@4:true"/>
|
||||
<setEntry value="org.eclipse.jetty.server@4:true"/>
|
||||
<setEntry value="org.eclipse.jetty.servlet@4:true"/>
|
||||
@@ -74,152 +103,119 @@
|
||||
<setEntry value="org.eclipse.jetty.websocket.client@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.websocket.common@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.xml@4:true"/>
|
||||
<setEntry value="slf4j.api@default:default"/>
|
||||
<setEntry value="org.apache.servicemix.bundles.zxing@default:default"/>
|
||||
<setEntry value="org.apache.commons.io@default:default"/>
|
||||
<setEntry value="jcl.over.slf4j@default:default"/>
|
||||
<setEntry value="com.sun.mail.javax.mail@default:default"/>
|
||||
<setEntry value="com.rabbitmq.client@default:default"/>
|
||||
<setEntry value="org.apache.commons.lang@default:default"/>
|
||||
<setEntry value="org.apache.commons.logging@default:default"/>
|
||||
<setEntry value="jackson-jaxrs@default:default"/>
|
||||
<setEntry value="com.sun.jersey@default:default"/>
|
||||
<setEntry value="javax.ws.rs@default:default"/>
|
||||
<setEntry value="org.apache.commons.beanutils@default:default"/>
|
||||
<setEntry value="org.apache.servicemix.bundles.ehcache@default:default"/>
|
||||
<setEntry value="org.apache.servicemix.bundles.scribe@default:default"/>
|
||||
<setEntry value="org.apache.shiro.core@default:default"/>
|
||||
<setEntry value="org.apache.shiro.core.source@default:default"/>
|
||||
<setEntry value="org.apache.shiro.ehcache@default:default"/>
|
||||
<setEntry value="org.apache.shiro.ehcache.source@default:default"/>
|
||||
<setEntry value="org.apache.shiro.web@default:default"/>
|
||||
<setEntry value="org.apache.shiro.web.source@default:default"/>
|
||||
<setEntry value="jackson-core-asl@default:default"/>
|
||||
<setEntry value="jackson-mapper-asl@default:default"/>
|
||||
<setEntry value="org.apache.commons.collections@default:default"/>
|
||||
<setEntry value="org.eclipse.jetty.client@default:default"/>
|
||||
<setEntry value="javax.xml@default:default"/>
|
||||
<setEntry value="com.sun.activation.javax.activation@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.common@2:true"/>
|
||||
<setEntry value="org.eclipse.equinox.console@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.launcher@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.simpleconfigurator@2:true"/>
|
||||
<setEntry value="org.eclipse.osgi@-1:true"/>
|
||||
<setEntry value="org.eclipse.osgi.services@default:default"/>
|
||||
<setEntry value="org.eclipse.equinox.cm@default:default"/>
|
||||
<setEntry value="com.sun.istack.commons-runtime@default:default"/>
|
||||
<setEntry value="jaxb-api@default:default"/>
|
||||
<setEntry value="com.sun.xml.bind.jaxb-impl@default:default"/>
|
||||
<setEntry value="javax.xml.stream@default:default"/>
|
||||
<setEntry value="javax.xml.ws@default:default"/>
|
||||
<setEntry value="org.eclipse.osgi.util@default:default"/>
|
||||
<setEntry value="com.jcraft.jsch@default:default"/>
|
||||
<setEntry value="com.amazon.aws.aws-java-api@default:default"/>
|
||||
<setEntry value="org.eclipse.osgi@-1:true"/>
|
||||
<setEntry value="org.hyperic.sigar@default:default"/>
|
||||
<setEntry value="org.jdom@default:default"/>
|
||||
<setEntry value="org.jvnet.mimepull@default:default"/>
|
||||
<setEntry value="org.mongodb.mongo-java-driver.source"/>
|
||||
<setEntry value="org.mongodb.mongo-java-driver@default:default"/>
|
||||
<setEntry value="org.objectweb.asm@default:default"/>
|
||||
<setEntry value="routeconverter@default:default"/>
|
||||
<setEntry value="slf4j.api@default:default"/>
|
||||
<setEntry value="slf4j.jdk14@default:false"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
<setEntry value="com.sap.sailing.domain.common@default:default"/>
|
||||
<setEntry value="com.sap.sailing.domain@default:default"/>
|
||||
<setEntry value="com.sap.sailing.news@4:true"/>
|
||||
<setEntry value="com.sap.sailing.domain.tractracadapter@5:true"/>
|
||||
<setEntry value="com.sap.sailing.expeditionconnector@default:default"/>
|
||||
<setEntry value="com.sap.sailing.domain.windfinderadapter@4:true"/>
|
||||
<setEntry value="com.sap.sailing.server@5:true"/>
|
||||
<setEntry value="com.sap.sailing.server.gateway@5:true"/>
|
||||
<setEntry value="com.tractrac.clientmodule@default:default"/>
|
||||
<setEntry value="com.google.gwt.servlet@default:default"/>
|
||||
<setEntry value="com.googlecode.java-diff-utils@default:default"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.competitorimport@default:default"/>
|
||||
<setEntry value="com.sap.sailing.dashboards.gwt@6:true"/>
|
||||
<setEntry value="com.sap.sailing.datamining.provider@default:default"/>
|
||||
<setEntry value="com.sap.sailing.datamining.shared@default:default"/>
|
||||
<setEntry value="com.sap.sailing.datamining@5:true"/>
|
||||
<setEntry value="com.sap.sailing.declination@default:default"/>
|
||||
<setEntry value="com.sap.sailing.domain.bravoadapter@5:true"/>
|
||||
<setEntry value="com.sap.sailing.domain.common@default:default"/>
|
||||
<setEntry value="com.sap.sailing.domain.deckmanadapter@5:true"/>
|
||||
<setEntry value="com.sap.sailing.domain.expeditionadapter@5:true"/>
|
||||
<setEntry value="com.sap.sailing.domain.igtimiadapter.gateway@5:true"/>
|
||||
<setEntry value="com.sap.sailing.domain.igtimiadapter.persistence@default:default"/>
|
||||
<setEntry value="com.sap.sailing.domain.igtimiadapter@4:true"/>
|
||||
<setEntry value="com.sap.sailing.domain.persistence@default:default"/>
|
||||
<setEntry value="com.sap.sailing.domain.swisstimingadapter@5:true"/>
|
||||
<setEntry value="com.sap.sailing.domain.racelogtrackingadapter@4:true"/>
|
||||
<setEntry value="com.sap.sailing.domain.shared.android@default:default"/>
|
||||
<setEntry value="com.sap.sailing.domain.swisstimingadapter.persistence@4:true"/>
|
||||
<setEntry value="com.sap.sailing.domain.swisstimingadapter@5:true"/>
|
||||
<setEntry value="com.sap.sailing.domain.swisstimingreplayadapter@4:true"/>
|
||||
<setEntry value="com.sap.sailing.domain.tractracadapter.persistence@4:true"/>
|
||||
<setEntry value="com.sap.sailing.gwt.ui@6:true"/>
|
||||
<setEntry value="com.sap.sailing.udpconnector@default:default"/>
|
||||
<setEntry value="com.sap.sailing.xmlexport@5:true"/>
|
||||
<setEntry value="com.sap.sailing.simulator@default:default"/>
|
||||
<setEntry value="com.sap.sailing.www@5:true"/>
|
||||
<setEntry value="com.sap.sailing.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.kiworesultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.domain.tractracadapter@5:true"/>
|
||||
<setEntry value="com.sap.sailing.domain.windfinderadapter@4:true"/>
|
||||
<setEntry value="com.sap.sailing.domain@default:default"/>
|
||||
<setEntry value="com.sap.sailing.ess40.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.expeditionconnector.common@default:default"/>
|
||||
<setEntry value="com.sap.sailing.expeditionconnector.persistence@4:true"/>
|
||||
<setEntry value="com.sap.sailing.expeditionconnector@default:default"/>
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
<setEntry value="com.sap.sailing.grib@default:default"/>
|
||||
<setEntry value="com.sap.sailing.gwt.ui@6:true"/>
|
||||
<setEntry value="com.sap.sailing.kiworesultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.velum.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail@default:default"/>
|
||||
<setEntry value="com.sap.sailing.monitoring@7:true"/>
|
||||
<setEntry value="com.sap.sailing.xrr.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.domain.igtimiadapter@4:true"/>
|
||||
<setEntry value="com.sap.sailing.domain.igtimiadapter.persistence@default:default"/>
|
||||
<setEntry value="com.sap.sailing.domain.racelogtrackingadapter@4:true"/>
|
||||
<setEntry value="com.sap.sailing.domain.deckmanadapter@5:true"/>
|
||||
<setEntry value="com.sap.sailing.xrr.structureimport@default:default"/>
|
||||
<setEntry value="com.sap.sailing.news@4:true"/>
|
||||
<setEntry value="com.sap.sailing.nmeaconnector@default:default"/>
|
||||
<setEntry value="com.sap.sailing.polars.datamining.shared@default:default"/>
|
||||
<setEntry value="com.sap.sailing.polars.datamining@5:true"/>
|
||||
<setEntry value="com.sap.sailing.polars@5:true"/>
|
||||
<setEntry value="com.sap.sailing.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.routeconverterjava11extension@default:false"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.server.gateway.serialization.shared.android@default:default"/>
|
||||
<setEntry value="com.sap.sailing.server.gateway.serialization@default:default"/>
|
||||
<setEntry value="com.sap.sailing.dashboards.gwt@6:true"/>
|
||||
<setEntry value="com.sap.sailing.dashboards.gwt@6:true"/>
|
||||
<setEntry value="com.sap.sailing.datamining@5:true"/>
|
||||
<setEntry value="com.sap.sailing.datamining.shared@default:default"/>
|
||||
<setEntry value="com.sap.sailing.polars@5:true"/>
|
||||
<setEntry value="com.sap.sailing.windestimation@5:true"/>
|
||||
<setEntry value="com.sap.sailing.polars.datamining@5:true"/>
|
||||
<setEntry value="com.sap.sailing.domain.shared.android@default:default"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail@default:default"/>
|
||||
<setEntry value="com.sap.sailing.polars.datamining.shared@default:default"/>
|
||||
<setEntry value="com.sap.sailing.xrr.schema@default:default"/>
|
||||
<setEntry value="com.sap.sailing.server.trackfiles@default:default"/>
|
||||
<setEntry value="com.sap.sailing.competitorimport@default:default"/>
|
||||
<setEntry value="com.sap.sailing.datamining.provider@default:default"/>
|
||||
<setEntry value="com.sap.sailing.grib@default:default"/>
|
||||
<setEntry value="com.sap.sailing.nmeaconnector@default:default"/>
|
||||
<setEntry value="com.sap.sailing.domain.expeditionadapter@5:true"/>
|
||||
<setEntry value="com.sap.sailing.expeditionconnector.persistence@4:true"/>
|
||||
<setEntry value="com.sap.sailing.expeditionconnector.common@default:default"/>
|
||||
<setEntry value="com.sap.sailing.domain.bravoadapter@5:true"/>
|
||||
<setEntry value="net.sf.marineapi@default:default"/>
|
||||
<setEntry value="com.sap.sailing.routeconverterjava11extension@default:default"/>
|
||||
<setEntry value="com.sap.sailing.server.gateway@5:true"/>
|
||||
<setEntry value="com.sap.sailing.server.interface@default:default"/>
|
||||
<setEntry value="com.sap.sse.datamining.ui@default:default"/>
|
||||
<setEntry value="com.sap.sailing.domain.igtimiadapter.gateway@5:true"/>
|
||||
<setEntry value="com.sap.sailing.shared.server@5:true"/>
|
||||
<setEntry value="com.sap.sailing.shared.server.gateway@5:true"/>
|
||||
<setEntry value="com.sap.sailing.server.trackfiles@default:default"/>
|
||||
<setEntry value="com.sap.sailing.server@5:true"/>
|
||||
<setEntry value="com.sap.sailing.shared.persistence@default:default"/>
|
||||
<setEntry value="com.sap.sse.debranding@default:default"/>
|
||||
<setEntry value="com.tractrac.clientmodule@default:default"/>
|
||||
<setEntry value="com.sap.sse.gwt@default:default"/>
|
||||
<setEntry value="com.google.gwt.servlet@default:default"/>
|
||||
<setEntry value="com.sap.sse.security@default:default"/>
|
||||
<setEntry value="com.sap.sse.security.ui@6:true"/>
|
||||
<setEntry value="com.sap.sse.security.userstore.mongodb@4:true"/>
|
||||
<setEntry value="com.sap.sse@default:default"/>
|
||||
<setEntry value="com.sap.sailing.shared.server.gateway@5:true"/>
|
||||
<setEntry value="com.sap.sailing.shared.server@5:true"/>
|
||||
<setEntry value="com.sap.sailing.simulator@default:default"/>
|
||||
<setEntry value="com.sap.sailing.udpconnector@default:default"/>
|
||||
<setEntry value="com.sap.sailing.velum.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.windestimation@5:true"/>
|
||||
<setEntry value="com.sap.sailing.www@5:true"/>
|
||||
<setEntry value="com.sap.sailing.xmlexport@5:true"/>
|
||||
<setEntry value="com.sap.sailing.xrr.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.xrr.schema@default:default"/>
|
||||
<setEntry value="com.sap.sailing.xrr.structureimport@default:default"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sse.common@default:default"/>
|
||||
<setEntry value="com.sap.sse.datamining@default:default"/>
|
||||
<setEntry value="com.sap.sse.datamining.annotations@default:default"/>
|
||||
<setEntry value="com.sap.sse.datamining.shared@default:default"/>
|
||||
<setEntry value="com.sap.sse.datamining.ui@default:default"/>
|
||||
<setEntry value="com.sap.sse.datamining@default:default"/>
|
||||
<setEntry value="com.sap.sse.debranding@default:default"/>
|
||||
<setEntry value="com.sap.sse.filestorage@4:true"/>
|
||||
<setEntry value="com.sap.sse.gwt.adminconsole@default:default"/>
|
||||
<setEntry value="com.sap.sse.gwt@default:default"/>
|
||||
<setEntry value="com.sap.sse.jersey.jaxbdependencyfragment@default:false"/>
|
||||
<setEntry value="com.sap.sse.jettyextensions@default:false"/>
|
||||
<setEntry value="com.sap.sse.landscape.aws.persistence@default:default"/>
|
||||
<setEntry value="com.sap.sse.landscape.aws@default:default"/>
|
||||
<setEntry value="com.sap.sse.landscape@default:default"/>
|
||||
<setEntry value="com.sap.sse.mail@5:true"/>
|
||||
<setEntry value="com.sap.sse.mongodb@default:default"/>
|
||||
<setEntry value="com.sap.sse.operationaltransformation@default:default"/>
|
||||
<setEntry value="com.sap.sse.replication@6:true"/>
|
||||
<setEntry value="com.sap.sse.filestorage@4:true"/>
|
||||
<setEntry value="com.sap.sse.shared.android@default:default"/>
|
||||
<setEntry value="com.sap.sse.mail@5:true"/>
|
||||
<setEntry value="com.sap.sse.threadmanager@default:default"/>
|
||||
<setEntry value="com.sap.sse.security.common@default:default"/>
|
||||
<setEntry value="org.json.simple@default:default"/>
|
||||
<setEntry value="com.sap.sse.jersey.jaxbdependencyfragment@default:default"/>
|
||||
<setEntry value="org.moxieapps.gwt.highcharts@default:default"/>
|
||||
<setEntry value="com.googlecode.java-diff-utils@default:default"/>
|
||||
<setEntry value="org.mp4parser.isoparser@default:default"/>
|
||||
<setEntry value="com.sap.sse.replication.interfaces@default:default"/>
|
||||
<setEntry value="com.sap.sse.security.persistence@default:default"/>
|
||||
<setEntry value="com.sap.sse.security.interface@default:default"/>
|
||||
<setEntry value="com.sap.sse.jettyextensions@default:default"/>
|
||||
<setEntry value="com.sap.sse.replication.persistence@default:default"/>
|
||||
<setEntry value="com.sap.sse.landscape@default:default"/>
|
||||
<setEntry value="com.sap.sse.landscape.aws@default:default"/>
|
||||
<setEntry value="com.sap.sse.landscape.aws.persistence@default:default"/>
|
||||
<setEntry value="com.sap.sailing.server.gateway.test.support:default"/>
|
||||
|
||||
<setEntry value="com.sap.sse.replication@6:true"/>
|
||||
<setEntry value="com.sap.sse.security.common@default:default"/>
|
||||
<setEntry value="com.sap.sse.security.interface@default:default"/>
|
||||
<setEntry value="com.sap.sse.security.persistence@default:default"/>
|
||||
<setEntry value="com.sap.sse.security.ui@6:true"/>
|
||||
<setEntry value="com.sap.sse.security.userstore.mongodb@4:true"/>
|
||||
<setEntry value="com.sap.sse.security@default:default"/>
|
||||
<setEntry value="com.sap.sse.shared.android@default:default"/>
|
||||
<setEntry value="com.sap.sse.threadmanager@default:default"/>
|
||||
<setEntry value="com.sap.sse@default:default"/>
|
||||
<setEntry value="com.tractrac.clientmodule@default:default"/>
|
||||
<setEntry value="net.sf.marineapi@default:default"/>
|
||||
<setEntry value="org.json.simple@default:default"/>
|
||||
<setEntry value="org.moxieapps.gwt.highcharts@default:default"/>
|
||||
<setEntry value="org.mp4parser.isoparser@default:default"/>
|
||||
</setAttribute>
|
||||
<booleanAttribute key="show_selected_only" value="false"/>
|
||||
<booleanAttribute key="tracing" value="false"/>
|
||||
|
||||
@@ -21,6 +21,10 @@ import com.sap.sse.landscape.aws.impl.AwsRegion;
|
||||
import com.sap.sse.landscape.aws.impl.AwsTargetGroupImpl;
|
||||
import com.sap.sse.landscape.mongodb.Database;
|
||||
import com.sap.sse.landscape.mongodb.MongoEndpoint;
|
||||
import com.sap.sse.landscape.mongodb.MongoProcess;
|
||||
import com.sap.sse.landscape.mongodb.MongoProcessInReplicaSet;
|
||||
import com.sap.sse.landscape.mongodb.MongoReplicaSet;
|
||||
import com.sap.sse.landscape.mongodb.impl.MongoProcessImpl;
|
||||
import com.sap.sse.landscape.rabbitmq.RabbitMQEndpoint;
|
||||
import com.sap.sse.landscape.ssh.SSHKeyPair;
|
||||
|
||||
@@ -59,6 +63,30 @@ extends Landscape<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> {
|
||||
String SECRET_ACCESS_KEY_SYSTEM_PROPERTY_NAME = "com.sap.sse.landscape.aws.secretaccesskey";
|
||||
|
||||
String S3_BUCKET_FOR_ALB_LOGS_SYSTEM_PROPERTY_NAME = "com.sap.sse.landscape.aws.s3bucketforalblogs";
|
||||
|
||||
/**
|
||||
* The name of the tag used on {@link AwsInstance hosts} running one or more {@link MongoProcess}(es). The tag value
|
||||
* provides information about the replica sets and the ports on which the respective {@link MongoProcess} is listening.
|
||||
* If no port is explicitly specified, the default port {@link MongoProcess#DEFAULT_PORT 27017} is assumed. If the replica
|
||||
* set name is empty then the port or at least ":" must be specified and a standalone process is assumed. The
|
||||
* format for the tag value is as follows:<pre>
|
||||
* ({replica-set-name}(:{port})?)(,({replica-set-name}(:{port})?))*
|
||||
* </pre>
|
||||
* In other words, the tag value is expected to be a comma-separated list of replica set name and optional port specifications
|
||||
* where the optional port specification is appended to the replica set name separated by a colon (:).<p>
|
||||
*
|
||||
* Examples:<pre>
|
||||
* archive:10201,:10202,live:10203
|
||||
* :
|
||||
* </pre>
|
||||
* The first example means that three MongoDB processes are running on the host, one listening on port 10201 which is part of the
|
||||
* replica set "archive", one standalone instance listening on port 10202, and a member of the "live" replica set running
|
||||
* on port 10203. The second example (":") means that a single standalong MongoDB process is assumed to be running on the
|
||||
* default port (usually 27017).
|
||||
*/
|
||||
String MONGO_REPLICA_SETS_TAG_NAME = "mongo-replica-sets";
|
||||
|
||||
String MONGO_DEFAULT_REPLICA_SET_NAME = "live";
|
||||
|
||||
/**
|
||||
* Based on system properties for the AWS access key ID and the secret access key (see
|
||||
@@ -341,12 +369,39 @@ extends Landscape<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> {
|
||||
ApplicationLoadBalancer<ShardingKey, MetricsT> getDNSMappedLoadBalancerFor(Region region, String hostname);
|
||||
|
||||
/**
|
||||
* The default MongoDB configuration to connect to.
|
||||
* The default MongoDB configuration to connect to. See also {@link #MONGO_DEFAULT_REPLICA_SET_NAME} and
|
||||
* {@link #getDatabaseConfigurationForReplicaSet(Region, String)}, but expect that this could also be a
|
||||
* standalone MongoDB instance.
|
||||
*/
|
||||
MongoEndpoint getDatabaseConfigurationForDefaultReplicaSet(Region region);
|
||||
|
||||
MongoEndpoint getDatabaseConfigurationForReplicaSet(com.sap.sse.landscape.Region region, String mongoReplicaSetName);
|
||||
|
||||
/**
|
||||
* Computes the {@link Tags tag value} to add for the {@link #MONGO_REPLICA_SETS_TAG_NAME} tag to represent the
|
||||
* configuration of the {@code mongoProcess}. In line with
|
||||
* {@link #getDatabaseConfigurationForReplicaSet(Region, String)}, this will encode the replica set name, if any,
|
||||
* followed by a colon and the port number into the tag value.
|
||||
*
|
||||
* @param tagsToAddTo
|
||||
* must not be {@code null}; the {@link #MONGO_REPLICA_SETS_TAG_NAME} tag will be
|
||||
* {@link Tags#and(String, String) added}.
|
||||
* @return the {@code tagsToAddTo} object, for chaining
|
||||
*/
|
||||
Tags getTagForMongoProcess(Tags tagsToAddTo, String replicaSetName, int port);
|
||||
|
||||
/**
|
||||
* Searches the region for {@link AwsInstance hosts} that are tagged with the {@link #MONGO_REPLICA_SETS_TAG_NAME}
|
||||
* tag such that the {@code mongoReplicaSetName} is part of the host's specification. For each such host found, a
|
||||
* {@link MongoProcessInReplicaSet} is constructed and added to the {@link MongoReplicaSet} returned from which the
|
||||
* called may obtain the {@link MongoReplicaSet#getInstances() replicas} and from them, e.g., the
|
||||
* {@link MongoProcess#getPort() port} and the host name
|
||||
* ({@link MongoProcess#getHost()}.{@link AwsInstance#getPrivateAddress() getPrivateAddress()}).
|
||||
*
|
||||
* @param mongoReplicaSetName
|
||||
* must not be {@code null}. If you're looking for a standalone {@link MongoProcess}, simply use the
|
||||
* {@link MongoProcessImpl} constructor.
|
||||
*/
|
||||
MongoReplicaSet getDatabaseConfigurationForReplicaSet(com.sap.sse.landscape.Region region, String mongoReplicaSetName);
|
||||
|
||||
/**
|
||||
* Gets a default RabbitMQ configuration for the {@code region} specified.<p>
|
||||
*
|
||||
@@ -360,4 +415,10 @@ extends Landscape<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> {
|
||||
* The region to use as the default region for instance creation, DB connectivity, reverse proxy config, ...
|
||||
*/
|
||||
AwsRegion getDefaultRegion();
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
+42
-8
@@ -7,6 +7,8 @@ import java.io.PipedOutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.jcraft.jsch.Channel;
|
||||
@@ -33,6 +35,7 @@ import com.sap.sse.landscape.ssh.SshCommandChannelImpl;
|
||||
import com.sap.sse.landscape.ssh.YesUserInfo;
|
||||
|
||||
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> {
|
||||
private final static Logger logger = Logger.getLogger(AwsInstanceImpl.class.getName());
|
||||
@@ -68,22 +71,53 @@ public class AwsInstanceImpl<ShardingKey, MetricsT extends ApplicationProcessMet
|
||||
|
||||
@Override
|
||||
public InetAddress getPublicAddress() {
|
||||
return getIpAddress(Instance::publicIpAddress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetAddress getPrivateAddress(Optional<Duration> timeoutNullMeaningForever) {
|
||||
return getAddressWithTimeout(timeoutNullMeaningForever, this::getPrivateAddress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetAddress getPrivateAddress() {
|
||||
return getIpAddress(Instance::privateIpAddress);
|
||||
}
|
||||
|
||||
private InetAddress getIpAddress(Function<Instance, String> addressAsStringSupplier) {
|
||||
try {
|
||||
final String publicIpAddress = getInstance().publicIpAddress();
|
||||
return publicIpAddress==null?null:InetAddress.getByName(publicIpAddress);
|
||||
final Instance instance = getInstance();
|
||||
final InetAddress result;
|
||||
if (instance.state().name() == InstanceStateName.RUNNING) {
|
||||
final String privateIpAddress = addressAsStringSupplier.apply(instance);
|
||||
result = privateIpAddress==null?null:InetAddress.getByName(privateIpAddress);
|
||||
} else {
|
||||
result = null; // not RUNNING
|
||||
}
|
||||
return result;
|
||||
} catch (UnknownHostException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private InetAddress getAddressWithTimeout(Optional<Duration> timeoutNullMeaningForever, Supplier<InetAddress> addressSupplierMethod) {
|
||||
final Instance instance = getInstance();
|
||||
InetAddress result;
|
||||
// for RUNNING and PENDING instances it's worthwhile waiting for the address to show; in all other cases we return null immediately
|
||||
if (instance.state().name() == InstanceStateName.RUNNING || instance.state().name() == InstanceStateName.PENDING) {
|
||||
final TimePoint started = TimePoint.now();
|
||||
while ((result = addressSupplierMethod.get()) == null &&
|
||||
(!timeoutNullMeaningForever.isPresent() ||
|
||||
started.until(TimePoint.now()).compareTo(timeoutNullMeaningForever.get()) < 0));
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetAddress getPublicAddress(Optional<Duration> timeoutNullMeaningForever) {
|
||||
InetAddress result;
|
||||
final TimePoint started = TimePoint.now();
|
||||
while ((result = getPublicAddress()) == null &&
|
||||
(!timeoutNullMeaningForever.isPresent() ||
|
||||
started.until(TimePoint.now()).compareTo(timeoutNullMeaningForever.get()) < 0));
|
||||
return result;
|
||||
return getAddressWithTimeout(timeoutNullMeaningForever, this::getPublicAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+61
-17
@@ -45,9 +45,10 @@ import com.sap.sse.landscape.aws.persistence.MongoObjectFactory;
|
||||
import com.sap.sse.landscape.aws.persistence.PersistenceFactory;
|
||||
import com.sap.sse.landscape.mongodb.Database;
|
||||
import com.sap.sse.landscape.mongodb.MongoEndpoint;
|
||||
import com.sap.sse.landscape.mongodb.MongoProcess;
|
||||
import com.sap.sse.landscape.mongodb.MongoReplicaSet;
|
||||
import com.sap.sse.landscape.mongodb.impl.DatabaseImpl;
|
||||
import com.sap.sse.landscape.mongodb.impl.MongoProcessImpl;
|
||||
import com.sap.sse.landscape.mongodb.impl.MongoProcessInReplicaSetImpl;
|
||||
import com.sap.sse.landscape.mongodb.impl.MongoReplicaSetImpl;
|
||||
import com.sap.sse.landscape.rabbitmq.RabbitMQEndpoint;
|
||||
import com.sap.sse.landscape.ssh.SSHKeyPair;
|
||||
@@ -131,7 +132,9 @@ import software.amazon.awssdk.services.route53.model.ResourceRecordSet;
|
||||
|
||||
public class AwsLandscapeImpl<ShardingKey, MetricsT extends ApplicationProcessMetrics,
|
||||
MasterProcessT extends ApplicationMasterProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>> implements AwsLandscape<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> {
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>>
|
||||
implements AwsLandscape<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> {
|
||||
private static final String MONGO_REPLICA_SET_NAME_AND_PORT_SEPARATOR = ":";
|
||||
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;
|
||||
@@ -140,9 +143,9 @@ ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterP
|
||||
// TODO <config> the "Java Application with Reverse Proxy" security group in eu-west-2 for experimenting; we need this security group per region
|
||||
private static final String DEFAULT_APPLICATION_SERVER_SECURITY_GROUP_ID_EU_WEST_1 = "sg-eaf31e85";
|
||||
private static final String DEFAULT_APPLICATION_SERVER_SECURITY_GROUP_ID_EU_WEST_2 = "sg-0b2afd48960251280";
|
||||
private static final String DEFAULT_MONGODB_SECURITY_GROUP_ID_EU_WEST_1 = "sg-0a9bc2fb61f10a342";
|
||||
private static final String DEFAULT_MONGODB_SECURITY_GROUP_ID_EU_WEST_2 = "sg-02649c35a73ee0ae5";
|
||||
private static final String DEFAULT_NON_DNS_MAPPED_ALB_NAME = "DefDyn";
|
||||
private static final String MONGO_REPLICA_SET_TAG_NAME = "mongo-replica-set";
|
||||
private static final String MONGO_DEFAULT_REPLICA_SET_NAME = "live";
|
||||
private static final String RABBITMQ_TAG_NAME = "RabbitMQEndpoint";
|
||||
private final String accessKeyId;
|
||||
private final String secretAccessKey;
|
||||
@@ -779,6 +782,20 @@ ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterP
|
||||
return getDefaultSecurityGroupForApplicationHosts(region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroup getDefaultSecurityGroupForMongoDBHosts(com.sap.sse.landscape.Region region) {
|
||||
final SecurityGroup result;
|
||||
// TODO find a better way, e.g., by tagging, to identify the security group per region to use for MongoDB hosts
|
||||
if (region.getId().equals(Region.EU_WEST_1.id())) {
|
||||
result = getSecurityGroup(DEFAULT_MONGODB_SECURITY_GROUP_ID_EU_WEST_1, region);
|
||||
} else if (region.getId().equals(Region.EU_WEST_2.id())) {
|
||||
result = getSecurityGroup(DEFAULT_MONGODB_SECURITY_GROUP_ID_EU_WEST_2, region);
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApplicationLoadBalancer<ShardingKey, MetricsT> getNonDNSMappedLoadBalancer(
|
||||
com.sap.sse.landscape.Region region, String wildcardDomain) {
|
||||
@@ -814,13 +831,46 @@ ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterP
|
||||
public MongoEndpoint getDatabaseConfigurationForDefaultReplicaSet(com.sap.sse.landscape.Region region) {
|
||||
return getDatabaseConfigurationForReplicaSet(region, MONGO_DEFAULT_REPLICA_SET_NAME);
|
||||
}
|
||||
|
||||
private int getMongoPort(String[] replicaSetNameAndOptionalPort) {
|
||||
final int result;
|
||||
if (replicaSetNameAndOptionalPort.length < 2) {
|
||||
result = MongoProcess.DEFAULT_PORT;
|
||||
} else {
|
||||
result = Integer.valueOf(replicaSetNameAndOptionalPort[1].trim());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoEndpoint getDatabaseConfigurationForReplicaSet(com.sap.sse.landscape.Region region, String mongoReplicaSetName) {
|
||||
public Optional<String> getTag(AwsInstance<ShardingKey, MetricsT> host, String tagName) {
|
||||
final DescribeTagsResponse tagResponse = getEc2Client(getRegion(host.getRegion())).describeTags(b->b.filters(
|
||||
Filter.builder()
|
||||
.name("resource-id").values(host.getInstanceId()).build(),
|
||||
Filter.builder()
|
||||
.name("key").values(tagName).build()));
|
||||
return tagResponse.tags().stream().map(t->t.value()).findAny();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tags getTagForMongoProcess(Tags tagsToAddTo, String replicaSetName, int port) {
|
||||
return tagsToAddTo.and(MONGO_REPLICA_SETS_TAG_NAME,
|
||||
(replicaSetName==null?"":replicaSetName)+MONGO_REPLICA_SET_NAME_AND_PORT_SEPARATOR+port);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoReplicaSet getDatabaseConfigurationForReplicaSet(com.sap.sse.landscape.Region region, String mongoReplicaSetName) {
|
||||
final MongoReplicaSet result = new MongoReplicaSetImpl(mongoReplicaSetName);
|
||||
for (final AwsInstance<ShardingKey, MetricsT> host : getHostsWithTagValue(region, MONGO_REPLICA_SET_TAG_NAME, mongoReplicaSetName)) {
|
||||
// assume MongoDB default port
|
||||
result.addReplica(new MongoProcessImpl(host));
|
||||
for (final AwsInstance<ShardingKey, MetricsT> host : getHostsWithTag(region, MONGO_REPLICA_SETS_TAG_NAME)) {
|
||||
getTag(host, MONGO_REPLICA_SETS_TAG_NAME).ifPresent(tagValue->{
|
||||
for (final String replicaNameWithOptionalPortColonSeparated : tagValue.split(",")) {
|
||||
final String[] splitByColon = replicaNameWithOptionalPortColonSeparated.split(MONGO_REPLICA_SET_NAME_AND_PORT_SEPARATOR);
|
||||
if (splitByColon[0].trim().equals(mongoReplicaSetName.trim())) {
|
||||
// standalone; no replica set name provided; maybe a port?
|
||||
final int port = getMongoPort(splitByColon);
|
||||
result.addReplica(new MongoProcessInReplicaSetImpl(result, port, host));
|
||||
}
|
||||
}});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -834,15 +884,9 @@ ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterP
|
||||
result = new RabbitMQEndpoint() {
|
||||
@Override
|
||||
public int getPort() {
|
||||
final DescribeTagsResponse tagResponse = getEc2Client(getRegion(region)).describeTags(b->b.filters(
|
||||
Filter.builder()
|
||||
.name("resource-id").values(anyRabbitMQHost.getInstanceId()).build(),
|
||||
Filter.builder()
|
||||
.name("key").values(RABBITMQ_TAG_NAME).build()));
|
||||
return tagResponse.tags().stream().map(t->{
|
||||
final String trimmedPort = t.value().trim();
|
||||
return trimmedPort.isEmpty() ? RabbitMQEndpoint.DEFAULT_PORT : Integer.valueOf(trimmedPort);
|
||||
}).findAny().orElse(RabbitMQEndpoint.DEFAULT_PORT);
|
||||
return getTag(anyRabbitMQHost, RABBITMQ_TAG_NAME)
|
||||
.map(t -> t.trim().isEmpty() ? RabbitMQEndpoint.DEFAULT_PORT : Integer.valueOf(t.trim()))
|
||||
.orElse(RabbitMQEndpoint.DEFAULT_PORT);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
package com.sap.sse.landscape.aws.orchestration;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.sap.sse.landscape.InboundReplicationConfiguration;
|
||||
import com.sap.sse.landscape.OutboundReplicationConfiguration;
|
||||
import com.sap.sse.landscape.ProcessConfigurationVariable;
|
||||
import com.sap.sse.landscape.Release;
|
||||
import com.sap.sse.landscape.application.ApplicationMasterProcess;
|
||||
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
|
||||
import com.sap.sse.landscape.application.ApplicationReplicaProcess;
|
||||
import com.sap.sse.landscape.aws.AwsInstance;
|
||||
import com.sap.sse.landscape.mongodb.Database;
|
||||
import com.sap.sse.landscape.rabbitmq.RabbitMQEndpoint;
|
||||
|
||||
/**
|
||||
* In addition to launching a host, this procedure launches an initial application server process on that host.
|
||||
* Therefore, it offers the configuration of release, server name, as well as replication properties for the application
|
||||
* server process.
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public class StartAwsApplicationHost<ShardingKey,
|
||||
MetricsT extends ApplicationProcessMetrics,
|
||||
MasterProcessT extends ApplicationMasterProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
HostT extends AwsInstance<ShardingKey, MetricsT>>
|
||||
extends StartAwsHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> {
|
||||
/**
|
||||
* A builder that helps building an instance of type {@link StartAwsApplicationHost} or any subclass thereof (then
|
||||
* using specialized builders). The following default rules apply, in addition to the defaults rules of the
|
||||
* builders that this builder interface {@link StartAwsHost.Builder extends}.
|
||||
* <ul>
|
||||
* <li>If no {@link #setRelease(Release) release is set}, an empty {@link Optional} will be returned by
|
||||
* {@link #getRelease()}, indicating to use the default release pre-deployed in the image launched.</li>
|
||||
* <li>If no {@link #setDatabaseName(String) database name is set explicitly}, it defaults to the
|
||||
* {@link #getServerName() server name}.</li>
|
||||
* <li>The {@link #getOutboundReplicationConfiguration() output replication}
|
||||
* {@link OutboundReplicationConfiguration#getOutboundReplicationExchangeName() exchange name} defaults to the
|
||||
* {@link #getServerName() server name}.</li>
|
||||
* <li>The {@link #getOutboundReplicationConfiguration() output replication}
|
||||
* {@link OutboundReplicationConfiguration#getOutboundRabbitMQEndpoint() RabbitMQ endpoint} defaults to the
|
||||
* {@link #getInboundReplicationConfiguration() inbound}
|
||||
* {@link InboundReplicationConfiguration#getInboundRabbitMQEndpoint() RabbitMQ endpoint}.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*/
|
||||
public static interface Builder<T extends StartAwsHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>, ShardingKey,
|
||||
MetricsT extends ApplicationProcessMetrics,
|
||||
MasterProcessT extends ApplicationMasterProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
HostT extends AwsInstance<ShardingKey, MetricsT>>
|
||||
extends StartAwsHost.Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> {
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setRelease(Optional<Release> release);
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setServerName(String serverName);
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setDatabaseName(String databaseName);
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setReplicationConfiguration(InboundReplicationConfiguration replicationConfiguration);
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setOutboundReplicationConfiguration(OutboundReplicationConfiguration outboundReplicationConfiguration);
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setRabbitConfiguration(RabbitMQEndpoint rabbitConfiguration);
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setDatabaseConfiguration(Database databaseConfiguration);
|
||||
}
|
||||
|
||||
protected abstract static class BuilderImpl<T extends StartAwsHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>, ShardingKey,
|
||||
MetricsT extends ApplicationProcessMetrics,
|
||||
MasterProcessT extends ApplicationMasterProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
HostT extends AwsInstance<ShardingKey, MetricsT>>
|
||||
extends StartAwsHost.BuilderImpl<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
implements Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> {
|
||||
private Optional<Release> release = Optional.empty();
|
||||
private String serverName;
|
||||
private String databaseName;
|
||||
private Database databaseConfiguration;
|
||||
private RabbitMQEndpoint rabbitConfiguration;
|
||||
private Optional<InboundReplicationConfiguration> inboundReplicationConfiguration = Optional.empty();
|
||||
private OutboundReplicationConfiguration outboundReplicationConfiguration;
|
||||
|
||||
/**
|
||||
* By default, the release pre-deployed in the image will be used, represented by an empty {@link Optional}
|
||||
* returned by this default method implementation.
|
||||
*/
|
||||
protected Optional<Release> getRelease() {
|
||||
return release;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setRelease(Optional<Release> release) {
|
||||
this.release = release;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected String getServerName() {
|
||||
return serverName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setServerName(String serverName) {
|
||||
this.serverName = serverName;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected String getDatabaseName() {
|
||||
return databaseName == null ? getServerName() : databaseName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setDatabaseName(String databaseName) {
|
||||
this.databaseName = databaseName;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Database getDatabaseConfiguration() {
|
||||
return databaseConfiguration == null ? getLandscape().getDatabase(getRegion(), getDatabaseName()) : databaseConfiguration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setDatabaseConfiguration(Database databaseConfiguration) {
|
||||
this.databaseConfiguration = databaseConfiguration;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected RabbitMQEndpoint getRabbitConfiguration() {
|
||||
return rabbitConfiguration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setRabbitConfiguration(RabbitMQEndpoint rabbitConfiguration) {
|
||||
this.rabbitConfiguration = rabbitConfiguration;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected boolean isOutboundReplicationExchangeNameSet() {
|
||||
return outboundReplicationConfiguration != null && outboundReplicationConfiguration.getOutboundReplicationExchangeName() != null;
|
||||
}
|
||||
|
||||
protected boolean isInboundReplicationRabbitMQEndpointSet() {
|
||||
return inboundReplicationConfiguration != null && inboundReplicationConfiguration.isPresent()
|
||||
&& inboundReplicationConfiguration.get().getInboundRabbitMQEndpoint() != null;
|
||||
}
|
||||
|
||||
protected boolean isOutboundReplicationRabbitMQEndpointSet() {
|
||||
return outboundReplicationConfiguration != null && outboundReplicationConfiguration.getOutboundRabbitMQEndpoint() != null;
|
||||
}
|
||||
|
||||
protected OutboundReplicationConfiguration getOutboundReplicationConfiguration() {
|
||||
final OutboundReplicationConfiguration.Builder resultBuilder;
|
||||
if (outboundReplicationConfiguration != null) {
|
||||
resultBuilder = OutboundReplicationConfiguration.copy(outboundReplicationConfiguration);
|
||||
} else {
|
||||
resultBuilder = OutboundReplicationConfiguration.builder();
|
||||
}
|
||||
if (!isOutboundReplicationExchangeNameSet()) {
|
||||
resultBuilder.setOutboundReplicationExchangeName(getServerName());
|
||||
}
|
||||
if (!isOutboundReplicationRabbitMQEndpointSet()) {
|
||||
getInboundReplicationConfiguration().ifPresent(irc->resultBuilder.setOutboundRabbitMQEndpoint(irc.getInboundRabbitMQEndpoint()));
|
||||
}
|
||||
return resultBuilder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setOutboundReplicationConfiguration(OutboundReplicationConfiguration outboundReplicationConfiguration) {
|
||||
this.outboundReplicationConfiguration = outboundReplicationConfiguration;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Optional<InboundReplicationConfiguration> getInboundReplicationConfiguration() {
|
||||
final InboundReplicationConfiguration.Builder resultBuilder;
|
||||
if (inboundReplicationConfiguration == null || !inboundReplicationConfiguration.isPresent()) {
|
||||
resultBuilder = InboundReplicationConfiguration.builder();
|
||||
} else {
|
||||
resultBuilder = InboundReplicationConfiguration.copy(inboundReplicationConfiguration.get());
|
||||
}
|
||||
return !isInboundReplicationRabbitMQEndpointSet()
|
||||
? Optional.of(resultBuilder
|
||||
.setInboundRabbitMQEndpoint(getLandscape().getDefaultRabbitConfiguration(getRegion()))
|
||||
.build())
|
||||
: inboundReplicationConfiguration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setReplicationConfiguration(InboundReplicationConfiguration replicationConfiguration) {
|
||||
this.inboundReplicationConfiguration = Optional.of(replicationConfiguration);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
protected StartAwsApplicationHost(
|
||||
BuilderImpl<? extends StartAwsHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> builder) {
|
||||
super(builder);
|
||||
builder.getRelease().ifPresent(this::addUserData);
|
||||
addUserData(builder.getDatabaseConfiguration());
|
||||
addUserData(builder.getOutboundReplicationConfiguration());
|
||||
if (builder.getServerName() != null) {
|
||||
addUserData(ProcessConfigurationVariable.SERVER_NAME, builder.getServerName());
|
||||
}
|
||||
builder.getInboundReplicationConfiguration().ifPresent(this::addUserData);
|
||||
}
|
||||
}
|
||||
+4
-25
@@ -66,8 +66,6 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
* <li>If an {@link #getImageType() image type} has been specified, it serves as the default for looking up the
|
||||
* {@link #getMachineImage() image} to launch from. However, an image type set explicitly, or subclasses overriding
|
||||
* {@link #getMachineImage()} may take precedence.</li>
|
||||
* <li>If no {@link #setRelease(Release) release is set}, an empty {@link Optional} will be returned by
|
||||
* {@link #getRelease()}, indicating to use the default release pre-deployed in the image launched.</li>
|
||||
* <li>If no {@link #setAvailabilityZone(AwsAvailabilityZone) availability zone} is specified, this builder will try
|
||||
* to obtain the {@link #getRegion()} which in this case must have been {@link #setRegion(AwsRegion)} or otherwise
|
||||
* be returned from an overridden {@link #getRegion()} in a specialized builder, and will
|
||||
@@ -78,17 +76,8 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
* <li>If no {@link #setSecurityGroups(Iterable) security group} has been set, the {@link #getLandscape() landscape}
|
||||
* is asked to provide its {@link AwsLandscape#getDefaultSecurityGroupForApplicationHosts(Region) default security
|
||||
* group for application hosts} in the {@link #getRegion() region} used by this builder.</li>
|
||||
* <li>If no {@link #setDatabaseName(String) database name is set explicitly}, it defaults to the
|
||||
* {@link #getServerName() server name}.</li>
|
||||
* <li>The {@link #getOptionalTimeout() optional timeout} defaults to an {@link Optional#empty() empty optional},
|
||||
* meaning that waiting for the instance won't timeout by default.</li>
|
||||
* <li>The {@link #getOutboundReplicationConfiguration() output replication}
|
||||
* {@link OutboundReplicationConfiguration#getOutboundReplicationExchangeName() exchange name} defaults to the
|
||||
* {@link #getServerName() server name}.</li>
|
||||
* <li>The {@link #getOutboundReplicationConfiguration() output replication}
|
||||
* {@link OutboundReplicationConfiguration#getOutboundRabbitMQEndpoint() RabbitMQ endpoint} defaults to the
|
||||
* {@link #getInboundReplicationConfiguration() inbound}
|
||||
* {@link InboundReplicationConfiguration#getInboundRabbitMQEndpoint() RabbitMQ endpoint}.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
@@ -105,7 +94,7 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setRelease(Optional<Release> release);
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setLandscape(AwsLandscape<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> landscape);
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setLandscape(AwsLandscape<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> landscape);
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setInstanceType(InstanceType instanceType);
|
||||
|
||||
@@ -127,8 +116,7 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setDatabaseName(String databaseName);
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setReplicationConfiguration(
|
||||
InboundReplicationConfiguration replicationConfiguration);
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setReplicationConfiguration(InboundReplicationConfiguration replicationConfiguration);
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setOutboundReplicationConfiguration(OutboundReplicationConfiguration outboundReplicationConfiguration);
|
||||
|
||||
@@ -136,8 +124,7 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setDatabaseConfiguration(Database databaseConfiguration);
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setCommaSeparatedEmailAddressesToNotifyOfStartup(
|
||||
String commaSeparatedEmailAddressesToNotifyOfStartup);
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setCommaSeparatedEmailAddressesToNotifyOfStartup(String commaSeparatedEmailAddressesToNotifyOfStartup);
|
||||
|
||||
Builder<T, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT> setOptionalTimeout(Optional<Duration> optionalTimeout);
|
||||
|
||||
@@ -462,16 +449,9 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
this.tags = Optional.of(builder.getTags().orElse(Tags.empty()).and(NAME_TAG_NAME, builder.getInstanceName()));
|
||||
this.securityGroups = builder.getSecurityGroups();
|
||||
this.hostSupplier = builder.getHostSupplier();
|
||||
builder.getRelease().ifPresent(this::addUserData);
|
||||
addUserData(builder.getDatabaseConfiguration());
|
||||
addUserData(builder.getOutboundReplicationConfiguration());
|
||||
if (builder.getServerName() != null) {
|
||||
addUserData(ProcessConfigurationVariable.SERVER_NAME, builder.getServerName());
|
||||
}
|
||||
if (builder.getCommaSeparatedEmailAddressesToNotifyOfStartup() != null) {
|
||||
addUserData(ProcessConfigurationVariable.SERVER_STARTUP_NOTIFY, builder.getCommaSeparatedEmailAddressesToNotifyOfStartup());
|
||||
}
|
||||
builder.getInboundReplicationConfiguration().ifPresent(this::addUserData);
|
||||
}
|
||||
|
||||
protected static <ShardingKey,
|
||||
@@ -506,10 +486,9 @@ extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>
|
||||
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
HostT castHost = getLandscape().launchHost(hostSupplier,
|
||||
host = getLandscape().launchHost(hostSupplier,
|
||||
getMachineImage(), getInstanceType(), getAvailabilityZone(), getKeyName(), getSecurityGroups(), getTags(),
|
||||
Util.toArray(getUserData(), new String[0]));
|
||||
host = castHost;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+138
-12
@@ -1,18 +1,48 @@
|
||||
package com.sap.sse.landscape.aws.orchestration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.jcraft.jsch.JSchException;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.landscape.Host;
|
||||
import com.sap.sse.landscape.application.ApplicationMasterProcess;
|
||||
import com.sap.sse.landscape.application.ApplicationProcessMetrics;
|
||||
import com.sap.sse.landscape.application.ApplicationReplicaProcess;
|
||||
import com.sap.sse.landscape.aws.AwsInstance;
|
||||
import com.sap.sse.landscape.aws.AwsLandscape;
|
||||
import com.sap.sse.landscape.aws.HostSupplier;
|
||||
import com.sap.sse.landscape.aws.Tags;
|
||||
import com.sap.sse.landscape.aws.impl.AwsInstanceImpl;
|
||||
import com.sap.sse.landscape.mongodb.MongoProcess;
|
||||
import com.sap.sse.landscape.mongodb.MongoReplicaSet;
|
||||
import com.sap.sse.landscape.mongodb.impl.MongoProcessImpl;
|
||||
import com.sap.sse.landscape.mongodb.impl.MongoProcessInReplicaSetImpl;
|
||||
import com.sap.sse.landscape.orchestration.StartHost;
|
||||
|
||||
import software.amazon.awssdk.services.ec2.model.InstanceType;
|
||||
|
||||
/**
|
||||
* Launches a MongoDB host with user data as follows:<pre>
|
||||
* Launches a MongoDB host with a single MongoDB process listening on the {@link MongoProcess#DEFAULT_PORT default port}
|
||||
* with user data as follows:
|
||||
*
|
||||
* <pre>
|
||||
* REPLICA_SET_NAME={@link Builder#setReplicaSetName(String) replicaSetName}
|
||||
* REPLICA_SET_PRIMARY={@link Builder#setReplicaSetName(String) replicaSetPrimary}
|
||||
* REPLICA_SET_PRIORITY={@link Builder#setReplicaSetName(String) replicaSetVotes}
|
||||
* REPLICA_SET_VOTES={@link Builder#setReplicaSetName(String) replicaSetVotes}</pre>
|
||||
* REPLICA_SET_VOTES={@link Builder#setReplicaSetName(String) replicaSetVotes}
|
||||
* </pre>
|
||||
*
|
||||
* If this is used to add a replica to an already existing replica set, specifying the replica set name is sufficient,
|
||||
* and the existing nodes will be discovered by searching for hosts tagged with the tag whose name is provided by the
|
||||
* {@link #MONGODB_REPLICA_SETS_TAG_NAME} constant.
|
||||
* <p>
|
||||
*
|
||||
* To start a primary, only specify the desired replica set name and leave the primary specification empty {@code null}.
|
||||
* 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.
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*/
|
||||
@@ -24,14 +54,33 @@ extends StartAwsHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, Aws
|
||||
REPLICA_SET_NAME, REPLICA_SET_PRIMARY, REPLICA_SET_PRIORITY, REPLICA_SET_VOTES;
|
||||
}
|
||||
|
||||
private MongoProcess mongoProcess;
|
||||
|
||||
private final String replicaSetName;
|
||||
|
||||
/**
|
||||
* In order to launch a standalone instance, call {@link #setReplicaSetName(String)} with {@code null} as a
|
||||
* parameter. To launch a new first instance (primary) for a replica set call {@link #setReplicaSetPrimary(String)}
|
||||
* with {@code null} as a parameter.
|
||||
*
|
||||
* Defaults:
|
||||
* <ul>
|
||||
* <li>The image type defaults to the value of the constant {@link #MONGODB_SERVER_IMAGE_TYPE} ("mongodb-server").</li>
|
||||
* <li>The replica set name defaults to "live"</li>
|
||||
* <li>The image type, indicated by the tag whose name is provided by the constant
|
||||
* {@link StartHost#IMAGE_TYPE_TAG_NAME}, defaults to the value of the constant {@link #MONGODB_SERVER_IMAGE_TYPE}
|
||||
* ("mongodb-server").</li>
|
||||
* <li>The replica set name defaults to {@link AwsLandscape#MONGO_DEFAULT_REPLICA_SET_NAME "live"}</li>
|
||||
* <li>The "primary" information, if not provided (and explicitly {@link #setReplicaSetPrimary(String) setting} to
|
||||
* {@code null} counts as "providing" in this case), is obtained by searching the region for instances that based on their
|
||||
* {@link AwsLandscape#MONGO_DEFAULT_REPLICA_SET_NAME} tag declare to belong to the replica set selected, connecting to the
|
||||
* replica set and figuring out its primary node.</li>
|
||||
* <li>The replica set priority defaults to 1</li>
|
||||
* <li>The replica set votes defaults to 1</li>
|
||||
* <li>A tag is added to the instance launched that lets the landscape recognize it as running a MongoDB process</li>
|
||||
* <li>The instance name (the "Name" tag's value) defaults to "MongoDB Replica Set {replica-set-name} P{replica-set-priority}"</li>
|
||||
* <li>The instance type defaults to {@link InstanceType#I3_LARGE} which is a small instance type with NVMe storage that is storage
|
||||
* optimized and hence provides good throughput to the NVMe disk</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*/
|
||||
public static interface Builder<ShardingKey, MetricsT extends ApplicationProcessMetrics,
|
||||
@@ -51,7 +100,7 @@ extends StartAwsHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, Aws
|
||||
|
||||
Builder<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> setReplicaSetVotes(int replicaSetVotes);
|
||||
|
||||
StartMongoDBServer<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> build();
|
||||
StartMongoDBServer<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> build() throws URISyntaxException, JSchException, IOException, InterruptedException;
|
||||
}
|
||||
|
||||
protected static class BuilderImpl<ShardingKey, MetricsT extends ApplicationProcessMetrics,
|
||||
@@ -59,8 +108,9 @@ extends StartAwsHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, Aws
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>>
|
||||
extends StartAwsHost.BuilderImpl<StartMongoDBServer<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>, ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, AwsInstance<ShardingKey, MetricsT>>
|
||||
implements Builder<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> {
|
||||
private String replicaSetName = "live";
|
||||
private String replicaSetName = AwsLandscape.MONGO_DEFAULT_REPLICA_SET_NAME;
|
||||
private String replicaSetPrimary;
|
||||
private boolean replicaSetPrimaryWasSetExplicitly = false;
|
||||
private int replicaSetPriority = 1;
|
||||
private int replicaSetVotes = 1;
|
||||
|
||||
@@ -82,6 +132,7 @@ extends StartAwsHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, Aws
|
||||
@Override
|
||||
public Builder<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> setReplicaSetPrimary(String replicaSetPrimary) {
|
||||
this.replicaSetPrimary = replicaSetPrimary;
|
||||
this.replicaSetPrimaryWasSetExplicitly = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -101,8 +152,32 @@ extends StartAwsHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, Aws
|
||||
return replicaSetName;
|
||||
}
|
||||
|
||||
protected String getReplicaSetPrimary() {
|
||||
return replicaSetPrimary;
|
||||
protected String getReplicaSetPrimary() throws URISyntaxException, JSchException, IOException, InterruptedException {
|
||||
final String result;
|
||||
if (replicaSetPrimary == null) {
|
||||
if (replicaSetPrimaryWasSetExplicitly) {
|
||||
// a new first primary for a (presumably) new replica set or a new stand-alone instance
|
||||
result = null;
|
||||
} else {
|
||||
if (getReplicaSetName() != null) {
|
||||
// no primary information was set explicitly; take all instances known so far and construct a comma-separated host:port list
|
||||
// for connecting to the entire replica set through which then the primary is automatically found for adding the replica to the set
|
||||
result = String.join(",", Util.map(Util.filter(getLandscape().getDatabaseConfigurationForReplicaSet(getRegion(), getReplicaSetName()).getInstances(),
|
||||
instance->instance.getHost().getPrivateAddress(getOptionalTimeout()) != null),
|
||||
instance->instance.getHost().getPrivateAddress(getOptionalTimeout()).getCanonicalHostName()+":"+instance.getPort()));
|
||||
} else {
|
||||
result = null; // empty replica set name provided, overriding default replica set name; launch as stand-alone
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (getReplicaSetName() == null) {
|
||||
throw new IllegalStateException("Cannot provide a primary address " + replicaSetPrimary
|
||||
+ " when no replica set name is specified which means to create a stand-alone process");
|
||||
} else {
|
||||
result = replicaSetPrimary;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected int getReplicaSetPriority() {
|
||||
@@ -114,7 +189,33 @@ extends StartAwsHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, Aws
|
||||
}
|
||||
|
||||
@Override
|
||||
public StartMongoDBServer<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> build() {
|
||||
protected String getInstanceName() {
|
||||
final String result;
|
||||
if (super.getInstanceName() != null) {
|
||||
result = super.getInstanceName();
|
||||
} else {
|
||||
result = "MongoDB Replica Set "+getReplicaSetName()+" P"+getReplicaSetPriority();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InstanceType getInstanceType() {
|
||||
final InstanceType result;
|
||||
if (super.getInstanceType() == null) {
|
||||
result = InstanceType.I3_LARGE;
|
||||
} else {
|
||||
result = super.getInstanceType();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StartMongoDBServer<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> build() throws URISyntaxException, JSchException, IOException, InterruptedException {
|
||||
setTags(Optional.of(getLandscape().getTagForMongoProcess(getTags().orElse(Tags.empty()), getReplicaSetName(), MongoProcess.DEFAULT_PORT)));
|
||||
if (getSecurityGroups() == null) {
|
||||
setSecurityGroups(Collections.singleton(getLandscape().getDefaultSecurityGroupForMongoDBHosts(getRegion())));
|
||||
}
|
||||
return new StartMongoDBServer<>(this);
|
||||
}
|
||||
}
|
||||
@@ -126,12 +227,37 @@ extends StartAwsHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, Aws
|
||||
return new BuilderImpl<>();
|
||||
}
|
||||
|
||||
protected StartMongoDBServer(BuilderImpl<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> builder) {
|
||||
protected StartMongoDBServer(BuilderImpl<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> builder) throws URISyntaxException, JSchException, IOException, InterruptedException {
|
||||
super(builder);
|
||||
addUserData(MongoDBReplicaSetUserData.REPLICA_SET_NAME.name(), builder.getReplicaSetName());
|
||||
addUserData(MongoDBReplicaSetUserData.REPLICA_SET_PRIMARY.name(), builder.getReplicaSetPrimary());
|
||||
this.replicaSetName = builder.getReplicaSetName();
|
||||
if (builder.getReplicaSetName() != null) {
|
||||
addUserData(MongoDBReplicaSetUserData.REPLICA_SET_NAME.name(), builder.getReplicaSetName());
|
||||
}
|
||||
if (builder.getReplicaSetPrimary() != null) {
|
||||
addUserData(MongoDBReplicaSetUserData.REPLICA_SET_PRIMARY.name(), builder.getReplicaSetPrimary());
|
||||
}
|
||||
addUserData(MongoDBReplicaSetUserData.REPLICA_SET_PRIORITY.name(), Integer.toString(builder.getReplicaSetPriority()));
|
||||
addUserData(MongoDBReplicaSetUserData.REPLICA_SET_VOTES.name(), Integer.toString(builder.getReplicaSetVotes()));
|
||||
}
|
||||
|
||||
/**
|
||||
* The process launched by this procedure. {@link MongoProcess#getHost()} is expected to match {@link #getHost()}.
|
||||
*/
|
||||
public MongoProcess getMongoProcess() {
|
||||
return mongoProcess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
super.run();
|
||||
if (replicaSetName == null) {
|
||||
mongoProcess = new MongoProcessImpl(getHost());
|
||||
} else {
|
||||
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, MongoProcess.DEFAULT_PORT, instance);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -15,9 +15,10 @@ import com.sap.sse.landscape.ssh.SshCommandChannel;
|
||||
|
||||
public interface Host {
|
||||
/**
|
||||
* Obtains the public IP address of this host. Note that during the boot phase a host may not yet have such
|
||||
* a public IP address assigned. In this case, {@code null} may be returned. To avoid this, you can alternatively
|
||||
* call {@link #getPublicAddress(Optional)} to wait for a public IP address to become available.
|
||||
* Obtains the public IP address of this host. Note that during the boot phase and after shutdown/termination a host
|
||||
* may not yet have such a public IP address assigned. In this case, {@code null} may be returned. To avoid this,
|
||||
* you can alternatively call {@link #getPublicAddress(Optional)} to wait for a public IP address to become
|
||||
* available.
|
||||
*/
|
||||
InetAddress getPublicAddress();
|
||||
|
||||
@@ -30,6 +31,23 @@ public interface Host {
|
||||
*/
|
||||
InetAddress getPublicAddress(Optional<Duration> timeoutNullMeaningForever);
|
||||
|
||||
/**
|
||||
* Obtains the private IP address of this host. Note that during the boot phase and after shutdown/termination a host
|
||||
* may not yet have such a public IP address assigned. In this case, {@code null} may be returned. To avoid this,
|
||||
* you can alternatively call {@link #getPrivateAddress(Optional)} to wait for a public IP address to become
|
||||
* available.
|
||||
*/
|
||||
InetAddress getPrivateAddress();
|
||||
|
||||
/**
|
||||
* Obtains the private IP address of this host, waiting for one to become available for the duration of
|
||||
* {@code timeout}, or forever in case {@code timeout} is {@code null}
|
||||
*
|
||||
* @param timeoutNullMeaningForever
|
||||
* if {@code null}, waits forever
|
||||
*/
|
||||
InetAddress getPrivateAddress(Optional<Duration> timeoutNullMeaningForever);
|
||||
|
||||
/**
|
||||
* Connects to an SSH session for the username specified, using the SSH key pair used to launch the instance, and
|
||||
* opens a "shell" channel. Use the {@link Channel} returned by {@link Channel#setInputStream(java.io.InputStream)
|
||||
|
||||
@@ -21,13 +21,19 @@ ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterP
|
||||
* @return the security group that shall be assigned by default to any application server host, whether master or
|
||||
* replica
|
||||
*/
|
||||
SecurityGroup getDefaultSecurityGroupForApplicationHosts(com.sap.sse.landscape.Region region);
|
||||
SecurityGroup getDefaultSecurityGroupForApplicationHosts(Region region);
|
||||
|
||||
/**
|
||||
* @return the security group that shall be assigned by default to any host used as part of the central reverse
|
||||
* proxy cluster in a region
|
||||
*/
|
||||
SecurityGroup getDefaultSecurityGroupForCentralReverseProxy(com.sap.sse.landscape.Region region);
|
||||
SecurityGroup getDefaultSecurityGroupForCentralReverseProxy(Region region);
|
||||
|
||||
/**
|
||||
* @return the security group that shall be assigned by default to any host used as part of a MongoDB replica set;
|
||||
* we expect public SSH access and local access to the default MongoDB port (usually 27017).
|
||||
*/
|
||||
SecurityGroup getDefaultSecurityGroupForMongoDBHosts(Region region);
|
||||
|
||||
/**
|
||||
* Obtains the default RabbitMQ configuration for the {@code region} specified. If nothing else is specified
|
||||
|
||||
+1
@@ -1,4 +1,5 @@
|
||||
package com.sap.sse.landscape.mongodb;
|
||||
|
||||
public interface MongoProcessInReplicaSet extends MongoProcess {
|
||||
MongoReplicaSet getReplicaSet();
|
||||
}
|
||||
+3
-10
@@ -1,8 +1,5 @@
|
||||
package com.sap.sse.landscape.mongodb.impl;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import com.mongodb.MongoClient;
|
||||
import com.sap.sse.landscape.Host;
|
||||
import com.sap.sse.landscape.mongodb.MongoProcessInReplicaSet;
|
||||
import com.sap.sse.landscape.mongodb.MongoReplicaSet;
|
||||
@@ -19,13 +16,9 @@ public class MongoProcessInReplicaSetImpl extends MongoProcessImpl implements Mo
|
||||
super(port, host);
|
||||
this.replicaSet = replicaSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInReplicaSet() throws URISyntaxException {
|
||||
return getReplicaSetClient().getReplicaSetStatus() != null;
|
||||
}
|
||||
|
||||
private MongoClient getReplicaSetClient() throws URISyntaxException {
|
||||
return replicaSet.getClient();
|
||||
@Override
|
||||
public MongoReplicaSet getReplicaSet() {
|
||||
return replicaSet;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,10 @@
|
||||
package com.sap.sse.landscape.orchestration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import com.jcraft.jsch.JSchException;
|
||||
import com.sap.sse.landscape.Host;
|
||||
import com.sap.sse.landscape.Landscape;
|
||||
import com.sap.sse.landscape.MachineImage;
|
||||
@@ -38,7 +43,7 @@ implements Procedure<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT> {
|
||||
MasterProcessT extends ApplicationMasterProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
ReplicaProcessT extends ApplicationReplicaProcess<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT>,
|
||||
HostT extends Host> {
|
||||
T build();
|
||||
T build() throws UnknownHostException, URISyntaxException, JSchException, IOException, InterruptedException;
|
||||
}
|
||||
|
||||
protected abstract static class BuilderImpl<T extends StartHost<ShardingKey, MetricsT, MasterProcessT, ReplicaProcessT, HostT>, ShardingKey,
|
||||
|
||||
Reference in new issue
Block a user