java/com.sap.sailing.landscape.common/META-INF/MANIFEST.MF
... ...
@@ -11,3 +11,4 @@ Require-Bundle: com.sap.sse.security.common,
11 11
com.sap.sse.landscape.aws.common
12 12
Bundle-ActivationPolicy: lazy
13 13
Export-Package: com.sap.sailing.landscape.common
14
+Import-Package: software.amazon.awssdk.regions
java/com.sap.sailing.landscape.common/src/com/sap/sailing/landscape/common/SharedLandscapeConstants.java
... ...
@@ -1,5 +1,7 @@
1 1
package com.sap.sailing.landscape.common;
2 2
3
+import software.amazon.awssdk.regions.Region;
4
+
3 5
public interface SharedLandscapeConstants {
4 6
/**
5 7
* If no specific domain name is provided, e.g., when creating a new application replica set, this will be
... ...
@@ -20,6 +22,15 @@ public interface SharedLandscapeConstants {
20 22
*/
21 23
String DEFAULT_SECURITY_SERVICE_REPLICA_SET_NAME = "security-service";
22 24
25
+ String RABBIT_IN_DEFAULT_REGION_HOSTNAME = "rabbit.internal.sapsailing.com";
26
+
27
+ Region DEFAULT_REGION = Region.EU_WEST_1;
28
+
29
+ /**
30
+ * We maintain a DNS entry for "rabbit.internal.sapsailing.com" (see {@link #RABBIT_IN_DEFAULT_REGION_HOSTNAME}) in this region
31
+ */
32
+ String REGION_WITH_RABBITMQ_DNS_HOSTNAME = DEFAULT_REGION.id();
33
+
23 34
/**
24 35
* This is the region of the load balancer handling the default traffic for {@code *.sapsailing.com}. It is also
25 36
* called the "dynamic" load balancer because adding, removing or changing any hostname-based rule in its HTTPS
... ...
@@ -38,8 +49,14 @@ public interface SharedLandscapeConstants {
38 49
* for archived events. If such a state is reached, "dynamic" load balancing may potentially be used regardless
39 50
* the region.
40 51
*/
41
- String REGION_WITH_DEFAULT_LOAD_BALANCER = "eu-west-1";
42
-
52
+ String REGION_WITH_DEFAULT_LOAD_BALANCER = DEFAULT_REGION.id();
53
+
54
+ /**
55
+ * Tag name used to identify instances on which a RabbitMQ installation is running. The tag value is currently interpreted to
56
+ * be the port number (usually 5672) on which the RabbitMQ endpoint can be reached.
57
+ */
58
+ String RABBITMQ_TAG_NAME = "RabbitMQEndpoint";
59
+
43 60
/**
44 61
* The tag value used to identify host images that can be launched in order to run one or more Sailing Analytics
45 62
* server processes on it.
java/com.sap.sse.landscape.aws.test/src/com/sap/sse/landscape/aws/ConnectivityTest.java
... ...
@@ -51,6 +51,7 @@ import com.sap.sse.landscape.aws.orchestration.CreateDNSBasedLoadBalancerMapping
51 51
import com.sap.sse.landscape.impl.ReleaseRepositoryImpl;
52 52
import com.sap.sse.landscape.mongodb.MongoEndpoint;
53 53
import com.sap.sse.landscape.mongodb.impl.DatabaseImpl;
54
+import com.sap.sse.landscape.rabbitmq.RabbitMQEndpoint;
54 55
import com.sap.sse.landscape.ssh.SSHKeyPair;
55 56
import com.sap.sse.landscape.ssh.SshCommandChannel;
56 57
... ...
@@ -535,4 +536,18 @@ public class ConnectivityTest<ProcessT extends AwsApplicationProcess<String, Sai
535 536
assertEquals(200, healthCheckConnection.getResponseCode());
536 537
healthCheckConnection.disconnect();
537 538
}
539
+
540
+ @Test
541
+ public void getDefaultRabbitConfigForEuWest1() {
542
+ final RabbitMQEndpoint rabbitConfig = landscape.getDefaultRabbitConfiguration(new AwsRegion(Region.EU_WEST_1, landscape));
543
+ assertEquals("rabbit.internal.sapsailing.com", rabbitConfig.getNodeName());
544
+ assertEquals(5672, rabbitConfig.getPort());
545
+ }
546
+
547
+ @Test
548
+ public void getDefaultRabbitConfigForEuWest2() {
549
+ final RabbitMQEndpoint rabbitConfig = landscape.getDefaultRabbitConfiguration(new AwsRegion(Region.EU_WEST_2, landscape));
550
+ assertTrue(rabbitConfig.getNodeName().startsWith("172.31."));
551
+ assertEquals(5672, rabbitConfig.getPort());
552
+ }
538 553
}
java/com.sap.sse.landscape.aws/META-INF/MANIFEST.MF
... ...
@@ -26,7 +26,8 @@ Require-Bundle: com.amazon.aws.aws-java-api;bundle-version="2.13.50",
26 26
com.sap.sse.replication.interfaces,
27 27
com.sap.sse.operationaltransformation,
28 28
org.mongodb.driver-core;bundle-version="4.3.1",
29
- org.mongodb.driver-sync;bundle-version="4.3.1"
29
+ org.mongodb.driver-sync;bundle-version="4.3.1",
30
+ com.sap.sailing.landscape.common
30 31
Web-ContextPath: /landscape
31 32
Import-Package: org.apache.shiro;version="1.2.2",
32 33
org.osgi.framework;version="1.8.0",
java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/AwsLandscape.java
... ...
@@ -34,7 +34,6 @@ import com.sap.sse.landscape.mongodb.MongoProcess;
34 34
import com.sap.sse.landscape.mongodb.MongoProcessInReplicaSet;
35 35
import com.sap.sse.landscape.mongodb.MongoReplicaSet;
36 36
import com.sap.sse.landscape.mongodb.impl.MongoProcessImpl;
37
-import com.sap.sse.landscape.rabbitmq.RabbitMQEndpoint;
38 37
import com.sap.sse.landscape.ssh.SSHKeyPair;
39 38
40 39
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
... ...
@@ -129,12 +128,6 @@ public interface AwsLandscape<ShardingKey> extends Landscape<ShardingKey> {
129 128
130 129
String MONGO_REPLICA_SET_NAME_AND_PORT_SEPARATOR = ":";
131 130
132
- /**
133
- * Tag name used to identify instances on which a RabbitMQ installation is running. The tag value is currently interpreted to
134
- * be the port number (usually 5672) on which the RabbitMQ endpoint can be reached.
135
- */
136
- String RABBITMQ_TAG_NAME = "RabbitMQEndpoint";
137
-
138 131
String CENTRAL_REVERSE_PROXY_TAG_NAME = "CentralReverseProxy";
139 132
140 133
/**
... ...
@@ -677,13 +670,6 @@ public interface AwsLandscape<ShardingKey> extends Landscape<ShardingKey> {
677 670
678 671
Iterable<MongoEndpoint> getMongoEndpoints(Region region);
679 672
680
- /**
681
- * Gets a default RabbitMQ configuration for the {@code region} specified.<p>
682
- *
683
- * TODO For now, the method searches for accordingly-tagged instances and picks the first one it finds. We need to extend this to RabbitMQ replication.
684
- */
685
- RabbitMQEndpoint getDefaultRabbitConfiguration(AwsRegion region);
686
-
687 673
Database getDatabase(Region region, String databaseName);
688 674
689 675
/**
java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/AwsLandscapeImpl.java
... ...
@@ -35,6 +35,7 @@ import java.util.regex.Pattern;
35 35
import com.jcraft.jsch.JSch;
36 36
import com.jcraft.jsch.JSchException;
37 37
import com.jcraft.jsch.KeyPair;
38
+import com.sap.sailing.landscape.common.SharedLandscapeConstants;
38 39
import com.sap.sse.common.Duration;
39 40
import com.sap.sse.common.TimePoint;
40 41
import com.sap.sse.common.Util;
... ...
@@ -1463,26 +1464,31 @@ public class AwsLandscapeImpl<ShardingKey> implements AwsLandscape<ShardingKey>
1463 1464
}
1464 1465
1465 1466
@Override
1466
- public RabbitMQEndpoint getDefaultRabbitConfiguration(AwsRegion region) {
1467
+ public RabbitMQEndpoint getDefaultRabbitConfiguration(com.sap.sse.landscape.Region region) {
1467 1468
final RabbitMQEndpoint result;
1468
- final Iterable<AwsInstance<ShardingKey>> rabbitMQHostsInRegion = getRunningHostsWithTag(region, RABBITMQ_TAG_NAME, AwsInstanceImpl::new);
1469
- if (rabbitMQHostsInRegion.iterator().hasNext()) {
1470
- final AwsInstance<ShardingKey> anyRabbitMQHost = rabbitMQHostsInRegion.iterator().next();
1471
- result = new RabbitMQEndpoint() {
1472
- @Override
1473
- public int getPort() {
1474
- return getTag(anyRabbitMQHost, RABBITMQ_TAG_NAME)
1475
- .map(t -> t.trim().isEmpty() ? RabbitMQEndpoint.DEFAULT_PORT : Integer.valueOf(t.trim()))
1476
- .orElse(RabbitMQEndpoint.DEFAULT_PORT);
1477
- }
1478
-
1479
- @Override
1480
- public String getNodeName() {
1481
- return anyRabbitMQHost.getPrivateAddress().getHostAddress();
1482
- }
1483
- };
1469
+ if (region.getId().equals(Region.EU_WEST_1.id())) {
1470
+ result = ()->SharedLandscapeConstants.RABBIT_IN_DEFAULT_REGION_HOSTNAME; // using default port RabbitMQEndpoint.DEFAULT_PORT
1484 1471
} else {
1485
- result = null;
1472
+ final Iterable<AwsInstance<ShardingKey>> rabbitMQHostsInRegion = getRunningHostsWithTag(
1473
+ region, SharedLandscapeConstants.RABBITMQ_TAG_NAME, AwsInstanceImpl::new);
1474
+ if (rabbitMQHostsInRegion.iterator().hasNext()) {
1475
+ final AwsInstance<ShardingKey> anyRabbitMQHost = rabbitMQHostsInRegion.iterator().next();
1476
+ result = new RabbitMQEndpoint() {
1477
+ @Override
1478
+ public int getPort() {
1479
+ return getTag(anyRabbitMQHost, SharedLandscapeConstants.RABBITMQ_TAG_NAME)
1480
+ .map(t -> t.trim().isEmpty() ? RabbitMQEndpoint.DEFAULT_PORT : Integer.valueOf(t.trim()))
1481
+ .orElse(RabbitMQEndpoint.DEFAULT_PORT);
1482
+ }
1483
+
1484
+ @Override
1485
+ public String getNodeName() {
1486
+ return anyRabbitMQHost.getPrivateAddress().getHostAddress();
1487
+ }
1488
+ };
1489
+ } else {
1490
+ result = null;
1491
+ }
1486 1492
}
1487 1493
return result;
1488 1494
}
... ...
@@ -1493,17 +1499,6 @@ public class AwsLandscapeImpl<ShardingKey> implements AwsLandscape<ShardingKey>
1493 1499
}
1494 1500
1495 1501
@Override
1496
- public RabbitMQEndpoint getMessagingConfigurationForDefaultCluster(com.sap.sse.landscape.Region region) {
1497
- final RabbitMQEndpoint result;
1498
- if (region.getId().equals(Region.EU_WEST_1.id())) {
1499
- result = ()->"rabbit.internal.sapsailing.com";
1500
- } else {
1501
- result = null;
1502
- }
1503
- return result;
1504
- }
1505
-
1506
- @Override
1507 1502
public <MetricsT extends ApplicationProcessMetrics, ProcessT extends AwsApplicationProcess<ShardingKey, MetricsT, ProcessT>,
1508 1503
HostT extends ApplicationProcessHost<ShardingKey, MetricsT, ProcessT>>
1509 1504
Iterable<HostT> getApplicationProcessHostsByTag(com.sap.sse.landscape.Region region, String tagName,
java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/orchestration/AwsApplicationConfiguration.java
... ...
@@ -9,6 +9,7 @@ import com.sap.sse.landscape.DefaultProcessConfigurationVariables;
9 9
import com.sap.sse.landscape.InboundReplicationConfiguration;
10 10
import com.sap.sse.landscape.OutboundReplicationConfiguration;
11 11
import com.sap.sse.landscape.ProcessConfigurationVariable;
12
+import com.sap.sse.landscape.Region;
12 13
import com.sap.sse.landscape.Release;
13 14
import com.sap.sse.landscape.UserDataProvider;
14 15
import com.sap.sse.landscape.application.ApplicationProcess;
... ...
@@ -43,7 +44,7 @@ implements UserDataProvider {
43 44
* {@link #getServerName() server name}.</li>
44 45
* <li>The {@link #setInboundReplicationConfiguration(InboundReplicationConfiguration) inbound replication}
45 46
* {@link InboundReplicationConfiguration#getInboundRabbitMQEndpoint() RabbitMQ endpoint} defaults to the region's
46
- * {@link AwsLandscape#getDefaultRabbitConfiguration(com.sap.sse.landscape.aws.impl.AwsRegion) default RabbitMQ
47
+ * {@link AwsLandscape#getDefaultRabbitConfiguration(Region) default RabbitMQ
47 48
* configuration}. Note that this setting will take effect only if auto-replication is activated for one or more
48 49
* replicables (see {@link InboundReplicationConfiguration#getReplicableIds()}).</li>
49 50
* <li>The {@link #setOutboundReplicationConfiguration() outbound replication}
java/com.sap.sse.landscape/src/com/sap/sse/landscape/Landscape.java
... ...
@@ -49,10 +49,15 @@ public interface Landscape<ShardingKey> {
49 49
/**
50 50
* Obtains the default RabbitMQ configuration for the {@code region} specified. If nothing else is specified
51 51
* explicitly, application server replica sets launched in the {@code region} shall use this for their replication
52
- * message channels and exchanges.
52
+ * message channels and exchanges.<p>
53
+ *
54
+ * For our default region, this will return a DNS name always pointing to the current private IP of
55
+ * the instance running the default RabbitMQ service in the region. In other regions, the private IP
56
+ * of the regional default RabbitMQ instance is discovered by scanning for running instances tagged
57
+ * with {@link SharedLandscapeConstants#RABBITMQ_TAG_NAME}.
53 58
*/
54
- RabbitMQEndpoint getMessagingConfigurationForDefaultCluster(Region region);
55
-
59
+ RabbitMQEndpoint getDefaultRabbitConfiguration(Region region);
60
+
56 61
/**
57 62
* Tells the regions supported. The underlying hyperscaler may have more, but we may not want to run in all.
58 63
*/
wiki/info/landscape/creating-ec2-image-for-rabbitmq-from-scratch.md
... ...
@@ -12,6 +12,8 @@ where ``a.b.c.d`` is the external IP address of your fresh instance.
12 12
13 13
The script will ensure the login user's ``authorized_keys`` are updated periodically to contain those of the landscape managers, then will install the necessary packages, particularly ``rabbitmq-server`` and, to get real log files under ``/var/log``, the ``syslog-ng`` package. It then enables the ``rabbitmq_management`` plugin, so access to the management UI becomes possible through port ``15672``. The configuration file under ``/etc/rabbitmq/rabbitmq.conf`` is patched such that guest logins are possible also from non-localhost addresses, by adding the ``loopback_users = none`` directive to the config file. It finally (re-)starts the RabbitMQ server to let these config changes take effect.
14 14
15
-Your RabbitMQ server then should be ready to handle requests. Test this by invoking the management UI, e.g., through an ssh port forward to port ``15672``. When this seems good, pick a smart time to change the DNS record for ``rabbit.internal.sapsailing.com`` because there will be a short time of interruptions on all application processes currently connected to the old RabbitMQ which you then have to stop. Those client applications will temporarily lose connection, but our replication component will re-establish these connections, using the DNS name which gets resolved again based on the DNS entry's TTL. Also, let ``rabbit.sapsailing.com`` point to the public IP of the instance.
15
+Your RabbitMQ server then should be ready to handle requests. Test this by invoking the management UI, e.g., through an ssh port forward to port ``15672``. When this seems good, pick a smart time to change the DNS record for ``rabbit.internal.sapsailing.com`` because there will be a short time of interruptions on all application processes currently connected to the old RabbitMQ which you then have to stop. Those client applications will temporarily lose connection, but our replication component will re-establish these connections, using the DNS name which gets resolved again based on the DNS entry's TTL.
16 16
17
-Add a tag with key ``RabbitMQEndpoint`` and value ``5672``, specifying the port on which the RabbitMQ server listens. This tag can be used by our landscape automation procedures to discover the RabbitMQ default instance in the region.
... ...
\ No newline at end of file
0
+Then associate the elastic IP ``54.76.64.42`` as the external IP of the new instance. This will let ``rabbit.sapsailing.com`` point to the public IP of the instance.
1
+
2
+Add a tag with key ``RabbitMQEndpoint`` and value ``5672``, specifying the port on which the RabbitMQ server listens. This tag can be used by our landscape automation procedures to discover the RabbitMQ default instance in the region.