diff --git a/configuration/environments/README b/configuration/environments/README
new file mode 100644
index 00000000000..d7553ebd08f
--- /dev/null
+++ b/configuration/environments/README
@@ -0,0 +1,2 @@
+place these under https://releases.sapsailing.com/environments which is usually
+served by trac@sapsailing.com:releases/environments
diff --git a/configuration/environments/archive-server b/configuration/environments/archive-server
new file mode 100755
index 00000000000..3aedd1cbdff
--- /dev/null
+++ b/configuration/environments/archive-server
@@ -0,0 +1,24 @@
+MEMORY=400g
+SERVER_NAME=ARCHIVE
+REPLICATION_CHANNEL=sapsailinganalytics-archive
+MONGODB_URI="mongodb://dbserver.internal.sapsailing.com:10201/winddb?replicaSet=archive&retryWrites=true&readPreference=secondaryPreferred"
+SERVER_STARTUP_NOTIFY=axel.uhl@sap.com
+BUILD_COMPLETE_NOTIFY=axel.uhl@sap.com
+
+# Configuring for shared SecurityService/SharedSailingData:
+#ADDITIONAL_JAVA_ARGS="$ADDITIONAL_JAVA_ARGS -DAnniversaryRaceDeterminator.enabled=false"
+ADDITIONAL_JAVA_ARGS="$ADDITIONAL_JAVA_ARGS -Dsecurity.sharedAcrossSubdomainsOf=sapsailing.com -Dsecurity.baseUrlForCrossDomainStorage=https://security-service.sapsailing.com -Dgwt.acceptableCrossDomainStorageRequestOriginRegexp=https?://(.*\.)?sapsailing\.com(:[0-9]*)?$"
+REPLICATE_ON_START=com.sap.sse.security.impl.SecurityServiceImpl,com.sap.sailing.shared.server.impl.SharedSailingDataImpl,com.sap.sse.landscape.aws.impl.AwsLandscapeStateImpl
+REPLICATE_MASTER_SERVLET_HOST=security-service.sapsailing.com
+REPLICATE_MASTER_SERVLET_PORT=443
+REPLICATE_MASTER_EXCHANGE_NAME=security_service
+
+# Provide authentication credentials for a user on security-service.sapsailing.com permitted to replicate, either by username/password...
+#REPLICATE_MASTER_USERNAME=(user for replicator login on security-service.sapsailing.com server having SERVER:REPLICATE:<server-name> permission)
+#REPLICATE_MASTER_PASSWORD=(password of the user for replication login on security-service.sapsailing.com)
+# Or by bearer token, obtained, e.g., through
+# curl -d "username=myuser&password=mysecretpassword" "https://security-service.sapsailing.com/security/api/restsecurity/access_token" | jq .access_token
+# or by logging in to the security-service.sapsailing.com server using your web browser and then navigating to
+# https://security-service.sapsailing.com/security/api/restsecurity/access_token
+#REPLICATE_MASTER_BEARER_TOKEN=
+
diff --git a/configuration/environments/archive-server-recovery b/configuration/environments/archive-server-recovery
new file mode 100755
index 00000000000..3e741d96d88
--- /dev/null
+++ b/configuration/environments/archive-server-recovery
@@ -0,0 +1,17 @@
+SERVER_NAME=ARCHIVE-RECOVERY
+REPLICATION_HOST=rabbit.internal.sapsailing.com
+REPLICATION_CHANNEL=sapsailinganalytics-archive
+TELNET_PORT=14888
+SERVER_PORT=8888
+MONGODB_HOST=dbserver.internal.sapsailing.com
+MONGODB_PORT=10208
+MONGODB_NAME=winddb
+EXPEDITION_PORT=2010
+REPLICATE_ON_START=
+REPLICATE_MASTER_SERVLET_HOST=
+REPLICATE_MASTER_SERVLET_PORT=
+REPLICATE_MASTER_QUEUE_HOST=
+REPLICATE_MASTER_QUEUE_PORT=
+SERVER_STARTUP_NOTIFY=simon.marcel.pamies@sap.com
+BUILD_COMPLETE_NOTIFY=simon.marcel.pamies@sap.com
+ADDITIONAL_JAVA_ARGS="$ADDITIONAL_JAVA_ARGS -Drestore.tracked.races=true -XX:ThreadPriorityPolicy=2"
diff --git a/configuration/environments/dev-server b/configuration/environments/dev-server
new file mode 100755
index 00000000000..a626f54c9b5
--- /dev/null
+++ b/configuration/environments/dev-server
@@ -0,0 +1,13 @@
+SERVER_NAME=DEV
+REPLICATION_HOST=rabbit.internal.sapsailing.com
+REPLICATION_CHANNEL=sapsailinganalytics-dev
+TELNET_PORT=14888
+SERVER_PORT=8888
+MONGODB_HOST=dbserver.internal.sapsailing.com
+MONGODB_PORT=10200
+EXPEDITION_PORT=2010
+REPLICATE_ON_START=False
+REPLICATE_MASTER_SERVLET_HOST=
+REPLICATE_MASTER_SERVLET_PORT=
+REPLICATE_MASTER_QUEUE_HOST=
+REPLICATE_MASTER_QUEUE_PORT=
diff --git a/configuration/environments/live-master-server b/configuration/environments/live-master-server
new file mode 100755
index 00000000000..e02ce9ee60a
--- /dev/null
+++ b/configuration/environments/live-master-server
@@ -0,0 +1,19 @@
+# To enable the use of the shared SecurityService and SharedSailingData from security-service.sapsailing.com:
+ADDITIONAL_JAVA_ARGS="$ADDITIONAL_JAVA_ARGS -Dsecurity.sharedAcrossSubdomainsOf=sapsailing.com -Dsecurity.baseUrlForCrossDomainStorage=https://security-service.sapsailing.com -Dgwt.acceptableCrossDomainStorageRequestOriginRegexp=https?://(.*\.)?sapsailing\.com(:[0-9]*)?$"
+# obtain initial polar sheet data from the archive server, without live replication:
+ADDITIONAL_JAVA_ARGS="$ADDITIONAL_JAVA_ARGS -Dpolardata.source.url=https://www.sapsailing.com"
+# obtain initial models for wind estimation from maneuvers from the archive server, without live replication:
+ADDITIONAL_JAVA_ARGS="$ADDITIONAL_JAVA_ARGS -Dwindestimation.source.url=https://www.sapsailing.com"
+REPLICATE_ON_START=com.sap.sse.security.impl.SecurityServiceImpl,com.sap.sailing.shared.server.impl.SharedSailingDataImpl,com.sap.sse.landscape.aws.impl.AwsLandscapeStateImpl
+REPLICATE_MASTER_SERVLET_HOST=security-service.sapsailing.com
+REPLICATE_MASTER_EXCHANGE_NAME=security_service
+
+# Provide authentication credentials for a user on the security-service.sapsailing.com permitted to replicate, either by username/password...
+#REPLICATE_MASTER_USERNAME=(user for replicator login on security-service.sapsailing.com server having SERVER:REPLICATE:<server-name> permission)
+#REPLICATE_MASTER_PASSWORD=(password of the user for replication login on security-service.sapsailing.com)
+# Or by bearer token, obtained, e.g., through
+# curl -d "username=myuser&password=mysecretpassword" "https://security-service.sapsailing.com/security/api/restsecurity/access_token" | jq .access_token
+# or by logging in to the security-service.sapsailing.com server with a user having the SERVER:REPLICATE:security-service and SERVER:READ_REPLICATOR:security-service
+# permissions, using your web browser and then navigating to
+# https://security-service.sapsailing.com/security/api/restsecurity/access_token
+#REPLICATE_MASTER_BEARER_TOKEN=
diff --git a/configuration/environments/live-replica-server b/configuration/environments/live-replica-server
new file mode 100755
index 00000000000..e90f85166a1
--- /dev/null
+++ b/configuration/environments/live-replica-server
@@ -0,0 +1,2 @@
+AUTO_REPLICATE=true
+ADDITIONAL_JAVA_ARGS="$ADDITIONAL_JAVA_ARGS -Dsecurity.sharedAcrossSubdomainsOf=sapsailing.com -Dsecurity.baseUrlForCrossDomainStorage=https://security-service.sapsailing.com -Dgwt.acceptableCrossDomainStorageRequestOriginRegexp=https?://(.*\.)?sapsailing\.com(:[0-9]*)?$"
diff --git a/configuration/environments/live-server b/configuration/environments/live-server
new file mode 100755
index 00000000000..2231ed23c59
--- /dev/null
+++ b/configuration/environments/live-server
@@ -0,0 +1,29 @@
+TELNET_PORT=14888
+SERVER_PORT=8888
+MONGODB_HOST=dbserver.internal.sapsailing.com
+MONGODB_PORT=10202
+EXPEDITION_PORT=2010
+DEPLOY_TO=server
+REPLICATE_MASTER_SERVLET_PORT=8888
+REPLICATE_MASTER_QUEUE_HOST=rabbit.internal.sapsailing.com
+REPLICATE_MASTER_QUEUE_PORT=5672
+REPLICATION_HOST=rabbit.internal.sapsailing.com
+ADDITIONAL_JAVA_ARGS="$ADDITIONAL_JAVA_ARGS -Dorg.eclipse.jetty.LEVEL=OFF -Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog -Drestore.tracked.races=true -Dpolardata.source.url=https://www.sapsailing.com -XX:ThreadPriorityPolicy=2"
+SERVER_STARTUP_NOTIFY=axel.uhl@sap.com
+BUILD_COMPLETE_NOTIFY=axel.uhl@sap.com
+
+# To enable the use of the shared SecurityService and SharedSailingData from security-service.sapsailing.com:
+ADDITIONAL_JAVA_ARGS="$ADDITIONAL_JAVA_ARGS -Dsecurity.sharedAcrossSubdomainsOf=sapsailing.com -Dsecurity.baseUrlForCrossDomainStorage=https://security-service.sapsailing.com -Dgwt.acceptableCrossDomainStorageRequestOriginRegexp=https?://(.*\.)?sapsailing\.com(:[0-9]*)?$"
+REPLICATE_ON_START=com.sap.sse.security.impl.SecurityServiceImpl,com.sap.sailing.shared.server.impl.SharedSailingDataImpl
+REPLICATE_MASTER_SERVLET_HOST=security-service.sapsailing.com
+REPLICATE_MASTER_SERVLET_PORT=443
+REPLICATE_MASTER_EXCHANGE_NAME=security_service
+
+# Provide authentication credentials for a user on security-service.sapsailing.com permitted to replicate, either by username/password...
+#REPLICATE_MASTER_USERNAME=(user for replicator login on security-service.sapsailing.com server having SERVER:REPLICATE:<server-name> permission)
+#REPLICATE_MASTER_PASSWORD=(password of the user for replication login on security-service.sapsailing.com)
+# Or by bearer token, obtained, e.g., through
+# curl -d "username=myuser&password=mysecretpassword" "https://security-service.sapsailing.com/security/api/restsecurity/access_token" | jq .access_token
+# or by logging in to the security-service.sapsailing.com server using your web browser and then navigating to
+# https://security-service.sapsailing.com/security/api/restsecurity/access_token
+#REPLICATE_MASTER_BEARER_TOKEN=
diff --git a/configuration/environments/local-dev-server b/configuration/environments/local-dev-server
new file mode 100755
index 00000000000..095440b8245
--- /dev/null
+++ b/configuration/environments/local-dev-server
@@ -0,0 +1,15 @@
+SERVER_NAME=DEV
+REPLICATION_HOST=localhost
+REPLICATION_CHANNEL=sapsailinganalytics-dev
+TELNET_PORT=14888
+SERVER_PORT=8888
+MONGODB_HOST=localhost
+MONGODB_PORT=27017
+EXPEDITION_PORT=2010
+REPLICATE_ON_START=False
+REPLICATE_MASTER_SERVLET_HOST=
+REPLICATE_MASTER_SERVLET_PORT=
+REPLICATE_MASTER_QUEUE_HOST=
+REPLICATE_MASTER_QUEUE_PORT=
+SERVER_STARTUP_NOTIFY=
+BUILD_COMPLETE_NOTIFY=
diff --git a/configuration/environments/master b/configuration/environments/master
new file mode 100755
index 00000000000..d9989af9388
--- /dev/null
+++ b/configuration/environments/master
@@ -0,0 +1,35 @@
+SERVER_NAME=LIVE
+MONGODB_NAME=live
+REPLICATION_CHANNEL=live
+MEMORY=4096m
+TELNET_PORT=14888
+SERVER_PORT=8888
+MONGODB_HOST=dbserver.internal.sapsailing.com
+MONGODB_PORT=10201
+EXPEDITION_PORT=2010
+DEPLOY_TO=server
+REPLICATE_ON_START=False
+REPLICATE_MASTER_SERVLET_HOST=
+REPLICATE_MASTER_SERVLET_PORT=8888
+REPLICATE_MASTER_QUEUE_HOST=rabbit.internal.sapsailing.com
+REPLICATE_MASTER_QUEUE_PORT=5672
+REPLICATION_HOST=rabbit.internal.sapsailing.com
+SERVER_STARTUP_NOTIFY=axel.uhl@sap.com
+BUILD_COMPLETE_NOTIFY=axel.uhl@sap.com
+ADDITIONAL_JAVA_ARGS="$ADDITIONAL_JAVA_ARGS -Dorg.eclipse.jetty.LEVEL=OFF -Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog -XX:ThreadPriorityPolicy=2"
+
+# To enable the use of the shared SecurityService and SharedSailingData from security-service.sapsailing.com:
+ADDITIONAL_JAVA_ARGS="$ADDITIONAL_JAVA_ARGS -Dsecurity.sharedAcrossSubdomainsOf=sapsailing.com -Dsecurity.baseUrlForCrossDomainStorage=https://security-service.sapsailing.com -Dgwt.acceptableCrossDomainStorageRequestOriginRegexp=https?://(.*\.)?sapsailing\.com(:[0-9]*)?$"
+REPLICATE_ON_START=com.sap.sse.security.impl.SecurityServiceImpl,com.sap.sailing.shared.server.impl.SharedSailingDataImpl,com.sap.sse.landscape.aws.impl.AwsLandscapeStateImpl
+REPLICATE_MASTER_SERVLET_HOST=security-service.sapsailing.com
+REPLICATE_MASTER_SERVLET_PORT=443
+REPLICATE_MASTER_EXCHANGE_NAME=security_service
+
+# Provide authentication credentials for a user on security-service.sapsailing.com permitted to replicate, either by username/password...
+#REPLICATE_MASTER_USERNAME=(user for replicator login on security-service.sapsailing.com server having SERVER:REPLICATE:<server-name> permission)
+#REPLICATE_MASTER_PASSWORD=(password of the user for replication login on security-service.sapsailing.com)
+# Or by bearer token, obtained, e.g., through
+# curl -d "username=myuser&password=mysecretpassword" "https://security-service.sapsailing.com/security/api/restsecurity/access_token" | jq .access_token
+# or by logging in to the security-service.sapsailing.com server using your web browser and then navigating to
+# https://security-service.sapsailing.com/security/api/restsecurity/access_token
+#REPLICATE_MASTER_BEARER_TOKEN=
diff --git a/configuration/environments/replica b/configuration/environments/replica
new file mode 100755
index 00000000000..1665c2f7e10
--- /dev/null
+++ b/configuration/environments/replica
@@ -0,0 +1,9 @@
+REPLICATION_HOST=rabbit.internal.sapsailing.com
+MONGODB_HOST=dbserver.internal.sapsailing.com
+MONGODB_PORT=10202
+EXPEDITION_PORT=2010
+REPLICATE_ON_START=com.sap.sailing.server.impl.RacingEventServiceImpl,com.sap.sse.security.impl.SecurityServiceImpl,com.sap.sse.filestorage.impl.FileStorageManagementServiceImpl,com.sap.sse.mail.impl.MailServiceImpl,com.sap.sailing.polars.impl.PolarDataServiceImpl,com.sap.sailing.domain.racelogtracking.impl.fixtracker.RegattaLogFixTrackerRegattaListener,com.sap.sailing.shared.server.impl.SharedSailingDataImpl,com.sap.sse.landscape.aws.impl.AwsLandscapeStateImpl
+REPLICATE_MASTER_SERVLET_PORT=8888
+REPLICATE_MASTER_QUEUE_HOST=rabbit.internal.sapsailing.com
+REPLICATE_MASTER_QUEUE_PORT=5672
+ADDITIONAL_JAVA_ARGS="$ADDITIONAL_JAVA_ARGS -Dorg.eclipse.jetty.LEVEL=OFF -Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog -XX:ThreadPriorityPolicy=2"
diff --git a/configuration/environments/security-service-master b/configuration/environments/security-service-master
new file mode 100755
index 00000000000..bf2047689ef
--- /dev/null
+++ b/configuration/environments/security-service-master
@@ -0,0 +1,34 @@
+TELNET_PORT=14888
+SERVER_PORT=8888
+MONGODB_HOST=dbserver.internal.sapsailing.com
+MONGODB_PORT=10202
+EXPEDITION_PORT=2010
+DEPLOY_TO=security_service
+REPLICATE_MASTER_SERVLET_PORT=8888
+REPLICATE_MASTER_QUEUE_HOST=rabbit.internal.sapsailing.com
+REPLICATE_MASTER_QUEUE_PORT=5672
+REPLICATION_HOST=rabbit.internal.sapsailing.com
+ADDITIONAL_JAVA_ARGS="$ADDITIONAL_JAVA_ARGS -Dorg.eclipse.jetty.LEVEL=OFF -Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog -Drestore.tracked.races=true -Dpolardata.source.url=https://www.sapsailing.com -XX:ThreadPriorityPolicy=2"
+SERVER_STARTUP_NOTIFY=axel.uhl@sap.com
+BUILD_COMPLETE_NOTIFY=axel.uhl@sap.com
+
+# To enable the use of the shared SecurityService and SharedSailingData from security-service.sapsailing.com:
+ADDITIONAL_JAVA_ARGS="$ADDITIONAL_JAVA_ARGS -Dsecurity.sharedAcrossSubdomainsOf=sapsailing.com -Dsecurity.baseUrlForCrossDomainStorage=https://security-service.sapsailing.com -Dgwt.acceptableCrossDomainStorageRequestOriginRegexp=https?://(.*\.)?sapsailing\.com(:[0-9]*)?$"
+# For the security-service master instance, don't activate replication from security-service
+#REPLICATE_ON_START=com.sap.sse.security.impl.SecurityServiceImpl,com.sap.sailing.shared.server.impl.SharedSailingDataImpl,com.sap.sse.landscape.aws.impl.AwsLandscapeStateImpl
+#REPLICATE_MASTER_SERVLET_HOST=security-service.sapsailing.com
+#REPLICATE_MASTER_SERVLET_PORT=443
+#REPLICATE_MASTER_EXCHANGE_NAME=security_service
+
+# Provide authentication credentials for a user on security-service.sapsailing.com permitted to replicate, either by username/password...
+#REPLICATE_MASTER_USERNAME=(user for replicator login on security-service.sapsailing.com server having SERVER:REPLICATE:<server-name> permission)
+#REPLICATE_MASTER_PASSWORD=(password of the user for replication login on security-service.sapsailing.com)
+# Or by bearer token, obtained, e.g., through
+# curl -d "username=myuser&password=mysecretpassword" "https://security-service.sapsailing.com/security/api/restsecurity/access_token" | jq .access_token
+# or by logging in to the security-service.sapsailing.com server using your web browser and then navigating to
+# https://security-service.sapsailing.com/security/api/restsecurity/access_token
+#REPLICATE_MASTER_BEARER_TOKEN=
+
+MONGODB_URI="mongodb://mongo0.internal.sapsailing.com,mongo1.internal.sapsailing.com/security_service?replicaSet=live&retryWrites=true"
+SERVER_NAME=security_service
+REPLICATION_CHANNEL=security_service
diff --git a/docker/makeImageForLatestRelease b/docker/makeImageForLatestRelease
index 34636204c8d..381858cacc3 100755
--- a/docker/makeImageForLatestRelease
+++ b/docker/makeImageForLatestRelease
@@ -1,9 +1,9 @@
#!/bin/bash
release=$1
-if [ "$release" = "" ]; then
+if [ "${release}" = "" ]; then
SET_LATEST=1
- release=$(wget -O - http://releases.sapsailing.com/ 2>/dev/null | grep build- | tail -1 | sed -e 's/^.*\(build-[0-9]*\).*$/\1/')
- echo Latest release is $release
+ release=$(wget -O - http://releases.sapsailing.com/ 2>/dev/null | grep 'build-[0-9]\{10\}' | tail -1 | sed -e 's/^.*\(build-[0-9]*\).*$/\1/')
+ echo Latest release is ${release}
fi
GITROOT="`dirname $0`/.."
DOCKERDIR="${GITROOT}/docker"
@@ -13,12 +13,12 @@ cp "$GITROOT/java/target/env.sh" "$DOCKERDIR"
cp "$GITROOT/java/target/start" "$DOCKERDIR"
cp "$GITROOT/java/target/configuration/JavaSE-11.profile" "$DOCKERDIR"
cd "$DOCKERDIR"
-docker build --build-arg RELEASE=${release} -t sapsailing:$release .
+docker build --build-arg RELEASE=${release} -t sapsailing:${release} .
echo "Cleaning up..."
rm start env.sh JavaSE-11.profile Dockerfile
-docker tag sapsailing:$release docker.sapsailing.com/sapsailing:$release
-docker push docker.sapsailing.com/sapsailing:$release
+docker tag sapsailing:${release} docker.sapsailing.com/sapsailing:${release}
+docker push docker.sapsailing.com/sapsailing:${release}
if [ "$SET_LATEST" = "1" ]; then
- docker tag sapsailing:$release docker.sapsailing.com/sapsailing:latest
+ docker tag sapsailing:${release} docker.sapsailing.com/sapsailing:latest
docker push docker.sapsailing.com/sapsailing:latest
fi
diff --git a/docker/makeImageForLatestRelease-on-sapmachine11 b/docker/makeImageForLatestRelease-on-sapmachine11
index 800dfcf0a99..2c5ae81b834 100755
--- a/docker/makeImageForLatestRelease-on-sapmachine11
+++ b/docker/makeImageForLatestRelease-on-sapmachine11
@@ -1,9 +1,9 @@
#!/bin/bash
release=$1
-if [ "$release" = "" ]; then
+if [ "${release}" = "" ]; then
SET_LATEST=1
- release=$(wget -O - http://releases.sapsailing.com/ 2>/dev/null | grep sapmachine11- | tail -1 | sed -e 's/^.*\(sapmachine11-[0-9]*\).*$/\1/')
- echo Latest release is $release
+ release=$(wget -O - http://releases.sapsailing.com/ 2>/dev/null | grep 'sapmachine11-[0-9]\{10\}' | tail -1 | sed -e 's/^.*\(sapmachine11-[0-9]*\).*$/\1/')
+ echo Latest release is ${release}
fi
GITROOT="`dirname $0`/.."
DOCKERDIR="${GITROOT}/docker"
@@ -14,14 +14,14 @@ for f in ${FILES_TO_COPY_FROM_JAVA_TARGET}; do
cp "${GITROOT}/java/target/${f}" "$DOCKERDIR"
done
cd "$DOCKERDIR"
-docker build --build-arg RELEASE=${release} -t sapsailing_on_sapmachine11:$release -f Dockerfile_sapsailing_on_sapmachine11 .
+docker build --build-arg RELEASE=${release} -t sapsailing_on_sapmachine11:${release} -f Dockerfile_sapsailing_on_sapmachine11 .
echo "Cleaning up..."
for f in ${FILES_TO_COPY_FROM_JAVA_TARGET}; do
rm "`basename ${f}`"
done
-docker tag sapsailing_on_sapmachine11:$release docker.sapsailing.com/sapsailing_on_sapmachine11:$release
-docker push docker.sapsailing.com/sapsailing_on_sapmachine11:$release
+docker tag sapsailing_on_sapmachine11:${release} docker.sapsailing.com/sapsailing_on_sapmachine11:${release}
+docker push docker.sapsailing.com/sapsailing_on_sapmachine11:${release}
if [ "$SET_LATEST" = "1" ]; then
- docker tag sapsailing_on_sapmachine11:$release docker.sapsailing.com/sapsailing_on_sapmachine11:latest
+ docker tag sapsailing_on_sapmachine11:${release} docker.sapsailing.com/sapsailing_on_sapmachine11:latest
docker push docker.sapsailing.com/sapsailing_on_sapmachine11:latest
fi
diff --git a/docker/makeImageForLatestRelease-on-sapmachine17 b/docker/makeImageForLatestRelease-on-sapmachine17
index 52a61e44c7a..3513d69dbe3 100755
--- a/docker/makeImageForLatestRelease-on-sapmachine17
+++ b/docker/makeImageForLatestRelease-on-sapmachine17
@@ -1,9 +1,9 @@
#!/bin/bash
release=$1
-if [ "$release" = "" ]; then
+if [ "${release}" = "" ]; then
SET_LATEST=1
- release=$(wget -O - http://releases.sapsailing.com/ 2>/dev/null | grep sapmachine17- | tail -1 | sed -e 's/^.*\(sapmachine17-[0-9]*\).*$/\1/')
- echo Latest release is $release
+ release=$(wget -O - http://releases.sapsailing.com/ 2>/dev/null | grep 'sapmachine17-[0-9]\{10\}' | tail -1 | sed -e 's/^.*\(sapmachine17-[0-9]*\).*$/\1/')
+ echo Latest release is ${release}
fi
GITROOT="`dirname $0`/.."
DOCKERDIR="${GITROOT}/docker"
@@ -14,14 +14,14 @@ for f in ${FILES_TO_COPY_FROM_JAVA_TARGET}; do
cp "${GITROOT}/java/target/${f}" "$DOCKERDIR"
done
cd "$DOCKERDIR"
-docker build --build-arg RELEASE=${release} -t sapsailing_on_sapmachine17:$release -f Dockerfile_sapsailing_on_sapmachine17 .
+docker build --build-arg RELEASE=${release} -t sapsailing_on_sapmachine17:${release} -f Dockerfile_sapsailing_on_sapmachine17 .
echo "Cleaning up..."
for f in ${FILES_TO_COPY_FROM_JAVA_TARGET}; do
rm "`basename ${f}`"
done
-docker tag sapsailing_on_sapmachine17:$release docker.sapsailing.com/sapsailing_on_sapmachine17:$release
-docker push docker.sapsailing.com/sapsailing_on_sapmachine17:$release
+docker tag sapsailing_on_sapmachine17:${release} docker.sapsailing.com/sapsailing_on_sapmachine17:${release}
+docker push docker.sapsailing.com/sapsailing_on_sapmachine17:${release}
if [ "$SET_LATEST" = "1" ]; then
- docker tag sapsailing_on_sapmachine17:$release docker.sapsailing.com/sapsailing_on_sapmachine17:latest
+ docker tag sapsailing_on_sapmachine17:${release} docker.sapsailing.com/sapsailing_on_sapmachine17:latest
docker push docker.sapsailing.com/sapsailing_on_sapmachine17:latest
fi
diff --git a/docker/makeImageForLatestRelease-raspi b/docker/makeImageForLatestRelease-raspi
index 2a060ffd8f0..a5b0477f3fb 100755
--- a/docker/makeImageForLatestRelease-raspi
+++ b/docker/makeImageForLatestRelease-raspi
@@ -1,9 +1,9 @@
#!/bin/bash
release=$1
-if [ "$release" = "" ]; then
+if [ "${release}" = "" ]; then
SET_LATEST=1
release=$(wget -O - http://releases.sapsailing.com/ 2>/dev/null | grep build- | tail -1 | sed -e 's/^.*\(build-[0-9]*\).*$/\1/')
- echo Latest release is $release
+ echo Latest release is ${release}
fi
GITROOT="`dirname $0`/.."
DOCKERDIR="${GITROOT}/docker"
diff --git a/java/com.sap.sailing.domain.test/TestTTCM without Proxy.launch b/java/com.sap.sailing.domain.test/TestTTCM without Proxy.launch
index 27b4a89210c..40f8f5c221b 100644
--- a/java/com.sap.sailing.domain.test/TestTTCM without Proxy.launch
+++ b/java/com.sap.sailing.domain.test/TestTTCM without Proxy.launch
@@ -1,16 +1,18 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinThreeRaces.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinThreeRaces.java
index db40db04dc8..65161d6f027 100644
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinThreeRaces.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/LowPointFirstToWinThreeRaces.java
@@ -33,7 +33,7 @@ import com.sap.sse.common.Util.Pair;
*
*
* Those carried wins are added to the
- * {@link #isWin(com.sap.sailing.domain.leaderboard.Leaderboard, com.sap.sailing.domain.base.Competitor, com.sap.sailing.domain.base.RaceColumn, com.sap.sse.common.TimePoint, com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingAndORCPerformanceCurveCache, Function)
+ * {@link #isWin(Leaderboard, Competitor, RaceColumn, TimePoint, Function, WindLegTypeAndLegBearingAndORCPerformanceCurveCache)
* wins} achieved in the medal series. More wins rank better. Equal numbers of races won make the score in the last race
* in that series the first tie-breaker. Note that "last race" can be different races in case of multiple fleets in that
* medal series, such as in a semi-final medal series split into fleets A and B. Should the tie not be resolved this
diff --git a/java/com.sap.sailing.gwt.ui/GWT Sailing DevMode.launch b/java/com.sap.sailing.gwt.ui/GWT Sailing DevMode.launch
index 964428b8c6e..29d77d495ef 100755
--- a/java/com.sap.sailing.gwt.ui/GWT Sailing DevMode.launch
+++ b/java/com.sap.sailing.gwt.ui/GWT Sailing DevMode.launch
@@ -95,7 +95,6 @@
-
diff --git a/java/com.sap.sailing.gwt.ui/GWT Sailing SDM (Home+Admin+Raceboard).launch b/java/com.sap.sailing.gwt.ui/GWT Sailing SDM (Home+Admin+Raceboard).launch
index 451b0abcafd..bd0ffca7c13 100644
--- a/java/com.sap.sailing.gwt.ui/GWT Sailing SDM (Home+Admin+Raceboard).launch
+++ b/java/com.sap.sailing.gwt.ui/GWT Sailing SDM (Home+Admin+Raceboard).launch
@@ -88,7 +88,6 @@
-
diff --git a/java/com.sap.sailing.gwt.ui/GWT Sailing SDM ManagementConsole.launch b/java/com.sap.sailing.gwt.ui/GWT Sailing SDM ManagementConsole.launch
index 3813def89a1..167290d78e2 100644
--- a/java/com.sap.sailing.gwt.ui/GWT Sailing SDM ManagementConsole.launch
+++ b/java/com.sap.sailing.gwt.ui/GWT Sailing SDM ManagementConsole.launch
@@ -85,7 +85,6 @@
-
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/whatsnew/resources/SailingAnalyticsNotes.html b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/whatsnew/resources/SailingAnalyticsNotes.html
index 2bfd62b15b6..9031190bc6e 100755
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/whatsnew/resources/SailingAnalyticsNotes.html
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/whatsnew/resources/SailingAnalyticsNotes.html
@@ -26,6 +26,9 @@
solved this issue.
Data mining now offers administrators with the necessary permissions to analyze role, permission,
session and subscription data for administrative purposes.
+ The .../v2/leaderboards API now supports the LEG_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS detail type,
+ also included when specifying ALL. It produces the field currentLegAverageSpeedOverGround-kts
+ in the data part of the result document.
January 2023
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_cs.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_cs.properties
index fd5a2c5cece..7c6fdf0ed83 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_cs.properties
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_cs.properties
@@ -1395,7 +1395,7 @@ calculatedTimeTraveled=Přepočtený čas
calculatedTimeTraveledTooltip=Přepočtený čas podle handicapu závodníka odvozený z času\nod startu rozjížďky a ujeté vzdálenosti (se započtením větru).
raceCalculatedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSeconds=Přepočtený čas u nejrychlejšího
raceCalculatedTimeAtEstimatedArrivalAtCompetitorFarthestAheadInSecondsTooltip=Přepočtený čas v okamžiku odhadovaného doplutí k závodníkovi, který je momentálně nejdále vpředu.\nOdhad vychází z průměrné rychlosti přibližování se k cíli v daném úseku a z předpokladu stejného (přepočteného) výkonu v následujících úsecích.
-sailorInfo=Informace o jachtaři
+sailorInfo=Informace pro Jachtaře
sailorInfoLongText=Oficiální výsledky, protesty,\ninformační tabule, předpověď počasí:
eventQuickfinder=Rychlé hledání události
regattaQuickfinder=Rychlé hledání regaty
@@ -1418,7 +1418,7 @@ numberWindFixes=Záznamy větru
sailedMiles=Odpluté námořní míle
millionValue=Miliony: {0,number,#0.0}
billionValue=Miliardy: {0,number,#0.0}
-noResults=Nejsou zde dostupné žádné výsledky. Zkuste zkontrolovat „Informace o jachtaři“.
+noResults=Nejsou zde dostupné žádné výsledky. Zkuste zkontrolovat „Informace pro Jachtaře“.
noNews=Nejsou k dispozici žádné novinky.
pointsValue={0,number,#0.00}
openLeaderboard=Otevřít výsledkovou tabuli
@@ -2402,7 +2402,7 @@ sharingLinkCopied=Zkopírovaný odkaz do schránky!
browserDoesNotSupportCopyToClipboard=Váš prohlížeč nepodporuje funkci kopírování do schránky.
browserDoesNotSupportNativeSharing=Váš prohlížeč nepodporuje nativní funkci sdílení.
startOfTrackingMustNotBeAfterEndOfTracking=Začátek trasování nesmí být po konci trasování.
-landscape=Na šířku
+landscape=Prostředí
identifier=Identifikátor
selectARole=Vyberte roli
showWindLadder=Rastr větru
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java
index 18430f8c8e4..079457e3fe1 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java
@@ -3402,7 +3402,7 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
for (Entry>, Integer> e : statistics.entrySet()) {
replicationCountByOperationClassName.put(e.getKey().getName(), e.getValue());
}
- replicaDTOs.add(new ReplicaDTO(replicaDescriptor.getIpAddress().getHostName(),
+ replicaDTOs.add(new ReplicaDTO(replicaDescriptor.getIpAddress().getHostAddress(),
replicaDescriptor.getRegistrationTime().asDate(), replicaDescriptor.getUuid().toString(),
replicaDescriptor.getReplicableIdsAsStrings(), replicaDescriptor.getAdditionalInformation(),
replicationCountByOperationClassName,
diff --git a/java/com.sap.sailing.landscape.ui/META-INF/MANIFEST.MF b/java/com.sap.sailing.landscape.ui/META-INF/MANIFEST.MF
index 1d33ef688e9..82622928c37 100755
--- a/java/com.sap.sailing.landscape.ui/META-INF/MANIFEST.MF
+++ b/java/com.sap.sailing.landscape.ui/META-INF/MANIFEST.MF
@@ -21,7 +21,8 @@ Require-Bundle: com.sap.sse.gwt,
com.amazon.aws.aws-java-api,
com.sap.sse.landscape.common,
com.sap.sse.landscape.aws.common,
- com.jcraft.jsch;bundle-version="0.1.54",
+ com.github.mwiede.jsch;bundle-version="0.2.8",
+ bcprov-ext;bundle-version="1.72.0",
elemental2;bundle-version="1.1.0",
org.json.simple,
com.sap.sse,
diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/CreateApplicationReplicaSetDialog.java b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/CreateApplicationReplicaSetDialog.java
index 8b398db548d..16ed1ae1e73 100755
--- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/CreateApplicationReplicaSetDialog.java
+++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/CreateApplicationReplicaSetDialog.java
@@ -1,5 +1,6 @@
package com.sap.sailing.landscape.ui.client;
+import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
@@ -11,6 +12,7 @@ import com.sap.sailing.landscape.common.SharedLandscapeConstants;
import com.sap.sailing.landscape.ui.client.i18n.StringMessages;
import com.sap.sse.common.Util;
import com.sap.sse.gwt.client.ErrorReporter;
+import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
import com.sap.sse.gwt.client.controls.IntegerBox;
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
@@ -114,9 +116,39 @@ public class CreateApplicationReplicaSetDialog extends AbstractApplicationReplic
private static class Validator implements DataEntryDialog.Validator {
private final StringMessages stringMessages;
+ private final LandscapeManagementWriteServiceAsync landscapeManagementService;
- public Validator(StringMessages stringMessages) {
+ public Validator(StringMessages stringMessages, LandscapeManagementWriteServiceAsync landscapeManagementService) {
this.stringMessages = stringMessages;
+ this.landscapeManagementService = landscapeManagementService;
+ }
+
+ @Override
+ public void validate(CreateApplicationReplicaSetInstructions valueToValidate, AsyncCallback callback,
+ AsyncActionsExecutor validationExecutor) {
+ // TODO Auto-generated method stub
+ final String localErrorMessage = getErrorMessage(valueToValidate);
+ if (localErrorMessage != null) {
+ validationExecutor.execute(cb->cb.onSuccess(localErrorMessage), VALIDATION_ACTION_CATEGORY, callback);
+ } else {
+ // check availability of DNS name remotely:
+ landscapeManagementService.hasDNSResourceRecordsForReplicaSet(valueToValidate.getName(), valueToValidate.getOptionalDomainName(),
+ new AsyncCallback() {
+ @Override
+ public void onFailure(Throwable caught) {
+ callback.onFailure(caught);
+ }
+
+ @Override
+ public void onSuccess(Boolean hasDNSResourceRecordsForReplicaSet) {
+ if (hasDNSResourceRecordsForReplicaSet) {
+ callback.onSuccess(stringMessages.dnsNameAlreadyInUse());
+ } else {
+ callback.onSuccess(null); // no error
+ }
+ }
+ });
+ }
}
@Override
@@ -154,7 +186,7 @@ public class CreateApplicationReplicaSetDialog extends AbstractApplicationReplic
boolean mayUseDynamicLoadBalancer) {
super(stringMessages
.createApplicationReplicaSet(), landscapeManagementService, releaseNames, stringMessages,
- errorReporter, new Validator(stringMessages), callback);
+ errorReporter, new Validator(stringMessages, landscapeManagementService), callback);
this.stringMessages = stringMessages;
this.useExistingSharedMasterInstance = useExistingSharedMasterInstance;
nameBox = createTextBox("", 40);
diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementPanel.java b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementPanel.java
index b5f316440e8..2f9a3eeb287 100755
--- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementPanel.java
+++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementPanel.java
@@ -257,7 +257,7 @@ public class LandscapeManagementPanel extends SimplePanel {
return result;
}
};
- applicationReplicaSetsTable.addColumn(rs->rs.getReplicaSetName(), stringMessages.name());
+ applicationReplicaSetsTable.addColumn(rs->rs.getReplicaSetName(), stringMessages.name(), (rs1, rs2)->rs1.getReplicaSetName().toLowerCase().compareTo(rs2.getReplicaSetName().toLowerCase()));
final SafeHtmlCell versionCell = new SafeHtmlCell();
final Column, SafeHtml> versionColumn = new Column, SafeHtml>(versionCell) {
@Override
diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementWriteService.java b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementWriteService.java
index 944e761914c..3e66437fafc 100755
--- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementWriteService.java
+++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementWriteService.java
@@ -160,4 +160,6 @@ public interface LandscapeManagementWriteService extends RemoteService {
void moveAllApplicationProcessesAwayFrom(AwsInstanceDTO host, String optionalInstanceTypeForNewInstance,
String optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception;
+
+ boolean hasDNSResourceRecordsForReplicaSet(String replicaSetName, String optionalDomainName);
}
diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementWriteServiceAsync.java b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementWriteServiceAsync.java
index 6957d6d5cdf..b99cfffca6b 100755
--- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementWriteServiceAsync.java
+++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementWriteServiceAsync.java
@@ -300,4 +300,6 @@ public interface LandscapeManagementWriteServiceAsync {
*/
void moveAllApplicationProcessesAwayFrom(AwsInstanceDTO host, String optionalInstanceTypeForNewInstance,
String optionalKeyName, byte[] privateKeyEncryptionPassphrase, AsyncCallback callback);
+
+ void hasDNSResourceRecordsForReplicaSet(String replicaSetName, String optionalDomainName, AsyncCallback callback);
}
diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages.java b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages.java
index 42b43d5d17d..cbc8bd0d3ed 100755
--- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages.java
+++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages.java
@@ -163,4 +163,5 @@ com.sap.sse.gwt.adminconsole.StringMessages {
String moveTheFollowingMasterAndReplicaProcessesAway(String fromHostWithId, String masterProcesses, String replicaProcesses);
String processOfReplicaSet(int portOfProcess, String replicaSetName);
String successfullyMovedAllProcessesAwayFromHost(String hostname);
+ String dnsNameAlreadyInUse();
}
diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages.properties b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages.properties
index c130c62ab45..c90cc5096f8 100755
--- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages.properties
+++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages.properties
@@ -151,4 +151,5 @@ moveAllApplicationProcessesAwayFromMaster=Move all application processes away fr
sameAsExistingHost=Same as existing host
moveTheFollowingMasterAndReplicaProcessesAway=Moving master processes [{1}] and replica processes [{2}] from host with ID {0} to a new host.
processOfReplicaSet=on port {0} (application replica set {1})
-successfullyMovedAllProcessesAwayFromHost=Successfully moved all processes away from host {0}
\ No newline at end of file
+successfullyMovedAllProcessesAwayFromHost=Successfully moved all processes away from host {0}
+dnsNameAlreadyInUse=DNS name already in use
\ No newline at end of file
diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_cs.properties b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_cs.properties
index bd38a8bd0e8..33b901c6ed8 100644
--- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_cs.properties
+++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_cs.properties
@@ -147,3 +147,8 @@ shardCreatedSuccessfully=Horizontální oddíl {0} byl úspěšně vytvořen.
deletedShard=Horizontální oddíl {0} byl odstraněn.
errorFetchingLeaderboardNames=Chyba při načítání názvů výsledkových tabulí: {0}
shardingDescription=Vyberte několik výsledkových tabulí (případně žádnou), které dosud nejsou v horizontálním oddílu, poté kliknutím na „Přidat horizontální oddíl“ vytvořte nový horizontální oddíl, který bude pracovat s vybranými výsledkovými tabulemi.\nPomocí tlačítek se šipkami do vybraného horizontálního oddílu přidejte nebo z něj odeberte výsledkové tabule.\nUpozorňujeme, že změny se provedou okamžitě, nikoliv až po zavření tohoto dialogového okna.
+moveAllApplicationProcessesAwayFromMaster=Přesunout všechny aplikační procesy z tohoto hlavního hostitele sady replik do nového hostitele
+sameAsExistingHost=Stejně jako existující hostitel
+moveTheFollowingMasterAndReplicaProcessesAway=Přesunování hlavních procesů [{1}] a procesů replik [{2}] z hostitele s ID {0} do nového hostitele.
+processOfReplicaSet=na portu {0} (aplikační sada replik {1})
+successfullyMovedAllProcessesAwayFromHost=Všechny procesy byly úspěšně přesunuty z hostitele {0}
diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_da.properties b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_da.properties
index 739dae6ac93..fc1bbe3f4bc 100644
--- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_da.properties
+++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_da.properties
@@ -147,3 +147,8 @@ shardCreatedSuccessfully=Shard "{0}" blev oprettet
deletedShard=Slettede shard "{0}"
errorFetchingLeaderboardNames=Fejl ved hentning af ranglistenavne: {0}
shardingDescription=Vælg nul eller flere ranglister, der endnu ikke er i en shard, og klik derefter på "Tilføj shard" for at oprette en ny shard, der håndterer de valgte ranglister.\nBrug piletasterne til at tilføje ranglister til eller fjerne dem fra en valgt shard.\nBemærk, at ændringerne udføres med det samme, ikke når du lukker denne dialogboks.
+moveAllApplicationProcessesAwayFromMaster=Flyt alle applikationsprocesser væk fra dette replikasæts overordnede vært til en ny vært
+sameAsExistingHost=Samme som eksisterende vært
+moveTheFollowingMasterAndReplicaProcessesAway=Flytter overordnede processer [{1}] og replikaprocesser [{2}] fra vært med ID {0} til en ny vært.
+processOfReplicaSet=på port {0} (applikationsreplikasæt {1})
+successfullyMovedAllProcessesAwayFromHost=Alle processer blev flyttet væk fra vært {0} uden fejl
diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_de.properties b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_de.properties
index 0e960411fa7..6e80bc3ec0a 100755
--- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_de.properties
+++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_de.properties
@@ -150,4 +150,5 @@ moveAllApplicationProcessesAwayFromMaster=Alle Anwendungs-Prozesse vom Master-Se
sameAsExistingHost=Gleich wie beim bestehenden Server
moveTheFollowingMasterAndReplicaProcessesAway=Verschieben der Master-Prozesse [{1}] und Replika-Prozesse [{2}] vom Server mit der Kennung {0} auf einen neuen Server
processOfReplicaSet=auf Port {0} (Anwendungs-Cluster {1})
-successfullyMovedAllProcessesAwayFromHost=Alle Prozesse erfolgreich von Server {0} verschoben
\ No newline at end of file
+successfullyMovedAllProcessesAwayFromHost=Alle Prozesse erfolgreich von Server {0} verschoben
+dnsNameAlreadyInUse=DNS-Name wird bereits benutzt
\ No newline at end of file
diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_es.properties b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_es.properties
index 85842b5e7c7..33046de1e01 100644
--- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_es.properties
+++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_es.properties
@@ -147,3 +147,8 @@ shardCreatedSuccessfully=Partición "{0}" creada correctamente
deletedShard=Partición eliminada "{0}"
errorFetchingLeaderboardNames=Error al obtener los nombres de la tabla de clasificación: {0}
shardingDescription=Seleccione cero o más tablas de clasificación que todavía no estén en una partición; a continuación, haga clic en "Añadir partición" para crear una nueva partición que gestione las tablas de clasificación seleccionadas.\nUse los botones de flecha para añadir o quitar tablas de clasificación de una partición seleccionada.\nTenga en cuenta que los cambios se realizan inmediatamente, no cuando cierra este cuadro de diálogo.
+moveAllApplicationProcessesAwayFromMaster=Mover todos los procesos de aplicación fuera del host principal de este conjunto de réplicas a otro host nuevo.
+sameAsExistingHost=Igual que el host existente
+moveTheFollowingMasterAndReplicaProcessesAway=Movimiento de procesos principales [{1}] y procesos de réplica [{2}] del host con ID {0} a un host nuevo.
+processOfReplicaSet=en el puerto {0} (conjunto de réplicas de aplicación {1})
+successfullyMovedAllProcessesAwayFromHost=Todos los procesos movidos correctamente fuera del host {0}
diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_fr.properties b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_fr.properties
index 914c9a7b87e..849c8642df9 100644
--- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_fr.properties
+++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_fr.properties
@@ -11,7 +11,7 @@ creationTime=Heure de création
sshKeys=Clés SSH
publicKey=Clé publique
privateKey=Clé privée
-pleaseProvideKeyPairName=Indiquez un nom de paire de clés.
+pleaseProvideKeyPairName=Indiquez un nom de paires de clés.
pleaseProvidePublicKey=Indiquez une clé publique.
pleaseProvidePrivateKey=Indiquez une clé privée.
generate=Générer
@@ -147,3 +147,8 @@ shardCreatedSuccessfully=Éclat "{0}" correctement créé
deletedShard=Supprimer l''éclat "{0}"
errorFetchingLeaderboardNames=Erreur lors de l''accès aux noms de palmarès : {0}
shardingDescription=Sélectionnez un ou plusieurs palmarès qui ne sont pas encore dans un éclat ou n''en sélectionnez aucun, puis cliquez sur "Ajouter un éclat" pour créer un éclat traitant les palmarès sélectionnés.\nUtilisez les flèches pour ajouter des palmarès ou les supprimer d''un éclat sélectionné.\nNotez que les modifications sont appliquées immédiatement, pas quand vous fermez la boîte de dialogue.
+moveAllApplicationProcessesAwayFromMaster=Déplacer tous les processus d''application de l''hôte principal de ce groupe de réplicas vers un nouvel hôte
+sameAsExistingHost=Identique à l''hôte existant
+moveTheFollowingMasterAndReplicaProcessesAway=Déplacement des processus principaux [{1}] et des processus de réplicas [{2}) de l''hôte avec l''ID {0} vers un nouvel hôte.
+processOfReplicaSet=sur le port {0} (ensemble de réplicas d''application {1})
+successfullyMovedAllProcessesAwayFromHost=Processus correctement déplacés depuis l''hôte {0}
diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_it.properties b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_it.properties
index 32f21c7ef13..9fff6b6c9af 100644
--- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_it.properties
+++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_it.properties
@@ -120,7 +120,7 @@ switchToAutoScalingReplicasOnly=Passare solo a repliche di messa in scala automa
problemSwitchingReplicaSetToAutoReplicasOnly=Problema nel cambio del set di replica dell''applicazione {0} a sole repliche di messa in scala automatica: {1}
successfullySwitchedReplicaSetToAutoReplicasOnly=Cambio corretto del set di replica dell''applicazione {0} a sole repliche di messa in scala automatica.
switchToReplicaOnSharedInstance=Passaggio alla replica nell''istanza condivisa
-moveMasterToOtherInstance=Spostare il processo principale ad altra istanza
+moveMasterToOtherInstance=Sposta il processo principale ad altra istanza
successfullyMovedMasterOfReplicaSet=Processo principale del set di replica {0} spostato correttamente
successfullyRemovedApplicationReplicaSet=Set di replica {0} rimosso correttamente
scaleAutoScalingReplicasUpOrDown=Ingrandisci/riduci repliche di messa in scala automatica
@@ -147,3 +147,8 @@ shardCreatedSuccessfully=Partizione "{0}" creata correttamente
deletedShard=Partizione "{0}" eliminata
errorFetchingLeaderboardNames=Errore nel recupero dei nomi classifica: {0}
shardingDescription=Selezionare zero o più classifiche non ancora comprese in una partizione, quindi fare clic su "Aggiungi partizione" per creare una nuova partizione per la gestione delle classifiche selezionate.\nUtilizzare i pulsanti freccia per aggiungere o rimuovere classifiche a/da una partizione selezionata.\nNotare che le modifiche vengono apportate immediatamente e non alla chiusura della finestra di dialogo.
+moveAllApplicationProcessesAwayFromMaster=Sposta tutti i processi dell''applicazione da questo host principale del set di replica a un nuovo host
+sameAsExistingHost=Uguale all''host esistente
+moveTheFollowingMasterAndReplicaProcessesAway=Spostamento in corso dei processi principali [{1}] e dei processi di replica [{2}] dall''host con ID {0} a un nuovo host.
+processOfReplicaSet=sulla porta {0} (set di replica dell''applicazione {1})
+successfullyMovedAllProcessesAwayFromHost=Spostamento di tutti i processi dall''host {0} avvenuto correttamente
diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_ja.properties b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_ja.properties
index 58de18cac08..944adb736c3 100644
--- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_ja.properties
+++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_ja.properties
@@ -147,3 +147,8 @@ shardCreatedSuccessfully=シャード "{0}" が作成されました
deletedShard=シャード "{0}" が削除されました
errorFetchingLeaderboardNames=リーダーボード名のフェッチでエラーが発生: {0}
shardingDescription=シャードにまだない 0 以上のリーダーボードを選択してから、"シャードの追加" をクリックして選択済みのリーダーボードを処理する新しいシャードを作成してください。\n矢印ボタンを使用して、リーダーボードを追加するか、選択済みのシャードからリーダーボードを削除してください。\n変更は、このダイアログを終了するときではなく、ただちに実行されることに注意してください。
+moveAllApplicationProcessesAwayFromMaster=この複製セットのマスタホストから新しいホストにすべてのアプリケーションプロセスを移動
+sameAsExistingHost=既存ホストと同じ
+moveTheFollowingMasterAndReplicaProcessesAway=マスタプロセス [{1}] および複製プロセス [{2}] を ID {0} のホストから新しいホストに移動。
+processOfReplicaSet=ポート {0} (アプリケーション複製セット {1}) 上
+successfullyMovedAllProcessesAwayFromHost=すべてのプロセスがホスト {0} から移動しました
diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_pt.properties b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_pt.properties
index d87ea8404cb..69902597862 100644
--- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_pt.properties
+++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_pt.properties
@@ -147,3 +147,8 @@ shardCreatedSuccessfully=Fração "{0}" criada com êxito
deletedShard=Fração "{0}" eliminada
errorFetchingLeaderboardNames=Erro ao chamar nomes de painel de classificação: {0}
shardingDescription=Selecione zero ou mais painéis de classificação que ainda não estejam em uma fração e clique em "Adicionar fração" para criar uma nova fração para processar os painéis de classificação selecionados.\nUtilize os botões de seta para adicionar painéis de classificação a ou remover painéis de classificação de uma fração selecionada.\nConsidere que as modificações são executadas imediatamente e não quando você fecha este diálogo.
+moveAllApplicationProcessesAwayFromMaster=Mova todos os processos de aplicação do host mestre deste conjunto de réplicas para um novo host.
+sameAsExistingHost=Igual ao host existente
+moveTheFollowingMasterAndReplicaProcessesAway=Movendo processos mestre [{1}] e processos replicados [{2}] do host com o ID {0} para um novo host.
+processOfReplicaSet=na porta {0} (conjunto de réplicas de aplicação {1})
+successfullyMovedAllProcessesAwayFromHost=Todos os processos movidos com êxito do host {0}
diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_ru.properties b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_ru.properties
index 444b389146c..c8ac21a4c0d 100644
--- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_ru.properties
+++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_ru.properties
@@ -147,3 +147,8 @@ shardCreatedSuccessfully=Шард "{0}" создан
deletedShard=Шард "{0}" удален
errorFetchingLeaderboardNames=Ошибка при получении имен таблиц лидеров: {0}
shardingDescription=Выберите ноль или больше таблиц лидеров, которые еще не добавлены в шард, затем щелкните "Добавить шард", чтобы создать новый шард для обработки выбранных таблиц лидеров.\nИспользуйте кнопки со стрелками, чтобы добавить таблицы лидеров или удалить их из выбранного шарда.\nОбратите внимание, что изменения выполняются немедленно, а не при закрытии этого диалогового окна.
+moveAllApplicationProcessesAwayFromMaster=Переместить все процессы приложения с основного хоста этого набора реплик на новый хост
+sameAsExistingHost=Совпадает с существующим хостом
+moveTheFollowingMasterAndReplicaProcessesAway=Перемещение основных процессов [{1}] и процессов реплик [{2}] с хоста с ид. {0} но новый хост.
+processOfReplicaSet=на порт {0} (набор реплик приложений {1})
+successfullyMovedAllProcessesAwayFromHost=Все процессы успешно перемещены с хоста {0}
diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_sl.properties b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_sl.properties
index 1752dcef797..540ac088125 100644
--- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_sl.properties
+++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_sl.properties
@@ -147,3 +147,8 @@ shardCreatedSuccessfully=Del podatkov "{0}" uspešno kreiran
deletedShard=Izbrisani del podatkov "{0}"
errorFetchingLeaderboardNames=Napaka pri priklicu imen lestvice vodilnih: {0}
shardingDescription=Izberite nič ali več lestvic vodilnih, ki še niso vključene v del podatkov, nato kliknite "Dodaj del podatkov", da ustvarite nov del podatkov, ki bo obdeloval izbrane lestvice vodilnih.\nZ uporabo gumbov s puščicami dodajte lestvice vodilnih izbranemu delu podatkov ali jih iz njega odstranite.\nUpoštevajte, da se spremembe izvedejo takoj in ne, ko zaprete to pogovorno okno.
+moveAllApplicationProcessesAwayFromMaster=Premaknite vse aplikacijski procese iz tega glavnega gostitelja niza replik v novega gostitelja
+sameAsExistingHost=Enako kot obstoječi gostitelj
+moveTheFollowingMasterAndReplicaProcessesAway=Premik glavnih procesov [{1}] in procesov replike [{2}] iz gostitelja z ID-jem {0} v novega gostitelja.
+processOfReplicaSet=vrata {0} (niz replik aplikacije {1})
+successfullyMovedAllProcessesAwayFromHost=Vsi procesi uspešno premaknjeni iz gostitelja {0}
diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_zh.properties b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_zh.properties
index 6a21434d053..6a01778923a 100644
--- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_zh.properties
+++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages_zh.properties
@@ -147,3 +147,8 @@ shardCreatedSuccessfully=分片 "{0}" 已成功创建
deletedShard=删除分片 "{0}"
errorFetchingLeaderboardNames=获取积分榜名称出错:{0}
shardingDescription=选择零个或多个尚未在分片中的积分榜,然后点击“添加分片”,创建处理所选积分榜的新分片。\n使用箭头按钮将积分榜添加到所选分片或从中移除。\n请注意,会立即执行更改,而不是在您关闭此对话框时执行。
+moveAllApplicationProcessesAwayFromMaster=将所有应用程序流程从此复本集的主主机移到一个新主机上
+sameAsExistingHost=与现有主机相同
+moveTheFollowingMasterAndReplicaProcessesAway=将主流程 [{1}] 和复本流程 [{2}] 从具有编号 {0} 的主机移动到新主机。
+processOfReplicaSet=在端口 {0} 上(应用程序复本集 {1})
+successfullyMovedAllProcessesAwayFromHost=已成功将所有流程移离主机 {0}
diff --git a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/LandscapeManagementWriteServiceImpl.java b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/LandscapeManagementWriteServiceImpl.java
index e140fe7f39f..b2816c3ac22 100755
--- a/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/LandscapeManagementWriteServiceImpl.java
+++ b/java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/server/LandscapeManagementWriteServiceImpl.java
@@ -110,6 +110,7 @@ import com.sap.sse.util.ThreadPoolUtil;
import software.amazon.awssdk.services.ec2.model.AvailabilityZone;
import software.amazon.awssdk.services.ec2.model.InstanceType;
import software.amazon.awssdk.services.ec2.model.KeyPairInfo;
+import software.amazon.awssdk.services.route53.model.ResourceRecordSet;
public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRemoteServiceServlet
implements LandscapeManagementWriteService {
@@ -950,4 +951,14 @@ public class LandscapeManagementWriteServiceImpl extends ResultCachingProxiedRem
: InstanceType.valueOf(optionalInstanceTypeForNewInstance)),
optionalKeyName, privateKeyEncryptionPassphrase);
}
+
+ @Override
+ public boolean hasDNSResourceRecordsForReplicaSet(String replicaSetName, String optionalDomainName) {
+ final AwsLandscape landscape = getLandscape();
+ final LandscapeService landscapeService = getLandscapeService();
+ final String hostname = landscapeService.getHostname(replicaSetName, optionalDomainName);
+ final Iterable existingDNSRulesForHostname = landscape.getResourceRecordSets(hostname);
+ // Failing early in case DNS record already exists (see also bug 5826):
+ return existingDNSRulesForHostname != null && !Util.isEmpty(existingDNSRulesForHostname);
+ }
}
diff --git a/java/com.sap.sailing.landscape/META-INF/MANIFEST.MF b/java/com.sap.sailing.landscape/META-INF/MANIFEST.MF
index 056a93781bb..8a6fcd31966 100755
--- a/java/com.sap.sailing.landscape/META-INF/MANIFEST.MF
+++ b/java/com.sap.sailing.landscape/META-INF/MANIFEST.MF
@@ -9,7 +9,8 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: com.sap.sse.landscape,
com.sap.sse.landscape.aws,
com.sap.sse.common,
- com.jcraft.jsch;bundle-version="0.1.54",
+ com.github.mwiede.jsch;bundle-version="0.2.8",
+ bcprov-ext;bundle-version="1.72.0",
com.amazon.aws.aws-java-api;bundle-version="2.14.24",
com.sap.sse.shared.android,
org.apache.httpcomponents.httpcore;bundle-version="4.4.0",
diff --git a/java/com.sap.sailing.landscape/src/com/sap/sailing/landscape/LandscapeService.java b/java/com.sap.sailing.landscape/src/com/sap/sailing/landscape/LandscapeService.java
index 4c0b7a836f1..051ae404489 100644
--- a/java/com.sap.sailing.landscape/src/com/sap/sailing/landscape/LandscapeService.java
+++ b/java/com.sap.sailing.landscape/src/com/sap/sailing/landscape/LandscapeService.java
@@ -449,4 +449,6 @@ public interface LandscapeService {
moveAllApplicationProcessesAwayFrom(SailingAnalyticsHost host,
Optional optionalInstanceTypeForNewInstance,
String optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception;
+
+ String getHostname(String replicaSetName, String optionalDomainName);
}
diff --git a/java/com.sap.sailing.landscape/src/com/sap/sailing/landscape/impl/LandscapeServiceImpl.java b/java/com.sap.sailing.landscape/src/com/sap/sailing/landscape/impl/LandscapeServiceImpl.java
index 4e941d4e9c3..4cac7af7bb1 100644
--- a/java/com.sap.sailing.landscape/src/com/sap/sailing/landscape/impl/LandscapeServiceImpl.java
+++ b/java/com.sap.sailing.landscape/src/com/sap/sailing/landscape/impl/LandscapeServiceImpl.java
@@ -127,6 +127,7 @@ import software.amazon.awssdk.services.elasticloadbalancingv2.model.Listener;
import software.amazon.awssdk.services.elasticloadbalancingv2.model.Rule;
import software.amazon.awssdk.services.elasticloadbalancingv2.model.TargetHealthDescription;
import software.amazon.awssdk.services.route53.model.RRType;
+import software.amazon.awssdk.services.route53.model.ResourceRecordSet;
import software.amazon.awssdk.services.sts.model.Credentials;
public class LandscapeServiceImpl implements LandscapeService {
@@ -168,6 +169,12 @@ public class LandscapeServiceImpl implements LandscapeService {
Integer optionalMemoryTotalSizeFactorOrNull, Optional minimumAutoScalingGroupSize,
Optional maximumAutoScalingGroupSize) throws Exception {
final AwsLandscape landscape = getLandscape();
+ final String hostname = getHostname(name, optionalDomainName);
+ final Iterable existingDNSRulesForHostname = landscape.getResourceRecordSets(hostname);
+ // Failing early in case DNS record already exists (see also bug 5826):
+ if (existingDNSRulesForHostname != null && !Util.isEmpty(existingDNSRulesForHostname)) {
+ throw new IllegalArgumentException("DNS record for "+hostname+" already exists");
+ }
final AwsRegion region = new AwsRegion(regionId, landscape);
final Release release = getRelease(releaseNameOrNullForLatestMaster);
final com.sap.sailing.landscape.procedures.SailingAnalyticsMasterConfiguration.Builder, String> masterConfigurationBuilder =
@@ -217,7 +224,6 @@ public class LandscapeServiceImpl implements LandscapeService {
});
// if an unmanaged replica process was launched, return a replica set that contains it; otherwise use the one we already have (without any replica)
return unmanagedReplica.map(ur->{
-
try {
return getLandscape().getApplicationReplicaSet(region, name, master, Collections.singleton(ur));
} catch (InterruptedException | ExecutionException | TimeoutException e) {
@@ -318,6 +324,12 @@ public class LandscapeServiceImpl implements LandscapeService {
Integer optionalMemoryTotalSizeFactorOrNull, Optional optionalInstanceType,
Optional> optionalPreferredInstanceToDeployTo) throws Exception {
final AwsLandscape landscape = getLandscape();
+ final String hostname = getHostname(replicaSetName, optionalDomainName);
+ final Iterable existingDNSRulesForHostname = landscape.getResourceRecordSets(hostname);
+ // Failing early in case DNS record already exists (see also bug 5826):
+ if (existingDNSRulesForHostname != null && !Util.isEmpty(existingDNSRulesForHostname)) {
+ throw new IllegalArgumentException("DNS record for "+hostname+" already exists");
+ }
final Release release = getRelease(releaseNameOrNullForLatestMaster);
final AppConfigBuilderT masterConfigurationBuilder = createMasterConfigurationBuilder(replicaSetName,
masterReplicationBearerToken, optionalMemoryInMegabytesOrNull, optionalMemoryTotalSizeFactorOrNull,
@@ -834,8 +846,7 @@ public class LandscapeServiceImpl implements LandscapeService {
}
final CreateLoadBalancerMapping.Builder, ?, String, SailingAnalyticsMetrics, SailingAnalyticsProcess> createLoadBalancerMappingBuilder =
dynamicLoadBalancerMapping ? CreateDynamicLoadBalancerMapping.builder() : CreateDNSBasedLoadBalancerMapping.builder();
- final String domainName = Optional.ofNullable(optionalDomainName).orElse(SharedLandscapeConstants.DEFAULT_DOMAIN_NAME);
- final String masterHostname = replicaSetName+"."+domainName;
+ final String masterHostname = getHostname(replicaSetName, optionalDomainName);
final CreateLoadBalancerMapping> createLoadBalancerMapping = createLoadBalancerMappingBuilder
.setProcess(master)
.setHostname(masterHostname)
@@ -885,6 +896,13 @@ public class LandscapeServiceImpl implements LandscapeService {
return applicationReplicaSet;
}
+ @Override
+ public String getHostname(String replicaSetName, String optionalDomainName) {
+ final String domainName = Optional.ofNullable(optionalDomainName).orElse(SharedLandscapeConstants.DEFAULT_DOMAIN_NAME);
+ final String masterHostname = replicaSetName+"."+domainName;
+ return masterHostname;
+ }
+
@Override
public AwsApplicationReplicaSet> upgradeApplicationReplicaSet(AwsRegion region,
AwsApplicationReplicaSet> replicaSet,
@@ -1081,7 +1099,7 @@ public class LandscapeServiceImpl implements LandscapeService {
// old replica was on a shared instance; in this case we'll over-provision, but it won't be long.
replicaConfigurationBuilder
.setInboundReplicationConfiguration(InboundReplicationConfiguration.builder()
- .setMasterHostname(master.getHost().getPrivateAddress().getHostName())
+ .setMasterHostname(master.getHost().getPrivateAddress().getHostAddress())
.setMasterHttpPort(master.getPort())
.setCredentials(new BearerTokenReplicationCredentials(replicationBearerToken))
.build());
@@ -1096,6 +1114,7 @@ public class LandscapeServiceImpl implements LandscapeService {
.setLandscape(getLandscape())
.setRegion(region)
.setTags(Tags.with(UPGRADE_REPLICA_TAG_KEY, replicaSet.getName()));
+ optionalKeyName.ifPresent(replicaHostBuilder::setKeyName);
final StartSailingAnalyticsReplicaHost replicaHostStartProcedure = replicaHostBuilder.build();
logger.info("Launching dedicated replica host of type "+instanceType+" for replica "+replica);
replicaHostStartProcedure.run();
diff --git a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/LeaderboardsResourceV2.java b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/LeaderboardsResourceV2.java
index a5bc0fd76f8..829d989173e 100644
--- a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/LeaderboardsResourceV2.java
+++ b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/LeaderboardsResourceV2.java
@@ -320,6 +320,7 @@ public class LeaderboardsResourceV2 extends AbstractLeaderboardsResource {
DetailType.LEG_WINDWARD_DISTANCE_TO_GO_IN_METERS,
DetailType.LEG_CURRENT_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS,
DetailType.LEG_CURRENT_SIGNED_CROSS_TRACK_ERROR_IN_METERS,
+ DetailType.LEG_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS,
DetailType.OVERALL_TIME_ON_TIME_FACTOR,
DetailType.OVERALL_TIME_ON_DISTANCE_ALLOWANCE_IN_SECONDS_PER_NAUTICAL_MILE };
}
@@ -463,6 +464,12 @@ public class LeaderboardsResourceV2 extends AbstractLeaderboardsResource {
value = currentLegEntry.currentOrAverageSignedCrossTrackErrorInMeters;
}
break;
+ case LEG_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS:
+ name = "currentLegAverageSpeedOverGround-kts";
+ if (currentLegEntry != null && currentLegEntry.averageSpeedOverGroundInKnots != null) {
+ value = currentLegEntry.averageSpeedOverGroundInKnots;
+ }
+ break;
case OVERALL_TIME_ON_TIME_FACTOR:
name = CompetitorJsonConstants.FIELD_TIME_ON_TIME_FACTOR;
value = leaderboardRowDTO.effectiveTimeOnTimeFactor;
diff --git a/java/com.sap.sailing.server.gateway/webservices/api/v2/leaderboardGetDoc.html b/java/com.sap.sailing.server.gateway/webservices/api/v2/leaderboardGetDoc.html
index 41912c72d64..d545f37367e 100644
--- a/java/com.sap.sailing.server.gateway/webservices/api/v2/leaderboardGetDoc.html
+++ b/java/com.sap.sailing.server.gateway/webservices/api/v2/leaderboardGetDoc.html
@@ -31,6 +31,7 @@ The supported race detail constants right now are:
- LEG_WINDWARD_DISTANCE_TO_GO_IN_METERS
- LEG_CURRENT_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS
- LEG_CURRENT_SIGNED_CROSS_TRACK_ERROR_IN_METERS
+- LEG_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS
- OVERALL_MAXIMUM_SPEED_OVER_GROUND_IN_KNOTS
- OVERALL_TIME_ON_TIME_FACTOR
- OVERALL_TIME_ON_DISTANCE_ALLOWANCE_IN_SECONDS_PER_NAUTICAL_MILE
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch b/java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch
index 3b8b4ce74e6..766c8027994 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch
@@ -1,32 +1,33 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -149,7 +150,9 @@
-
+
+
+
@@ -197,7 +200,7 @@
-
+
@@ -311,8 +314,8 @@
-
-
-
-
+
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy).launch b/java/com.sap.sailing.server/SailingServer (No Proxy).launch
index 8c7d1d0d434..b5bf004ac43 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy).launch
@@ -34,286 +34,292 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Axel).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Axel).launch
index d77cbc5f4d6..dd4deb00dd6 100644
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Axel).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Axel).launch
@@ -151,7 +151,9 @@
-
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch
index 03b521aef62..62026ef9857 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch
@@ -148,7 +148,9 @@
-
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Igtimi Local Test).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Igtimi Local Test).launch
index a7b65db500c..0507d144ab3 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Igtimi Local Test).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Igtimi Local Test).launch
@@ -151,7 +151,9 @@
-
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Java11 GENERATED).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Java11 GENERATED).launch
index 89faf34e630..00226cc8a2c 100644
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Java11 GENERATED).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Java11 GENERATED).launch
@@ -151,7 +151,9 @@
-
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Java11).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Java11).launch
index 2e33c80f519..10922cfa3e2 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Java11).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Java11).launch
@@ -153,7 +153,9 @@
-
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Java11, JFR Recording).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Java11, JFR Recording).launch
index 50bf524c9df..c17102a4293 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Java11, JFR Recording).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Java11, JFR Recording).launch
@@ -151,7 +151,9 @@
-
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889).launch
index 653fe982b8c..ea2c1f95cef 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889).launch
@@ -146,7 +146,9 @@
-
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch
index 391bd078d07..c3040ae44a6 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch
@@ -142,7 +142,9 @@
-
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate SS and SSD).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate SS and SSD).launch
index 2e6061b4df4..3e825d03f0d 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate SS and SSD).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate SS and SSD).launch
@@ -27,286 +27,292 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate dev).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate dev).launch
index a29496ab5b3..2dd3eb6eb34 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate dev).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate dev).launch
@@ -25,286 +25,292 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate).launch
index dbfb301e40a..d6c5e9855c6 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate).launch
@@ -148,7 +148,9 @@
-
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8890).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8890).launch
index 11fc4ab0880..37dbda47910 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8890).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8890).launch
@@ -146,7 +146,9 @@
-
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8890, auto-replicate from replica at 8889).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8890, auto-replicate from replica at 8889).launch
index 4228bdacbc7..fc93c6b4744 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8890, auto-replicate from replica at 8889).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8890, auto-replicate from replica at 8889).launch
@@ -146,7 +146,9 @@
-
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch
index eb10ccb7f94..e6e712a75ce 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch
@@ -142,7 +142,9 @@
-
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, debranding active).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, debranding active).launch
index 4d5dfabd471..7fd56d6bd37 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, debranding active).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, debranding active).launch
@@ -151,7 +151,9 @@
-
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, winddb Axel).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, winddb Axel).launch
index 31f6c1ebe52..2c9cd966b0b 100644
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, winddb Axel).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, winddb Axel).launch
@@ -148,7 +148,9 @@
-
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest Axel).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest Axel).launch
index 0658d22922a..b3aad4313dc 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest Axel).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest Axel).launch
@@ -148,7 +148,9 @@
-
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch
index e73430658da..6d24d6573b3 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch
@@ -154,7 +154,9 @@
-
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (Proxy, Jetty on 8889, Polar & Wind estimation Import from 8888).launch b/java/com.sap.sailing.server/SailingServer (Proxy, Jetty on 8889, Polar & Wind estimation Import from 8888).launch
index 32fdef14fd9..d36aa425d68 100755
--- a/java/com.sap.sailing.server/SailingServer (Proxy, Jetty on 8889, Polar & Wind estimation Import from 8888).launch
+++ b/java/com.sap.sailing.server/SailingServer (Proxy, Jetty on 8889, Polar & Wind estimation Import from 8888).launch
@@ -146,7 +146,9 @@
-
+
+
+
diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java
index 7d7412cdd72..4b358889322 100644
--- a/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java
+++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java
@@ -4748,7 +4748,7 @@ Replicator {
public Map getLocalStatisticsByYear() {
final Map calculators = new HashMap<>();
getAllEvents().forEach((event) -> {
- if (getSecurityService().hasCurrentUserReadPermission(event)) {
+ if (getSecurityService().hasCurrentUserReadPermission(event) && event.isPublic()) {
final Integer eventYear = EventUtil.getYearOfEvent(event);
// The year may be null if the event has no start date set
// In this case the event is ignored for the yearly
diff --git a/java/com.sap.sailing.targetplatform.base/features/target-base/feature.xml b/java/com.sap.sailing.targetplatform.base/features/target-base/feature.xml
index f125000f9f6..8179e51e4b9 100755
--- a/java/com.sap.sailing.targetplatform.base/features/target-base/feature.xml
+++ b/java/com.sap.sailing.targetplatform.base/features/target-base/feature.xml
@@ -347,5 +347,26 @@
install-size="0"
version="1.2.1"
unpack="false"/>
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.targetplatform.base/plugins/target-base/bcprov-ext-jdk18on-172.jar b/java/com.sap.sailing.targetplatform.base/plugins/target-base/bcprov-ext-jdk18on-172.jar
new file mode 100644
index 00000000000..6385272118d
Binary files /dev/null and b/java/com.sap.sailing.targetplatform.base/plugins/target-base/bcprov-ext-jdk18on-172.jar differ
diff --git a/java/com.sap.sailing.targetplatform.base/plugins/target-base/jsch-0.2.8-sources.jar b/java/com.sap.sailing.targetplatform.base/plugins/target-base/jsch-0.2.8-sources.jar
new file mode 100644
index 00000000000..dd78549c545
Binary files /dev/null and b/java/com.sap.sailing.targetplatform.base/plugins/target-base/jsch-0.2.8-sources.jar differ
diff --git a/java/com.sap.sailing.targetplatform.base/plugins/target-base/jsch-0.2.8.jar b/java/com.sap.sailing.targetplatform.base/plugins/target-base/jsch-0.2.8.jar
new file mode 100644
index 00000000000..5a52c05919c
Binary files /dev/null and b/java/com.sap.sailing.targetplatform.base/plugins/target-base/jsch-0.2.8.jar differ
diff --git a/java/com.sap.sailing.targetplatform/definitions/race-analysis-p2-remote.target b/java/com.sap.sailing.targetplatform/definitions/race-analysis-p2-remote.target
index b7a7b22f2bd..b7ee608ab51 100755
--- a/java/com.sap.sailing.targetplatform/definitions/race-analysis-p2-remote.target
+++ b/java/com.sap.sailing.targetplatform/definitions/race-analysis-p2-remote.target
@@ -1,6 +1,6 @@
-
+
@@ -84,8 +84,6 @@
-
-
@@ -329,8 +327,9 @@
-
-
+
+
+
diff --git a/java/com.sap.sailing.www/release_notes_admin.html b/java/com.sap.sailing.www/release_notes_admin.html
index eba5cf127d6..34e29a412f7 100755
--- a/java/com.sap.sailing.www/release_notes_admin.html
+++ b/java/com.sap.sailing.www/release_notes_admin.html
@@ -44,6 +44,20 @@
will open an AWS console, showing the instances launched off that AMI. This way it becomes easy to see
which instances are using which of the managed AMIs.
+ - SSH keys produced with new versions of OpenSSH as well as the highly secure ED25519 keys are now supported
+ for AWS landscape management. This removes the requirement to convert new OpenSSH keys to PEM format before
+ starting to work with them.
+
+ - For the DNS name resulting from a new replica set name and an optional domain name or the default domain name
+ (sapsailing.com) it is now checked that this name is not taken yet. An error message will be shown
+ otherwise.
+
+ - Sorting of replica-set table by name is now case-insensitive.
+ - Bug fix: when working cross-region with the Landscape panel, temporary upgrade replicas were identified
+ trying to obtain their host name from their IP address. When this is attempted, however, for an IP address
+ identifying a host in one region and the host name is determined from within another region then the
+ internal DNS name chosen is that of the other region and therefore incorrect. Instead, now the IP address's
+ numeric representation is used instead.
February 2023
diff --git a/java/com.sap.sse.feature.runtime/feature.xml b/java/com.sap.sse.feature.runtime/feature.xml
index 3e67cfc702f..8e8c975c240 100644
--- a/java/com.sap.sse.feature.runtime/feature.xml
+++ b/java/com.sap.sse.feature.runtime/feature.xml
@@ -716,11 +716,26 @@
version="2.9.0"
unpack="false"/>
+
+
+
+
+
{
private final FlowPanel rightButtonPanel;
private final FlowPanel leftButtonPanel;
private final AsyncActionsExecutor validationExecutor;
- private static final String VALIDATION_ACTION_CATEGORY = "validation";
+ protected static final String VALIDATION_ACTION_CATEGORY = "validation";
private boolean dialogInInvalidState = false;
diff --git a/java/com.sap.sse.landscape.aws.test/src/com/sap/sse/landscape/aws/ConnectivityTest.java b/java/com.sap.sse.landscape.aws.test/src/com/sap/sse/landscape/aws/ConnectivityTest.java
index fc71db190ed..ee9ba697c5d 100755
--- a/java/com.sap.sse.landscape.aws.test/src/com/sap/sse/landscape/aws/ConnectivityTest.java
+++ b/java/com.sap.sse.landscape.aws.test/src/com/sap/sse/landscape/aws/ConnectivityTest.java
@@ -87,12 +87,12 @@ import software.amazon.awssdk.services.sts.model.Credentials;
*/
public class ConnectivityTest> {
private static final Logger logger = Logger.getLogger(ConnectivityTest.class.getName());
- private static final Optional optionalTimeout = Optional.of(Duration.ONE_MINUTE.times(5));
+ private static final Optional optionalTimeout = Optional.of(Duration.ONE_MINUTE.times(10));
private static AwsLandscape landscape;
private static AwsRegion region;
private static byte[] keyPass;
private static String AXELS_KEY_PASS;
- private static final String AXELS_KEY_NAME = "Axel";
+ private static final String AXELS_KEY_NAME = "Axel_ed25519";
private static final String pathPrefixForShardingKey = "/sse/landscape/test";
@BeforeClass
@@ -193,7 +193,7 @@ public class ConnectivityTest proxy = landscape.getCentralReverseProxy(region);
final String hostname = "kw2021.sapsailing.com";
final AwsInstance proxyHost = proxy.getHosts().iterator().next();
- final ProcessT process = createApplicationProcess(proxyHost);
- proxy.setEventRedirect(hostname, process, UUID.randomUUID(), /* optional SSH key name */ Optional.empty(), AXELS_KEY_PASS.getBytes());
+ final ProcessT process = createApplicationProcess(proxyHost, "testtest");
+ proxy.setEventRedirect(hostname, process, UUID.randomUUID(), Optional.of(AXELS_KEY_NAME), AXELS_KEY_PASS.getBytes());
final ByteArrayOutputStream configFileContents = new ByteArrayOutputStream();
- final ChannelSftp sftpChannel = proxyHost.createRootSftpChannel(optionalTimeout, /* optional SSH key name */ Optional.empty(), AXELS_KEY_PASS.getBytes());
+ final ChannelSftp sftpChannel = proxyHost.createRootSftpChannel(optionalTimeout, Optional.of(AXELS_KEY_NAME), AXELS_KEY_PASS.getBytes());
sftpChannel.connect((int) optionalTimeout.orElse(Duration.NULL).asMillis());
final String configFileName = "/etc/httpd/conf.d/"+hostname+".conf";
sftpChannel.get(configFileName, configFileContents);
assertTrue(configFileContents.toString().startsWith("Use Event-SSL "+hostname));
sftpChannel.getSession().disconnect();
- proxy.removeRedirect(hostname, /* optional SSH key name */ Optional.empty(), AXELS_KEY_PASS.getBytes());
- final SshCommandChannel lsSshChannel = proxyHost.createRootSshChannel(optionalTimeout, /* optional SSH key name */ Optional.empty(), AXELS_KEY_PASS.getBytes());
+ proxy.removeRedirect(hostname, Optional.of(AXELS_KEY_NAME), AXELS_KEY_PASS.getBytes());
+ final SshCommandChannel lsSshChannel = proxyHost.createRootSshChannel(optionalTimeout, Optional.of(AXELS_KEY_NAME), AXELS_KEY_PASS.getBytes());
final String lsOutput = lsSshChannel.runCommandAndReturnStdoutAndLogStderr("ls "+configFileName, /* stderr prefix */ null, /* stderr log level */ null);
assertTrue(lsOutput.isEmpty());
}
- protected ProcessT createApplicationProcess(final AwsInstance host) {
+ protected ProcessT createApplicationProcess(final AwsInstance host, String serverName) {
final SailingAnalyticsHostImpl> sailingAnalyticsHost =
new SailingAnalyticsHostImpl>(
host.getInstanceId(), host.getAvailabilityZone(), host.getPrivateAddress(), host.getLaunchTimePoint(),
landscape, new SailingAnalyticsProcessFactory(()->landscape));
@SuppressWarnings("unchecked")
- final ProcessT process = (ProcessT) new SailingAnalyticsProcessImpl(8888, sailingAnalyticsHost, ApplicationProcessHost.DEFAULT_SERVER_PATH, 2010, landscape);
+ final ProcessT process = (ProcessT) new SailingAnalyticsProcessImpl(8888, sailingAnalyticsHost, ApplicationProcessHost.DEFAULT_SERVERS_PATH+"/"+serverName, 2010, landscape);
return process;
}
@@ -236,7 +236,8 @@ public class ConnectivityTest"sg-0b2afd48960251280"),
Optional.of(Tags.with("Name", "MyHost").and("Hello", "World")),
"MONGODB_URI=\""+mongoEndpoint.getURI(Optional.of(new DatabaseImpl(mongoEndpoint, "winddbTest")))+"\"",
- "INSTALL_FROM_RELEASE="+SailingReleaseRepository.INSTANCE.getLatestMasterRelease().getName());
+ "INSTALL_FROM_RELEASE="+SailingReleaseRepository.INSTANCE.getLatestMasterRelease().getName(),
+ "SERVER_NAME=\""+serverName+"\"");
try {
assertNotNull(host);
final Instance instance = landscape.getInstance(host.getInstanceId(), region);
@@ -261,15 +263,15 @@ public class ConnectivityTest castLandscape = (AwsLandscape) landscape;
final CreateDNSBasedLoadBalancerMapping.Builder, ?, String, SailingAnalyticsMetrics, ProcessT> builder = CreateDNSBasedLoadBalancerMapping.builder();
builder
@@ -285,7 +287,7 @@ public class ConnectivityTest proxy = landscape.getCentralReverseProxy(new AwsRegion("eu-west-2", landscape));
+ final ReverseProxyCluster proxy = landscape.getCentralReverseProxy(new AwsRegion(Region.EU_WEST_2, landscape));
assertEquals(1, Util.size(proxy.getHosts()));
final HttpURLConnection healthCheckConnection = (HttpURLConnection) new URL("http://"+proxy.getHosts().iterator().next().getPublicAddress().getCanonicalHostName()+proxy.getHealthCheckPath()).openConnection();
assertEquals(200, healthCheckConnection.getResponseCode());
diff --git a/java/com.sap.sse.landscape.aws/META-INF/MANIFEST.MF b/java/com.sap.sse.landscape.aws/META-INF/MANIFEST.MF
index f65acba39aa..dcfef6a649e 100755
--- a/java/com.sap.sse.landscape.aws/META-INF/MANIFEST.MF
+++ b/java/com.sap.sse.landscape.aws/META-INF/MANIFEST.MF
@@ -9,7 +9,8 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: com.amazon.aws.aws-java-api;bundle-version="2.13.50",
com.sap.sse.landscape,
com.sap.sse.common,
- com.jcraft.jsch;bundle-version="0.1.54",
+ com.github.mwiede.jsch;bundle-version="0.2.8",
+ bcprov-ext;bundle-version="1.72.0",
com.sap.sse.landscape.aws.persistence,
com.sap.sse.security,
com.sap.sse.mongodb,
diff --git a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/AwsLandscape.java b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/AwsLandscape.java
index fbd74ad1891..8ffd298a885 100755
--- a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/AwsLandscape.java
+++ b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/AwsLandscape.java
@@ -304,15 +304,11 @@ public interface AwsLandscape extends Landscape {
*/
Iterable getSSHKeyPairs();
- /**
- * Assumes that the {@code keyPair}'s private key has been encrypted using this landscape's default encryption passphrase
- * and uses that to decrypt it.
- */
- byte[] getDecryptedPrivateKey(SSHKeyPair keyPair, byte[] privateKeyEncryptionPassphrase) throws JSchException;
-
/**
* Adds a key pair with {@link KeyPair#decrypt(byte[]) decrypted} private key to the AWS {@code region} identified
- * and stores it persistently also in the local server's database with the private key encrypted.
+ * and stores it persistently also in the local server's database with the private key encrypted. This will currently
+ * not work for keys of type ED25519 because the {@code getPrivateKey()} method of {@link KeyPair} is not implemented
+ * for that key type and instead throws an {@link UnsupportedOperationException}.
*
*
* The calling subject must have {@code CREATE} permission for the key and the {@code CREATE_OBJECT} permission for
@@ -321,7 +317,7 @@ public interface AwsLandscape extends Landscape {
SSHKeyPair addSSHKeyPair(com.sap.sse.landscape.Region region, String creator, String keyName, KeyPair keyPairWithDecryptedPrivateKey) throws JSchException;
/**
- * Creates a key pair with the given name in the region specified and obtains the key details and stores them in
+ * Creates an RSA key pair with the given name in the region specified and obtains the key details and stores them in
* this landscape persistently, such that {@link #getKeyPairInfo(Region, String)} as well as
* {@link #getSSHKeyPair(Region, String)} will be able to obtain (information on) the key. The private key is
* stored encrypted with the passphrase provided as parameter {@code privateKeyEncryptionPassphrase}.
diff --git a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/AwsLandscapeState.java b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/AwsLandscapeState.java
index d8ba84d2df2..05d6c3ecc6d 100755
--- a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/AwsLandscapeState.java
+++ b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/AwsLandscapeState.java
@@ -1,6 +1,5 @@
package com.sap.sse.landscape.aws;
-import com.jcraft.jsch.JSchException;
import com.sap.sse.landscape.aws.impl.AwsLandscapeStateImpl;
import com.sap.sse.landscape.aws.impl.SSHKeyPairListener;
import com.sap.sse.landscape.ssh.SSHKeyPair;
@@ -19,8 +18,6 @@ public interface AwsLandscapeState extends Replicable getSSHKeyPairs();
- byte[] getDecryptedPrivateKey(SSHKeyPair keyPair, byte[] privateKeyEncryptionPassphrase) throws JSchException;
-
void addSSHKeyPair(SSHKeyPair result);
}
diff --git a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/AwsInstanceImpl.java b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/AwsInstanceImpl.java
index e720eb8c213..b9226494b2f 100755
--- a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/AwsInstanceImpl.java
+++ b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/AwsInstanceImpl.java
@@ -148,7 +148,7 @@ public class AwsInstanceImpl implements AwsInstance {
}
final JSch jsch = new JSch();
JSch.setLogger(new JCraftLogAdapter());
- jsch.addIdentity(keyName, landscape.getDecryptedPrivateKey(keyPair, privateKeyEncryptionPassphrase), keyPair.getPublicKey(), /* passphrase */ null);
+ jsch.addIdentity(keyName, keyPair.getEncryptedPrivateKey(), keyPair.getPublicKey(), privateKeyEncryptionPassphrase);
final InetAddress address = getPublicAddress();
if (address == null) {
throw new IllegalStateException("Instance "+getInstanceId()+" doesn't have a public IP address");
diff --git a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/AwsLandscapeImpl.java b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/AwsLandscapeImpl.java
index 0bae0890192..1580e87177d 100644
--- a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/AwsLandscapeImpl.java
+++ b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/AwsLandscapeImpl.java
@@ -232,6 +232,11 @@ public class AwsLandscapeImpl implements AwsLandscape
this.pathPrefixForShardingKey = pathPrefixForShardingKey;
}
+ /**
+ * @param unencryptedKeyPair
+ * will not work for keys of type ED25519 because for those types the {@code getPrivateKey} method of
+ * {@link KeyPair} is not implemented and throws an {@link UnsupportedOperationException} instead.
+ */
private static byte[] getPrivateKeyBytes(KeyPair unencryptedKeyPair) {
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
unencryptedKeyPair.writePrivateKey(bos);
@@ -912,13 +917,6 @@ public class AwsLandscapeImpl implements AwsLandscape
return landscapeState.getSSHKeyPairs();
}
- @Override
- public byte[] getDecryptedPrivateKey(SSHKeyPair keyPair, byte[] privateKeyEncryptionPassphrase) throws JSchException {
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- keyPair.getKeyPair(new JSch(), privateKeyEncryptionPassphrase).writePrivateKey(bos);
- return bos.toByteArray();
- }
-
@Override
public >
Map, ApplicationReplicaSet> getScopes() {
@@ -2074,6 +2072,4 @@ public class AwsLandscapeImpl implements AwsLandscape
.predefinedMetricType(MetricType.ALB_REQUEST_COUNT_PER_TARGET))
.targetValue((double) AwsAutoScalingGroup.DEFAULT_MAX_REQUESTS_PER_TARGET)));
}
-
-
}
diff --git a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/AwsLandscapeStateImpl.java b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/AwsLandscapeStateImpl.java
index 2377fb070d2..9ac32b5ba14 100755
--- a/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/AwsLandscapeStateImpl.java
+++ b/java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/AwsLandscapeStateImpl.java
@@ -1,6 +1,5 @@
package com.sap.sse.landscape.aws.impl;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
@@ -13,8 +12,6 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-import com.jcraft.jsch.JSch;
-import com.jcraft.jsch.JSchException;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.landscape.aws.AwsLandscape;
import com.sap.sse.landscape.aws.AwsLandscapeOperation;
@@ -128,13 +125,6 @@ public class AwsLandscapeStateImpl extends AbstractReplicableWithObjectInputStre
return Collections.unmodifiableCollection(sshKeyPairs.values());
}
- @Override
- public byte[] getDecryptedPrivateKey(SSHKeyPair keyPair, byte[] privateKeyEncryptionPassphrase) throws JSchException {
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- keyPair.getKeyPair(new JSch(), privateKeyEncryptionPassphrase).writePrivateKey(bos);
- return bos.toByteArray();
- }
-
@Override
public void clearReplicaState() throws MalformedURLException, IOException, InterruptedException {
sshKeyPairs.clear();
diff --git a/java/com.sap.sse.landscape/META-INF/MANIFEST.MF b/java/com.sap.sse.landscape/META-INF/MANIFEST.MF
index ccf6eb5f1ac..445028a0521 100755
--- a/java/com.sap.sse.landscape/META-INF/MANIFEST.MF
+++ b/java/com.sap.sse.landscape/META-INF/MANIFEST.MF
@@ -17,7 +17,8 @@ Export-Package: com.sap.sse.landscape,
com.sap.sse.landscape.rabbitmq,
com.sap.sse.landscape.ssh
Require-Bundle: com.sap.sse.common,
- com.jcraft.jsch;bundle-version="0.1.54",
+ com.github.mwiede.jsch;bundle-version="0.2.8",
+ bcprov-ext;bundle-version="1.72.0",
com.sap.sse.landscape,
org.json.simple,
org.apache.httpcomponents.httpcore;bundle-version="4.4.9",
diff --git a/java/com.sap.sse.landscape/src/com/sap/sse/landscape/ssh/SSHKeyPair.java b/java/com.sap.sse.landscape/src/com/sap/sse/landscape/ssh/SSHKeyPair.java
index 9fa003be886..db4e6ed8f62 100755
--- a/java/com.sap.sse.landscape/src/com/sap/sse/landscape/ssh/SSHKeyPair.java
+++ b/java/com.sap.sse.landscape/src/com/sap/sse/landscape/ssh/SSHKeyPair.java
@@ -34,7 +34,11 @@ public class SSHKeyPair extends NamedImpl implements Named, WithQualifiedObjectI
/**
* This constructor variant accepts an unencrypted private key but in turn insists on a valid, non-{@code null}
* encryption passphrase which will be used to encrypt the private key before storing it in the new object's
- * {@link #encryptedPrivateKey} field.
+ * {@link #encryptedPrivateKey} field.
+ *
+ * Currently, this will not work for ED25519 keys because the {@code getPrivateKey()} method in {@link KeyPair} used by
+ * {@link KeyPair#writePrivateKey(java.io.OutputStream)} is not implemented for that key type and throws an
+ * {@link UnsupportedOperationException}. See also https://github.com/mwiede/jsch/issues/294.
*/
public SSHKeyPair(String regionId, String creatorName, TimePoint creationTime, String keyName, byte[] publicKey, byte[] unencryptedPrivateKey,
byte[] privateKeyEncryptionPassphrase) throws JSchException {
diff --git a/java/com.sap.sse.security.ui/GWT Security DevMode.launch b/java/com.sap.sse.security.ui/GWT Security DevMode.launch
index 26167ca2c75..fa5403d9c38 100755
--- a/java/com.sap.sse.security.ui/GWT Security DevMode.launch
+++ b/java/com.sap.sse.security.ui/GWT Security DevMode.launch
@@ -88,7 +88,6 @@
-
diff --git a/wiki/howto/autossh.md b/wiki/howto/autossh.md
index b7dc07c2b9e..6f26e1fa65f 100644
--- a/wiki/howto/autossh.md
+++ b/wiki/howto/autossh.md
@@ -21,10 +21,10 @@ The only problem with this approach is that the source compilation in this case
It can therefore be useful to use the tool `checkinstall` instead of `sudo make install`.
## Configuration
-It is benefitial to use tmux for the usage of autossh to create a terminal session, in which autossh can run without blocking the whole terminal session. Use `yum install tmux` for the installation.
+It is beneficial to use `tmux` for the usage of `autossh` to create a terminal session, in which `autossh` can run without blocking the whole terminal session. Use `yum install tmux` for the installation.
-Autossh itself relies on ssh and passes its terminal arguments to ssh. There are a few exeptions, for example the -M argument, which specifies the monitoring and echo port needed for the operation of autossh (uses the specified port and the port + 1). Autossh can be configured via environment variables, refer to the autossh manual for further information (`man autossh`).
-It can be useful to tweak the ssh_config and sshd_config to assure a quick recovery from failovers (see [Olympic Setup](/wiki/info/landscape/olympic-setup.md#tunnels) for the configuration). A typical command for creating a ssh tunnel is the following:
+Autossh itself relies on `ssh` and passes its terminal arguments to `ssh`. There are a few exeptions, for example the -M argument, which specifies the monitoring and echo port needed for the operation of `autossh` (uses the specified port and the port + 1). Autossh can be configured via environment variables, refer to the `autossh` manual for further information (`man autossh`).
+It can be useful to tweak the `/etc/ssh_config` and `/etc/sshd_config` to assure a quick recovery from failovers (see [Olympic Setup](/wiki/info/landscape/olympic-setup.md#tunnels) for the configuration). A typical command for creating a ssh tunnel is the following:
```
autossh -M 20000 -N -L *:5672:localhost:5672 -i /root/.ssh/id_rsa
diff --git a/wiki/howto/misc/server-replication.md b/wiki/howto/misc/server-replication.md
index 367996d99a1..7b485b20b0c 100644
--- a/wiki/howto/misc/server-replication.md
+++ b/wiki/howto/misc/server-replication.md
@@ -118,7 +118,7 @@ Steps to get it working:
192.168.1.50 tw2014 tw2014.sapsailing.com
* For rewriting the URLs and Ports to the fitting spectator URL when entering the URL we need an Apache installed (apt-get install apache2) and set up like on our sapsailing.com server. Please check 000-macros.conf, 001-events.conf and 000-main.conf and set it up as you need for the event. They need to be in the config dir of apache (/etc/apache2/mods-enabled and /etc/apache2/sites-enabled)
-* For better remote administration of the local replica, set up and autossh tunnel to trac@sapsailing.com and put it into rc.local for autostarting, e.g. as the following:
+* For better remote administration of the local replica, set up an autossh tunnel to `trac@sapsailing.com` and put it into `rc.local` for autostarting, e.g. as the following:
autossh -M 20009 -f -N -L 1337:127.0.0.1:22 -i SSHKEY trac@sapsailing.com
diff --git a/wiki/howto/onboarding.md b/wiki/howto/onboarding.md
index 74c1a2a192f..1f9311e7be2 100644
--- a/wiki/howto/onboarding.md
+++ b/wiki/howto/onboarding.md
@@ -24,7 +24,7 @@ First of all, make sure you've looked at [http://www.amazon.de/Patterns-Elements
The primary Git repository for the project is hosted on sapsailing.com. It is mirrored on an hourly basis into SAP's internal Git/Gerrit repository, but branches from the external Git end up under the remote `sapsailing.com` in the internal repository, thus do not automatically merge into their branch counterparts. Conversely, commits pushed onto branches of the SAP-internal Gerrit will not by themselves end up on the external Git at sapsailing.com.
- For access to the external git at `ssh://trac@sapsailing.com/home/trac/git` please send your SSH public key to Axel Uhl or Simon Marcel Pamies, requesting git access. Make sure to NOT generate the key using Putty. Putty keys don't work reliably under Linux and on Windows/Cygwin environments. Use ssh-keygen in a Cygwin or Linux or MacOS/X environment instead. For further instructions for generating an ssh-key see [GitHub](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent).
- Note: If you want to use the ssh-key in the context of our solution, it has to be in the PEM format, therefore add the parameter `-m PEM` to the ssh-keygen command when you are creating a new one. Example: `ssh-keygen -t rsa -b 4096 -C "test@test.com" -m PEM`. When using an existing key with the OpenSSH format, you can convert your private key with the command `ssh-keygen -p -m PEM -f `, the public key can stay as it was. Make sure to set a password for your key.
+ Note: If you want to use the ssh-key in the context of our solution, it can be an RSA or ED25519 format. Example for creating a key: `ssh-keygen -t ed25519 -b 512 -C "test@test.com"`. Make sure to set a non-empty password for your key.
- Alternatively, for access to the SAP-internal Git/Gerrit repository register yourself as a Git user in the SAP-Git under: [https://git.wdf.sap.corp:8080/](https://git.wdf.sap.corp:8080/); ask the Git administrator (Axel Uhl) to get on the list of enabled committers
2. Bugzilla
diff --git a/wiki/info/landscape/olympic-failover.md b/wiki/info/landscape/olympic-failover.md
index 0f9e4179d47..28d1ffd5374 100644
--- a/wiki/info/landscape/olympic-failover.md
+++ b/wiki/info/landscape/olympic-failover.md
@@ -6,11 +6,11 @@ This page is meant to describe a couple of failure scenarios and appropiate miti
### Scenario
-The Lenovo P1 device on which the SAP Sailing Analytics Master is running fails and is not available anymore. Reason could be a hardware failure on the CPU e.g.
+The Lenovo P1 device on which the SAP Sailing Analytics Master / Primary is running fails and is not available anymore. Reason could be a hardware failure on the CPU e.g.
The local replica on the second P1 device is still available, also the cloud replicas are still available. Data from the past is still available to users and on-site consumers. However no new data will be stored.
-The mongodb replicaset member running will also be not available anymore.
+The mongodb replicaset member running on the primary P1 will also be not available anymore.
### Mitigation
@@ -24,6 +24,8 @@ SSH tunnels won't need to change.
The local replica has to be safely shut down, on-site users might experience some change, depending on how we decide with local routing.
+Alternatively, based on the Tokyo 2020 experience, we may consider running the second Lenovo P1 laptop also in "master/primary" mode as a "shadow" where all we need to focus on is initially connecting the TracTrac races and linking them properly to the leaderboard slots. From there on, administration other than adding or removing wind sources, proved to be low effort and close to zero interaction. The official scores are transmitted after confirmation from TracTrac, and so are all start time, finish times, and penalties. This approach could help reduce the time to fail over from the primary to the shadow system in a lot less time than would be required for a re-start of the second Lenovo P1 in master/primary mode.
+
### Open questions
How exactly has the switch to happen?
diff --git a/wiki/info/landscape/olympic-setup.md b/wiki/info/landscape/olympic-setup.md
index ab817988de5..1fb51296965 100644
--- a/wiki/info/landscape/olympic-setup.md
+++ b/wiki/info/landscape/olympic-setup.md
@@ -149,7 +149,7 @@ The connection IDs will be shown, e.g., ``st-soft-aws_A``. Such a connection can
On both laptops there is a script ``/usr/local/bin/tunnels`` which establishes SSH tunnels using the ``autossh`` tool. The ``autossh`` processes are forked into the background using the ``-f`` option. It seems important to then pass the port to use for sending heartbeats using the ``-M`` option. If this is omitted, according to my experience only one of several ``autossh`` processes survives.
-During regular operations we assume that we have an Internet connection that allows us to reach our jump host ``tokyo-ssh.sapsailing.com`` through SSH, establishing various port forwards. We also expect TracTrac to have their primary server available. Furthermore, we assume both our laptops to be in service. ``sap-p1-1`` then runs the master server instance, ``sap-p1-2`` runs a local replica. The master on ``sap-p1-1`` replicates the central security service at ``security-service.sapsailing.com`` using the RabbitMQ installation on ``rabbit.internal.sapsailing.com`` in the AWS region eu-west-1. The port forwarding through tokyo-ssh.sapsailing.com (in ap-northeast-1) to the internal RabbitMQ address (in eu-west-1) works through VPC peering. The RabbitMQ instance used for outbound replication, both, into the cloud and for the on-site replica, is rabbit-ap-northeast-1.sapsailing.com. The replica on ``sap-p1-2`` obtains its replication stream from there, and for the HTTP connection for "reverse replication" it uses a direct connection to ``sap-p1-1``. The outside world, in particular all "S-ded-tokyo2020-m" master security groups in all regions supported, access the on-site master through a reverse port forward on our jump host ``tokyo-ssh.sapsailing.com:8888`` which under regular operations points to ``sap-p1-1:8888`` where the master process runs.
+During regular operations we assume that we have an Internet connection that allows us to reach our jump host ``tokyo-ssh.sapsailing.com`` through SSH, establishing various port forwards. We also expect TracTrac to have their primary server available. Furthermore, we assume both our laptops to be in service. ``sap-p1-1`` then runs the master server instance, ``sap-p1-2`` runs a local replica. The master on ``sap-p1-1`` replicates the central security service at ``security-service.sapsailing.com`` using the RabbitMQ installation on ``rabbit.internal.sapsailing.com`` in the AWS region `eu-west-1`. The port forwarding through `tokyo-ssh.sapsailing.com` (in `ap-northeast-1`) to the internal RabbitMQ address (in eu-west-1) works through VPC peering. The RabbitMQ instance used for outbound replication, both, into the cloud and for the on-site replica, is `rabbit-ap-northeast-1.sapsailing.com`. The replica on ``sap-p1-2`` obtains its replication stream from there, and for the HTTP connection for "reverse replication" it uses a direct connection to ``sap-p1-1``. The outside world, in particular all "S-ded-tokyo2020-m" master security groups in all regions supported, access the on-site master through a reverse port forward on our jump host ``tokyo-ssh.sapsailing.com:8888`` which under regular operations points to ``sap-p1-1:8888`` where the master process runs.
On both laptops we establish a port forward from ``localhost:22443`` to ``sapsailing.com:443``. Together with the alias in ``/etc/hosts`` that aliases ``www.sapsailing.com`` to ``localhost``, requests to ``www.sapsailing.com:22443`` will end up on the archive server.