mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-22 21:55:39 +00:00
Merge branch 'master' into bug5774
This commit is contained in:
@@ -45,3 +45,4 @@ SailingServer (No Proxy) Chargebee.launch
|
||||
## SAC Showcase, HDI Container
|
||||
mta_archives/
|
||||
db/.env
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# SAP Sailing Analytics
|
||||
|
||||
The SAP Sailing Analytics platform as seen on [sapsailing.com](https://sapsailing.com)
|
||||
|
||||
Sailing provides the perfect platform for SAP to showcase solutions and help the sport run like never before. SAP’s involvement in the sport has transformed the sailing experience by providing tools, which:
|
||||
|
||||
+2
-2
@@ -50,9 +50,9 @@ allprojects {
|
||||
ext {
|
||||
// regular
|
||||
buildTools = "30.0.3"
|
||||
compileSdk = 31
|
||||
compileSdk = 33
|
||||
minSdk = 16
|
||||
targetSdk = 31
|
||||
targetSdk = 33
|
||||
|
||||
sourceCompatibilityVersion = JavaVersion.VERSION_1_8
|
||||
targetCompatibilityVersion = JavaVersion.VERSION_1_8
|
||||
|
||||
@@ -1,615 +0,0 @@
|
||||
<Macro ArchiveRewrite>
|
||||
Use Rewrite 172.31.47.15 8888
|
||||
</Macro>
|
||||
|
||||
<Macro Headers>
|
||||
SetEnvIf Request_Method POST REQUEST_IS_POST=1
|
||||
SetEnvIf Request_URI ^/gateway.* REQUEST_IS_POST=1
|
||||
SetEnvIf Request_URI ^/gwt/RegattaOverview.* REQUEST_IS_POST=1
|
||||
SetEnvIf Request_URI ^/?$ REQUEST_IS_POST=1
|
||||
|
||||
Header set Expires "Sun, 19 Nov 1978 05:00:00 GMT" env=REQUEST_IS_POST
|
||||
Header set Cache-Control no-cache,no-store,must-revalidate,post-check=0,pre-check=0 env=REQUEST_IS_POST
|
||||
|
||||
AddOutputFilterByType DEFLATE text/plain
|
||||
AddOutputFilterByType DEFLATE text/html
|
||||
AddOutputFilterByType DEFLATE text/xml
|
||||
AddOutputFilterByType DEFLATE text/json
|
||||
AddOutputFilterByType DEFLATE application/json
|
||||
AddOutputFilterByType DEFLATE text/css
|
||||
AddOutputFilterByType DEFLATE image/gif
|
||||
AddOutputFilterByType DEFLATE image/png
|
||||
AddOutputFilterByType DEFLATE image/jpeg
|
||||
AddOutputFilterByType DEFLATE application/xml
|
||||
AddOutputFilterByType DEFLATE application/xhtml+xml
|
||||
AddOutputFilterByType DEFLATE application/rss+xml
|
||||
AddOutputFilterByType DEFLATE application/javascript
|
||||
AddOutputFilterByType DEFLATE application/x-javascript
|
||||
|
||||
AllowEncodedSlashes NoDecode
|
||||
</Macro>
|
||||
|
||||
<Macro Rewrite $IP $PORT>
|
||||
ProxyPass "/" "http://$IP:$PORT/" nocanon
|
||||
ProxyPassReverse / http://$IP:$PORT/
|
||||
ProxyPreserveHost On
|
||||
</Macro>
|
||||
|
||||
<Macro SSL>
|
||||
SSLEngine On
|
||||
SSLCertificateFile /etc/pki/tls/certs/star_sapsailing_com.crt
|
||||
SSLCertificateKeyFile /etc/pki/tls/private/star_sapsailing_com.key
|
||||
SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
|
||||
</Macro>
|
||||
|
||||
<Macro Status $HOSTNAME $PATH>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
<Location /$PATH>
|
||||
SetHandler server-status
|
||||
Order deny,allow
|
||||
Allow from all
|
||||
</Location>
|
||||
CustomLog logs/services_log combined
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Home $HOSTNAME $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
RewriteEngine on
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/Home.html" [L,NE]
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Home-SSL $HOSTNAME $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
RedirectPermanent / https://$HOSTNAME/
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost *:443>
|
||||
ServerName $HOSTNAME
|
||||
Use SSL
|
||||
Use Headers
|
||||
RewriteEngine on
|
||||
RewriteRule ^(/)?$ "https://$HOSTNAME/gwt/Home.html" [L,NE]
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Plain $HOSTNAME $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
Use Headers
|
||||
RewriteEngine on
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Plain-SSL $HOSTNAME $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
RedirectPermanent / https://$HOSTNAME/
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost *:443>
|
||||
ServerName $HOSTNAME
|
||||
Use SSL
|
||||
Use Headers
|
||||
RewriteEngine on
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro HardRedirect $HOSTNAME $TARGETURL>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
Use Headers
|
||||
RedirectMatch /(.*)$ $TARGETURL/
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro LiveCenterWithLanguageSubstitution-ARCHIVE $HOSTNAME $EVENTUUID>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/Home.html?locale=de#/event/:eventId=$EVENTUUID" [L,NE]
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^/en$"
|
||||
RewriteRule ^(/en)?$ "http://$HOSTNAME/gwt/Home.html?locale=en#/event/:eventId=$EVENTUUID" [L,NE]
|
||||
|
||||
Use Rewrite 172.31.30.89 8888
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro LiveCenterWithLanguageSubstitution $HOSTNAME $EVENTUUID $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/Home.html?locale=de#/event/:eventId=$EVENTUUID" [L,NE]
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^/en$"
|
||||
RewriteRule ^(/en)?$ "http://$HOSTNAME/gwt/Home.html?locale=en#/event/:eventId=$EVENTUUID" [L,NE]
|
||||
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro RibDashboard $HOSTNAME $LEADERBOARD_NAME $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
# The following matches the query string and captures it in group %1 for the RewriteRule to use before the fragment
|
||||
RewriteCond %{QUERY_STRING} "^(.*)$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/dashboards/RibDashboard.html?leaderboardName=$LEADERBOARD_NAME&%1" [L,NE]
|
||||
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
|
||||
<Macro RegattaOverview-WithLeaderboard-WithLanguage $HOSTNAME $EVENTUUID $LANG $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/RegattaOverview.html?event=$EVENTUUID&locale=$LANG&enableLeaderboard=true" [L,NE]
|
||||
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro RegattaOverview-WithLanguage $HOSTNAME $EVENTUUID $LANG $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/RegattaOverview.html?event=$EVENTUUID&locale=$LANG" [L,NE]
|
||||
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro RegattaOverview-WithLeaderboard $HOSTNAME $EVENTUUID $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/RegattaOverview.html?event=$EVENTUUID&enableLeaderboard=true" [L,NE]
|
||||
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Event $HOSTNAME $EVENTUUID $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
# The following matches the query string and captures it in group %1 for the RewriteRule to use before the fragment
|
||||
RewriteCond %{QUERY_STRING} "^(.*)$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/Home.html?%1#/event/:eventId=$EVENTUUID" [L,NE]
|
||||
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Event-SSL-Redirect $HOSTNAME $EVENTUUID $IP $PORT>
|
||||
Use RedirectPermanentToSSL $HOSTNAME
|
||||
Use Event-SSL $HOSTNAME $EVENTUUID $IP $PORT
|
||||
</Macro>
|
||||
|
||||
<Macro RedirectPermanentToSSL $HOSTNAME>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
RedirectPermanent / https://$HOSTNAME/
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Event-SSL $HOSTNAME $EVENTUUID $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
RedirectPermanent / https://$HOSTNAME/
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost *:443>
|
||||
ServerName $HOSTNAME
|
||||
Use SSL
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
# The following matches the query string and captures it in group %1 for the RewriteRule to use before the fragment
|
||||
RewriteCond %{QUERY_STRING} "^(.*)$"
|
||||
RewriteRule ^(/)?$ "https://$HOSTNAME/gwt/Home.html?%1#/event/:eventId=$EVENTUUID" [L,NE]
|
||||
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Series $HOSTNAME $EVENTUUID $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
# The following matches the query string and captures it in group %1 for the RewriteRule to use before the fragment
|
||||
RewriteCond %{QUERY_STRING} "^(.*)$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/Home.html?%1#/series/:seriesId=$EVENTUUID" [L,NE]
|
||||
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Series-SSL $HOSTNAME $EVENTUUID $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
RedirectPermanent / https://$HOSTNAME/
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost *:443>
|
||||
ServerName $HOSTNAME
|
||||
Use SSL
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
# The following matches the query string and captures it in group %1 for the RewriteRule to use before the fragment
|
||||
RewriteCond %{QUERY_STRING} "^(.*)$"
|
||||
RewriteRule ^(/)?$ "https://$HOSTNAME/gwt/Home.html?%1#/series/:seriesId=$EVENTUUID" [L,NE]
|
||||
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro EventRegattaIntro $HOSTNAME $EVENTUUID $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
# The following matches the query string and captures it in group %1 for the RewriteRule to use before the fragment
|
||||
RewriteCond %{QUERY_STRING} "^(.*)$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/Home.html?%1#/regatta/overview/:eventId=$EVENTUUID" [L,NE]
|
||||
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Event-WithLanguage $HOSTNAME $EVENTUUID $LANG $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/Home.html?locale=$LANG#EventPlace:eventId=$EVENTUUID" [L,NE]
|
||||
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Event-ARCHIVE $HOSTNAME $EVENTUUID>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
# The following matches the query string and captures it in group %1 for the RewriteRule to use before the fragment
|
||||
RewriteCond %{QUERY_STRING} "^(.*)$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/Home.html?%1#/event/:eventId=$EVENTUUID" [L,NE]
|
||||
|
||||
Use Rewrite 172.31.30.89 8888
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Event-ARCHIVE-SSL $HOSTNAME $EVENTUUID>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
RedirectPermanent / https://$HOSTNAME/
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost *:443>
|
||||
ServerName $HOSTNAME
|
||||
Use SSL
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
# The following matches the query string and captures it in group %1 for the RewriteRule to use before the fragment
|
||||
RewriteCond %{QUERY_STRING} "^(.*)$"
|
||||
RewriteRule ^(/)?$ "https://$HOSTNAME/gwt/Home.html?%1#/event/:eventId=$EVENTUUID" [L,NE]
|
||||
|
||||
Use Rewrite 172.31.30.89 8888
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
|
||||
<Macro RegattaOverview $HOSTNAME $EVENTUUID $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
# The following matches the query string and captures it in group %1 for the RewriteRule to use before the fragment
|
||||
RewriteCond %{QUERY_STRING} "^(.*)$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/RegattaOverview.html?event=$EVENTUUID&%1" [L,NE]
|
||||
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Events $HOSTNAME $EVENTNAME $EXTRA $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/events/$EVENTNAME/$EXTRA" [L,NE]
|
||||
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Spectator-WithParam $HOSTNAME $GROUPNAME $EXTRA $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/Spectator.html?leaderboardGroupName=$GROUPNAME&$EXTRA" [L,NE]
|
||||
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Spectator-WithLanguage $HOSTNAME $GROUPNAME $LANG $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/Spectator.html?leaderboardGroupName=$GROUPNAME&showRaceDetails=true&locale=$LANG" [L,NE]
|
||||
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Spectator $HOSTNAME $GROUPNAME $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/Spectator.html?leaderboardGroupName=$GROUPNAME&showRaceDetails=true" [L,NE]
|
||||
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Leaderboard $HOSTNAME $GROUPNAME $NAME $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/Leaderboard.html?name=$NAME&leaderboardGroupName=$GROUPNAME&showRaceDetails=true&root=leaderboardGroupPanel" [L,NE]
|
||||
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Leaderboard-WithParam $HOSTNAME $GROUPNAME $NAME $EXTRA $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/Leaderboard.html?name=$NAME&leaderboardGroupName=$GROUPNAME&$EXTRA" [L,NE]
|
||||
|
||||
Use Rewrite-ARCHIVE1
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Spectator-ARCHIVE $HOSTNAME $GROUPNAME>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/Spectator.html?leaderboardGroupName=$GROUPNAME&showRaceDetails=true" [L,NE]
|
||||
|
||||
Use Rewrite 172.31.30.89 8888
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Spectator-ARCHIVE-SSL $HOSTNAME $GROUPNAME>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
RedirectPermanent / https://$HOSTNAME/
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost *:443>
|
||||
ServerName $HOSTNAME
|
||||
Use SSL
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
RewriteRule ^(/)?$ "https://$HOSTNAME/gwt/Spectator.html?leaderboardGroupName=$GROUPNAME&showRaceDetails=true" [L,NE]
|
||||
|
||||
Use Rewrite 172.31.30.89 8888
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Spectator-ARCHIVE-WithParam $HOSTNAME $GROUPNAME $EXTRA>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/Spectator.html?leaderboardGroupName=$GROUPNAME&$EXTRA" [L,NE]
|
||||
|
||||
Use Rewrite 172.31.30.89 8888
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Home-ARCHIVE $HOSTNAME>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
Use Headers
|
||||
RewriteEngine on
|
||||
RewriteRule ^(/)?$ "https://$HOSTNAME/gwt/Home.html" [L,NE]
|
||||
Use ArchiveRewrite
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Event-ARCHIVE $HOSTNAME $EVENTUUID>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
Use Headers
|
||||
RewriteEngine on
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
# The following matches the query string and captures it in group %1 for the RewriteRule to use before the fragment
|
||||
RewriteCond %{QUERY_STRING} "^(.*)$"
|
||||
RewriteRule ^(/)?$ "https://$HOSTNAME/gwt/Home.html#/event/:eventId=$EVENTUUID" [L,NE]
|
||||
Use ArchiveRewrite
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Series-ARCHIVE $HOSTNAME $SERIESUUID>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
Use Headers
|
||||
RewriteEngine on
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
# The following matches the query string and captures it in group %1 for the RewriteRule to use before the fragment
|
||||
RewriteCond %{QUERY_STRING} "^(.*)$"
|
||||
RewriteRule ^(/)?$ "https://$HOSTNAME/gwt/Home.html?%1#/series/events/:leaderboardGroupId=$SERIESUUID" [L,NE]
|
||||
Use ArchiveRewrite
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Spectator-DEV $HOSTNAME $GROUPNAME>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/Spectator.html?leaderboardGroupName=$GROUPNAME&showRaceDetails=true" [L,NE]
|
||||
|
||||
Use Rewrite 172.31.18.218 8888
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Spectator-DEV-WithParam $HOSTNAME $GROUPNAME $EXTRA>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/gwt/Spectator.html?leaderboardGroupName=$GROUPNAME&$EXTRA" [L,NE]
|
||||
|
||||
Use Rewrite 172.31.18.218 8888
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Events-DEV $HOSTNAME $EVENTNAME $EXTRA>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
RewriteRule ^(/)?$ "http://$HOSTNAME/events/$EVENTNAME/$EXTRA" [L,NE]
|
||||
|
||||
Use Rewrite 172.31.18.218 8888
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Use like this:
|
||||
#
|
||||
# echo "MY_SECRET_ENV_VAR=\\\"some secret that may even contain blanks or = or &\\\"" | ./addSecret
|
||||
#
|
||||
# Copy stdin to SECRETS_TO_ADD
|
||||
SECRETS_TO_ADD=$( cat )
|
||||
SERVERS_PATH=/home/sailing/servers
|
||||
SECRETS_PATH=/root/secrets
|
||||
SECRETS_IN_APP_PATH=configuration/secrets
|
||||
FIND_ANALYTICS_SERVERS_SCRIPT="$( dirname ${0} )/findSailingAnalyticsServers"
|
||||
for IP in $( ${FIND_ANALYTICS_SERVERS_SCRIPT} ); do
|
||||
echo "Handling server with IP ${IP} ..."
|
||||
ssh root@$IP 'echo "Appending '${SECRETS_TO_ADD}' to '${SECRETS_PATH}'"
|
||||
echo "'${SECRETS_TO_ADD}'" >>'${SECRETS_PATH}'
|
||||
echo "Server directories:"
|
||||
for i in $( ls '${SERVERS_PATH}' ); do
|
||||
echo "Appending to '${SERVERS_PATH}'/${i}/'${SECRETS_IN_APP_PATH}'"
|
||||
echo "'${SECRETS_TO_ADD}'" >>'${SERVERS_PATH}'/${i}/'${SECRETS_IN_APP_PATH}'
|
||||
done'
|
||||
done
|
||||
@@ -1 +1,2 @@
|
||||
* * * * * export PATH=/bin:/usr/bin:/usr/local/bin; sleep $(( $RANDOM * 60 / 32768 )); update_authorized_keys_for_landscape_managers_if_changed $( cat /root/ssh-key-reader.token ) https://security-service.sapsailing.com /root 2>&1 >>/var/log/sailing.err
|
||||
* * * * * export PATH=/bin:/usr/bin:/usr/local/bin; switchoverArchive.sh /etc/httpd/conf.d/000-macros.conf 2 9
|
||||
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
aws ec2 describe-instances --filters Name=tag-key,Values=sailing-analytics-server | jq -r '.Reservations[].Instances[].NetworkInterfaces[].PrivateIpAddresses[].Association.PublicIp'
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
echo "
|
||||
"
|
||||
BODY=$( cat )
|
||||
echo "${BODY}" >/tmp/github-hook-body
|
||||
REF=$( echo "${BODY}" | jq -r '.ref' )
|
||||
PUSHER=$( echo "${BODY}" | jq -r '.pusher.email' )
|
||||
logger -t github-cgi "ref ia $REF, pusher was $PUSHER"
|
||||
# For testing:
|
||||
#if [ "${PUSHER}" = "axel.uhl@sap.com" -a "${REF}" = "refs/heads/translation" ]; then
|
||||
if [ "${PUSHER}" = "tmsatsls+github.tools.sap_service-tip-git@sap.com" -a "${REF}" = "refs/heads/translation" ]; then
|
||||
echo "Identified a push to refs/heads/translation by ${PUSHER}."
|
||||
echo "Fetching translation branch from github.tools.sap and pushing it to ssh://trac@sapsailing.com/home/trac/git"
|
||||
logger -t github-cgi "fetching translation branch from github.tools.sap and pushing it to ssh://trac@sapsailing.com/home/trac/git"
|
||||
cd /home/wiki/gitwiki
|
||||
sudo -u wiki git fetch sapsailing translation:translation 2>&1
|
||||
sudo -u wiki git push origin translation:translation 2>&1
|
||||
else
|
||||
echo "Either pusher was not tmsatsls+github.tools.sap_service-tip-git@sap.com or ref was not refs/heads/translation. Not triggering."
|
||||
fi
|
||||
@@ -1,56 +1,10 @@
|
||||
# ARCHIVE, based on i3.2xlarge, 64GB RAM and 1.9TB swap
|
||||
#Define ARCHIVE_IP 172.31.24.90
|
||||
#Define ARCHIVE_IP 172.31.24.90
|
||||
#Define ARCHIVE_IP 172.31.20.25
|
||||
#Define ARCHIVE_IP 172.31.16.178
|
||||
#Define ARCHIVE_IP 172.31.25.130
|
||||
#Define ARCHIVE_IP 172.31.25.246
|
||||
#Define ARCHIVE_IP 172.31.24.192
|
||||
#Define ARCHIVE_IP 172.31.22.16
|
||||
# Failover (hanging in full gc):
|
||||
#Define ARCHIVE_IP 172.31.29.138
|
||||
# Production (hanging in full gc):
|
||||
#Define ARCHIVE_IP 172.31.18.201
|
||||
# New Candidate, not really ready...
|
||||
#Define ARCHIVE_IP 172.31.28.255
|
||||
#Define ARCHIVE_IP 172.31.21.159
|
||||
#Define ARCHIVE_IP 172.31.19.41
|
||||
#Define ARCHIVE_IP 172.31.29.206
|
||||
#Define ARCHIVE_IP 172.31.25.194
|
||||
#Define ARCHIVE_IP 172.31.17.130
|
||||
#Define ARCHIVE_IP 172.31.20.156
|
||||
#Define ARCHIVE_IP 172.31.28.168
|
||||
#Define ARCHIVE_IP 172.31.23.135
|
||||
#Define ARCHIVE_IP 172.31.16.245
|
||||
#Define ARCHIVE_IP 172.31.29.3
|
||||
#Define ARCHIVE_IP 172.31.20.157
|
||||
#Define ARCHIVE_IP 172.31.17.35
|
||||
#Define ARCHIVE_IP 172.31.28.236
|
||||
#Define ARCHIVE_IP 172.31.16.207
|
||||
#Define ARCHIVE_IP 172.31.26.1
|
||||
#Define ARCHIVE_IP 172.31.21.3
|
||||
#Define ARCHIVE_IP 172.31.28.73
|
||||
#Define ARCHIVE_IP 172.31.17.113
|
||||
#Define ARCHIVE_IP 172.31.30.211
|
||||
#Define ARCHIVE_IP 172.31.20.222
|
||||
#Define ARCHIVE_IP 172.31.21.139
|
||||
#Define ARCHIVE_IP 172.31.23.47
|
||||
#Define ARCHIVE_IP 172.31.20.62
|
||||
#Define ARCHIVE_IP 172.31.20.131
|
||||
#Define ARCHIVE_IP 172.31.47.208
|
||||
#Define ARCHIVE_IP 172.31.41.14
|
||||
#Define ARCHIVE_IP 172.31.34.59
|
||||
#Define ARCHIVE_IP 172.31.46.41
|
||||
#Define ARCHIVE_IP 172.31.44.232
|
||||
#Define ARCHIVE_IP 172.31.46.28
|
||||
#Define ARCHIVE_IP 172.31.45.169
|
||||
#Define ARCHIVE_IP 172.31.45.31
|
||||
#Define ARCHIVE_IP 172.31.44.175
|
||||
#Define ARCHIVE_IP 172.31.36.140
|
||||
Define ARCHIVE_IP 172.31.46.176
|
||||
Define ARCHIVE_IP 172.31.40.242
|
||||
Define ARCHIVE_FAILOVER_IP 172.31.40.242
|
||||
Define PRODUCTION_ARCHIVE ${ARCHIVE_IP}
|
||||
|
||||
<Macro ArchiveRewrite>
|
||||
Use Rewrite ${ARCHIVE_IP} 8888
|
||||
Use Rewrite ${PRODUCTION_ARCHIVE} 8888
|
||||
</Macro>
|
||||
|
||||
<Macro Headers>
|
||||
@@ -197,27 +151,6 @@ Define ARCHIVE_IP 172.31.46.176
|
||||
ProxyPreserveHost On
|
||||
</Macro>
|
||||
|
||||
<Macro SSL>
|
||||
SSLEngine On
|
||||
SSLCertificateFile /etc/pki/tls/certs/star_sapsailing_com.crt
|
||||
SSLCertificateKeyFile /etc/pki/tls/private/star_sapsailing_com.key
|
||||
SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
|
||||
</Macro>
|
||||
|
||||
<Macro SSL-sail-insight>
|
||||
SSLEngine On
|
||||
SSLCertificateFile /etc/letsencrypt/live/sail-insight.com/cert.pem
|
||||
SSLCertificateKeyFile /etc/letsencrypt/live/sail-insight.com/privkey.pem
|
||||
SSLCertificateChainFile /etc/letsencrypt/live/sail-insight.com/fullchain.pem
|
||||
</Macro>
|
||||
|
||||
<Macro SSL-Tennis>
|
||||
SSLEngine On
|
||||
SSLCertificateFile /etc/pki/tls/certs/star_saptennis_com.crt
|
||||
SSLCertificateKeyFile /etc/pki/tls/private/star_saptennis_com_2022.key
|
||||
SSLCertificateChainFile /etc/pki/tls/certs/saptennis_chain_2022.crt
|
||||
</Macro>
|
||||
|
||||
<Macro Status $HOSTNAME $PATH>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
@@ -230,19 +163,6 @@ Define ARCHIVE_IP 172.31.46.176
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Status-SSL $HOSTNAME $PATH>
|
||||
<VirtualHost *:443>
|
||||
ServerName $HOSTNAME
|
||||
Use SSL
|
||||
<Location /$PATH>
|
||||
SetHandler server-status
|
||||
Order deny,allow
|
||||
Allow from all
|
||||
</Location>
|
||||
CustomLog logs/services_log combined
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Home-ARCHIVE $HOSTNAME>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
@@ -253,50 +173,6 @@ Define ARCHIVE_IP 172.31.46.176
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Home-ARCHIVE-SSL-Redirect $HOSTNAME>
|
||||
Use RedirectPermanentToSSL $HOSTNAME
|
||||
Use Home-ARCHIVE-SSL $HOSTNAME
|
||||
</Macro>
|
||||
|
||||
<Macro Tennis-With-SSL $HOSTNAME $IP $PORT $PATH>
|
||||
<VirtualHost *:443>
|
||||
ServerName $HOSTNAME
|
||||
Use Headers-Tennis
|
||||
Use SSL-Tennis
|
||||
RewriteEngine on
|
||||
RewriteRule ^(/)?$ https://$HOSTNAME/$PATH [L,NE]
|
||||
RewriteRule ^/(.*)$ http://$IP:$PORT/$1 [P,L]
|
||||
ProxyPassReverse / http://$IP:$PORT/
|
||||
ProxyPreserveHost On
|
||||
CustomLog logs/tennis_log combined
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Tennis-With-SSL-Plain $HOSTNAME $IP $PORT>
|
||||
<VirtualHost *:443>
|
||||
ServerName $HOSTNAME
|
||||
Use Headers-Tennis
|
||||
Use SSL-Tennis
|
||||
RewriteEngine on
|
||||
RewriteRule ^/(.*)$ http://$IP:$PORT/$1 [P,L]
|
||||
ProxyPassReverse / http://$IP:$PORT/
|
||||
ProxyPreserveHost On
|
||||
CustomLog logs/tennis_log combined
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Home-ARCHIVE-SSL $HOSTNAME>
|
||||
<VirtualHost *:443>
|
||||
ServerName $HOSTNAME
|
||||
Use SSL
|
||||
Use Headers
|
||||
RewriteEngine on
|
||||
# LogLevel alert rewrite:trace5
|
||||
RewriteRule ^(/)?$ "https://$HOSTNAME/gwt/Home.html" [L,NE]
|
||||
Use ArchiveRewrite
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Home $HOSTNAME $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
@@ -308,34 +184,6 @@ Define ARCHIVE_IP 172.31.46.176
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Home-SSL-Redirect $HOSTNAME $IP $PORT>
|
||||
Use RedirectPermanentToSSL $HOSTNAME
|
||||
Use Home-SSL $HOSTNAME $IP $PORT
|
||||
</Macro>
|
||||
|
||||
<Macro Tennis-SSL-Redirect $HOSTNAME>
|
||||
Use RedirectPermanentToSSL $HOSTNAME
|
||||
</Macro>
|
||||
|
||||
<Macro Tennis-SSL-Redirect-WWW $HOSTNAME>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
RedirectPermanent / https://www.$HOSTNAME/
|
||||
CustomLog logs/tennis_log combined
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Home-SSL $HOSTNAME $IP $PORT>
|
||||
<VirtualHost *:443>
|
||||
ServerName $HOSTNAME
|
||||
Use SSL
|
||||
Use Headers
|
||||
RewriteEngine on
|
||||
RewriteRule ^(/)?$ "https://$HOSTNAME/gwt/Home.html" [L,NE]
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Plain $HOSTNAME $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
@@ -355,28 +203,6 @@ Define ARCHIVE_IP 172.31.46.176
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro RedirectPermanentToSSL $HOSTNAME>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
RedirectPermanent / https://$HOSTNAME/
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Plain-SSL-Redirect $HOSTNAME $IP $PORT>
|
||||
Use RedirectPermanentToSSL $HOSTNAME
|
||||
Use Plain-SSL $HOSTNAME $IP $PORT
|
||||
</Macro>
|
||||
|
||||
<Macro Plain-SSL $HOSTNAME $IP $PORT>
|
||||
<VirtualHost *:443>
|
||||
ServerName $HOSTNAME
|
||||
Use SSL
|
||||
Use Headers
|
||||
RewriteEngine on
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro HardRedirect $HOSTNAME $TARGETURL>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
@@ -491,50 +317,6 @@ Define ARCHIVE_IP 172.31.46.176
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Event-SSL-Redirect $HOSTNAME $EVENTUUID $IP $PORT>
|
||||
Use RedirectPermanentToSSL $HOSTNAME
|
||||
Use Event-SSL $HOSTNAME $EVENTUUID $IP $PORT
|
||||
</Macro>
|
||||
|
||||
<Macro Event-SSL $HOSTNAME $EVENTUUID $IP $PORT>
|
||||
<VirtualHost *:443>
|
||||
ServerName $HOSTNAME
|
||||
Use SSL
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
# The following matches the query string and captures it in group %1 for the RewriteRule to use before the fragment
|
||||
RewriteCond %{QUERY_STRING} "^(.*)$"
|
||||
RewriteRule ^(/)?$ "https://$HOSTNAME/gwt/Home.html?%1#/event/:eventId=$EVENTUUID" [L,NE]
|
||||
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Series-SSL $HOSTNAME $SERIESUUID $IP $PORT>
|
||||
<VirtualHost *:443>
|
||||
ServerName $HOSTNAME
|
||||
Use SSL
|
||||
Use Headers
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
# The following matches the query string and captures it in group %1 for the RewriteRule to use before the fragment
|
||||
RewriteCond %{QUERY_STRING} "^(.*)$"
|
||||
RewriteRule ^(/)?$ "https://$HOSTNAME/gwt/Home.html?%1#/series/events/:seriesId=$SERIESUUID" [L,NE]
|
||||
|
||||
Use Rewrite $IP $PORT
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Series-SSL-Redirect $HOSTNAME $EVENTUUID $IP $PORT>
|
||||
Use RedirectPermanentToSSL $HOSTNAME
|
||||
Use Series-SSL $HOSTNAME $EVENTUUID $IP $PORT
|
||||
</Macro>
|
||||
|
||||
<Macro Series $HOSTNAME $SERIESUUID $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
@@ -581,11 +363,6 @@ Define ARCHIVE_IP 172.31.46.176
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Series-ARCHIVE-SSL-Redirect $HOSTNAME $SERIESUUID>
|
||||
Use RedirectPermanentToSSL $HOSTNAME
|
||||
Use Series-ARCHIVE-SSL $HOSTNAME $SERIESUUID
|
||||
</Macro>
|
||||
|
||||
<Macro Series-ARCHIVE $HOSTNAME $SERIESUUID>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
@@ -599,25 +376,6 @@ Define ARCHIVE_IP 172.31.46.176
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Series-ARCHIVE-SSL $HOSTNAME $SERIESUUID>
|
||||
<VirtualHost *:443>
|
||||
ServerName $HOSTNAME
|
||||
Use SSL
|
||||
Use Headers
|
||||
RewriteEngine on
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
# The following matches the query string and captures it in group %1 for the RewriteRule to use before the fragment
|
||||
RewriteCond %{QUERY_STRING} "^(.*)$"
|
||||
RewriteRule ^(/)?$ "https://$HOSTNAME/gwt/Home.html?%1#/series/events/:leaderboardGroupId=$SERIESUUID" [L,NE]
|
||||
Use ArchiveRewrite
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Event-ARCHIVE-SSL-Redirect $HOSTNAME $EVENTUUID>
|
||||
Use RedirectPermanentToSSL $HOSTNAME
|
||||
Use Event-ARCHIVE-SSL $HOSTNAME $EVENTUUID
|
||||
</Macro>
|
||||
|
||||
<Macro Event-ARCHIVE $HOSTNAME $EVENTUUID>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
@@ -631,20 +389,6 @@ Define ARCHIVE_IP 172.31.46.176
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Event-ARCHIVE-SSL $HOSTNAME $EVENTUUID>
|
||||
<VirtualHost *:443>
|
||||
ServerName $HOSTNAME
|
||||
Use SSL
|
||||
Use Headers
|
||||
RewriteEngine on
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
# The following matches the query string and captures it in group %1 for the RewriteRule to use before the fragment
|
||||
RewriteCond %{QUERY_STRING} "^(.*)$"
|
||||
RewriteRule ^(/)?$ "https://$HOSTNAME/gwt/Home.html?%1#/event/:eventId=$EVENTUUID" [L,NE]
|
||||
Use ArchiveRewrite
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro RegattaOverview $HOSTNAME $EVENTUUID $IP $PORT>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
@@ -763,23 +507,6 @@ Define ARCHIVE_IP 172.31.46.176
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Spectator-ARCHIVE-SSL-Redirect $HOSTNAME $GROUPNAME>
|
||||
Use RedirectPermanentToSSL $HOSTNAME
|
||||
Use Spectator-ARCHIVE-SSL $HOSTNAME "$GROUPNAME"
|
||||
</Macro>
|
||||
|
||||
<Macro Spectator-ARCHIVE-SSL $HOSTNAME $GROUPNAME>
|
||||
<VirtualHost *:443>
|
||||
ServerName $HOSTNAME
|
||||
Use SSL
|
||||
Use Headers
|
||||
RewriteEngine on
|
||||
RewriteCond %{REQUEST_URI} "^(/)?$"
|
||||
RewriteRule ^(/)?$ "https://$HOSTNAME/gwt/Spectator.html?leaderboardGroupName=$GROUPNAME&showRaceDetails=true" [L,NE]
|
||||
Use ArchiveRewrite
|
||||
</VirtualHost>
|
||||
</Macro>
|
||||
|
||||
<Macro Spectator-ARCHIVE-WithParam $HOSTNAME $GROUPNAME $EXTRA>
|
||||
<VirtualHost *:80>
|
||||
ServerName $HOSTNAME
|
||||
|
||||
@@ -34,16 +34,6 @@
|
||||
# WWW as the default virtual host for HTTPS access to port 443 because it's listed as the first on :443
|
||||
Use Home-ARCHIVE www.sapsailing.com
|
||||
|
||||
<VirtualHost *:443>
|
||||
# a rewrite rule to map sapsailing.com to www.sapsailing.com for HTTPS requests
|
||||
ServerName sapsailing.com
|
||||
Use SSL
|
||||
RewriteEngine on
|
||||
RewriteRule ^.*$ https://www.sapsailing.com%{REQUEST_URI} [L,R=301,NE]
|
||||
CustomLog logs/access_log sapsailing_httpd_redirect_combined env=!original_client_ip
|
||||
CustomLog logs/access_log sapsailing_httpd_redirect_combined_first_forwarded_for_ip env=original_client_ip
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost *:80>
|
||||
ServerName jobs.sapsailing.com
|
||||
CustomLog logs/jobs_log combined env=!original_client_ip
|
||||
@@ -57,27 +47,6 @@ Use Home-ARCHIVE www.sapsailing.com
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
|
||||
# sail-insight.com
|
||||
<VirtualHost *:80>
|
||||
ServerName sail-insight.com
|
||||
ServerAlias www.sail-insight.com
|
||||
RedirectPermanent / https://sail-insight.com/
|
||||
</VirtualHost>
|
||||
<VirtualHost *:443>
|
||||
ServerName sail-insight.com
|
||||
ServerAlias www.sail-insight.com
|
||||
Use SSL-sail-insight
|
||||
CustomLog logs/services_log combined env=!original_client_ip
|
||||
CustomLog logs/services_log first_forwarded_for_ip env=original_client_ip
|
||||
Alias / /home/trac/sail-insight-website/
|
||||
<Directory /home/trac/sail-insight-website>
|
||||
Options Indexes FollowSymLinks MultiViews
|
||||
AllowOverride All
|
||||
Order allow,deny
|
||||
allow from all
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
|
||||
# P2 repository
|
||||
<VirtualHost *:80>
|
||||
ServerName p2.sapsailing.com
|
||||
@@ -160,13 +129,3 @@ Use Home-ARCHIVE www.sapsailing.com
|
||||
CustomLog logs/services_log combined env=!original_client_ip
|
||||
CustomLog logs/services_log first_forwarded_for_ip env=original_client_ip
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost *:80>
|
||||
ServerName hudson.sapsailing.com
|
||||
RewriteEngine on
|
||||
# LogLevel alert rewrite:trace5
|
||||
RewriteRule ^/(.*)$ http://172.31.28.12:8080/$1 [P]
|
||||
ProxyPassReverse / http://172.31.28.12:8080/
|
||||
CustomLog logs/services_log combined env=!original_client_ip
|
||||
CustomLog logs/services_log first_forwarded_for_ip env=original_client_ip
|
||||
</VirtualHost>
|
||||
|
||||
@@ -21,8 +21,8 @@ Use Status 172.31.42.171 internal-server-status
|
||||
Use Status 127.0.0.1 internal-server-status
|
||||
|
||||
# Uncomment the following and update the internal IP to what your Archive server candidate is
|
||||
Use Plain archive-failover.sapsailing.com 172.31.44.175 8888
|
||||
Use Plain archive-candidate.sapsailing.com 172.31.46.176 8888
|
||||
Use Plain archive-failover.sapsailing.com 172.31.40.12 8888
|
||||
Use Plain archive-candidate.sapsailing.com 172.31.46.203 8888
|
||||
|
||||
Use Plain my-master.sapsailing.com 172.31.24.34 8888
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ ServerName git.sapsailing.com
|
||||
SetEnv GIT_PROJECT_ROOT /home/trac/git
|
||||
SetEnv GIT_HTTP_EXPORT_ALL
|
||||
ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
|
||||
ScriptAlias /hooks/ /var/www/cgi-bin/
|
||||
|
||||
<Location /git/ >
|
||||
Options +ExecCGI
|
||||
@@ -44,7 +45,7 @@ SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:SSLv3:!RC4:!MD5:+HIGH
|
||||
# pass phrase. Note that a kill -HUP will prompt again. A new
|
||||
# certificate can be generated using the genkey(1) command.
|
||||
#SSLCertificateFile /etc/pki/tls/certs/ca.crt
|
||||
SSLCertificateFile /etc/pki/tls/certs/star_sapsailing_com.crt
|
||||
#SSLCertificateFile /etc/pki/tls/certs/star_sapsailing_com.crt
|
||||
|
||||
# Server Private Key:
|
||||
# If the key is not combined with the certificate, use this
|
||||
@@ -52,7 +53,7 @@ SSLCertificateFile /etc/pki/tls/certs/star_sapsailing_com.crt
|
||||
# you've both a RSA and a DSA private key you can configure
|
||||
# both in parallel (to also allow the use of DSA ciphers, etc.)
|
||||
#SSLCertificateKeyFile /etc/pki/tls/private/ca.key
|
||||
SSLCertificateKeyFile /etc/pki/tls/private/star_sapsailing_com.key
|
||||
#SSLCertificateKeyFile /etc/pki/tls/private/star_sapsailing_com.key
|
||||
|
||||
# Server Certificate Chain:
|
||||
# Point SSLCertificateChainFile at a file containing the
|
||||
@@ -62,7 +63,7 @@ SSLCertificateKeyFile /etc/pki/tls/private/star_sapsailing_com.key
|
||||
# when the CA certificates are directly appended to the server
|
||||
# certificate for convinience.
|
||||
#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
|
||||
SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
|
||||
#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
|
||||
|
||||
# Certificate Authority (CA):
|
||||
# Set the CA certificate verification path where to find CA
|
||||
@@ -127,6 +128,10 @@ SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
|
||||
|
||||
<Directory "/var/www/cgi-bin">
|
||||
SSLOptions +StdEnvVars
|
||||
AllowOverride None
|
||||
Options FollowSymLinks
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
</Directory>
|
||||
|
||||
# SSL Protocol Adjustments:
|
||||
|
||||
@@ -1,261 +0,0 @@
|
||||
|
||||
# XXX: Move to saptennis.com
|
||||
Use Tennis-Plain tennis-analytics.sapsailing.com 54.234.185.60 8888
|
||||
Use Tennis-Plain mobile.tennis-analytics.sapsailing.com 54.234.185.60 8888
|
||||
Use Tennis-Plain api.tennis-analytics.sapsailing.com 54.234.185.60 8888
|
||||
Use Tennis-Plain dev.tennis-analytics.sapsailing.com 34.242.130.58 8888
|
||||
|
||||
# XXX: Move these to SSL
|
||||
Use Tennis-Plain saptennis.com 54.234.185.60 8888
|
||||
Use Tennis-Plain draw.saptennis.com 54.234.185.60 8888
|
||||
Use Tennis-Plain groupedit.saptennis.com 34.253.178.230 8888
|
||||
|
||||
Use Tennis-With-SSL-Plain dev.saptennis.com 34.254.157.195 8888
|
||||
Use Tennis-With-SSL-Plain api.saptennis.com 54.234.185.60 8888
|
||||
Use Tennis-With-SSL-Plain tpc.saptennis.com 34.242.18.47 8888
|
||||
Use Tennis-With-SSL media.saptennis.com 34.240.66.211 8888 "media/mediaportal"
|
||||
Use Tennis-With-SSL-Plain apps.saptennis.com 34.241.245.147 8888
|
||||
|
||||
# Monitoring
|
||||
Use Tennis-With-SSL-Plain monitor.saptennis.com 172.31.45.221 3000
|
||||
Use Tennis-Plain hellgate.saptennis.com 172.31.45.221 2003
|
||||
|
||||
# Piwik
|
||||
Use Tennis-With-SSL-Plain analytics.saptennis.com 172.31.45.221 8999
|
||||
|
||||
Use Tennis-SSL-Redirect media.saptennis.com
|
||||
|
||||
<VirtualHost *:80>
|
||||
ServerName hellgate.saptennis.com
|
||||
ProxyRequests Off
|
||||
<Proxy *>
|
||||
Order deny,allow
|
||||
Allow from all
|
||||
</Proxy>
|
||||
|
||||
<Location />
|
||||
ProxyPass http://172.31.45.221:2003/
|
||||
ProxyPassReverse http://172.31.45.221:2003/
|
||||
</Location>
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost *:443>
|
||||
ServerName tpc.wta-playerzone.com
|
||||
Use Headers
|
||||
|
||||
SSLEngine On
|
||||
SSLCertificateFile /etc/pki/tls/certs/tpc.wta-playerzone.com.crt
|
||||
SSLCertificateKeyFile /etc/pki/tls/private/tpc.wta-playerzone.com.key
|
||||
|
||||
RewriteEngine on
|
||||
RewriteRule ^(/)?$ "https://tpc.wta-playerzone.com/tpc/ui5" [L,NE]
|
||||
Use Rewrite 34.242.18.47 8888
|
||||
|
||||
<IfModule mod_mime.c>
|
||||
AddType text/css .css
|
||||
AddType application/x-javascript .js
|
||||
AddType text/x-component .htc
|
||||
AddType text/html .html .htm
|
||||
AddType text/richtext .rtf .rtx
|
||||
AddType image/svg+xml .svg .svgz
|
||||
AddType text/plain .txt
|
||||
AddType text/xsd .xsd
|
||||
AddType text/xsl .xsl
|
||||
AddType text/xml .xml
|
||||
AddType video/asf .asf .asx .wax .wmv .wmx
|
||||
AddType video/avi .avi
|
||||
AddType image/bmp .bmp
|
||||
AddType application/java .class
|
||||
AddType video/divx .divx
|
||||
AddType application/msword .doc .docx
|
||||
AddType application/vnd.ms-fontobject .eot
|
||||
AddType application/x-msdownload .exe
|
||||
AddType image/gif .gif
|
||||
AddType application/x-gzip .gz .gzip
|
||||
AddType image/x-icon .ico
|
||||
AddType image/jpeg .jpg .jpeg .jpe
|
||||
AddType application/vnd.ms-access .mdb
|
||||
AddType audio/midi .mid .midi
|
||||
AddType video/quicktime .mov .qt
|
||||
AddType audio/mpeg .mp3 .m4a
|
||||
AddType video/mp4 .mp4 .m4v
|
||||
AddType video/mpeg .mpeg .mpg .mpe
|
||||
AddType application/vnd.ms-project .mpp
|
||||
AddType application/x-font-otf .otf
|
||||
AddType application/vnd.oasis.opendocument.database .odb
|
||||
AddType application/vnd.oasis.opendocument.chart .odc
|
||||
AddType application/vnd.oasis.opendocument.formula .odf
|
||||
AddType application/vnd.oasis.opendocument.graphics .odg
|
||||
AddType application/vnd.oasis.opendocument.presentation .odp
|
||||
AddType application/vnd.oasis.opendocument.spreadsheet .ods
|
||||
AddType application/vnd.oasis.opendocument.text .odt
|
||||
AddType audio/ogg .ogg
|
||||
AddType application/pdf .pdf
|
||||
AddType image/png .png
|
||||
AddType application/vnd.ms-powerpoint .pot .pps .ppt .pptx
|
||||
AddType audio/x-realaudio .ra .ram
|
||||
AddType application/x-shockwave-flash .swf
|
||||
AddType application/x-tar .tar
|
||||
AddType image/tiff .tif .tiff
|
||||
AddType application/x-font-ttf .ttf .ttc
|
||||
AddType audio/wav .wav
|
||||
AddType audio/wma .wma
|
||||
AddType application/vnd.ms-write .wri
|
||||
AddType application/vnd.ms-excel .xla .xls .xlsx .xlt .xlw
|
||||
AddType application/zip .zip
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_deflate.c>
|
||||
# Force deflate for mangled headers developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping/
|
||||
<IfModule mod_setenvif.c>
|
||||
<IfModule mod_headers.c>
|
||||
SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
|
||||
RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
|
||||
</IfModule>
|
||||
</IfModule>
|
||||
|
||||
<IfModule filter_module>
|
||||
# HTML, TXT, CSS, JavaScript, JSON, XML, HTC:
|
||||
FilterDeclare COMPRESS
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$text/html'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$text/css'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$text/plain'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$text/xml'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$text/x-component'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$application/javascript'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$application/json'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$application/xml'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$application/xhtml+xml'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$application/rss+xml'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$application/atom+xml'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$application/vnd.ms-fontobject'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$image/svg+xml'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$image/x-icon'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$image/gif'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$image/jpeg'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$image/png'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$application/x-font-ttf'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$font/opentype'"
|
||||
FilterChain COMPRESS
|
||||
FilterProtocol COMPRESS DEFLATE change=yes;byteranges=no
|
||||
</IfModule>
|
||||
|
||||
<IfModule !mod_filter.c>
|
||||
# Legacy versions of Apache
|
||||
AddOutputFilterByType DEFLATE text/html text/plain text/css application/json
|
||||
AddOutputFilterByType DEFLATE application/javascript
|
||||
AddOutputFilterByType DEFLATE text/xml application/xml text/x-component
|
||||
AddOutputFilterByType DEFLATE application/xhtml+xml application/rss+xml application/atom+xml
|
||||
AddOutputFilterByType DEFLATE image/x-icon image/svg+xml application/vnd.ms-fontobject application/x-font-ttf font/opentype
|
||||
</IfModule>
|
||||
|
||||
</IfModule>
|
||||
</VirtualHost>
|
||||
<VirtualHost *:80>
|
||||
ServerName tpc.wta-playerzone.com
|
||||
Use Headers
|
||||
RewriteEngine on
|
||||
RewriteRule ^(/)?$ "http://tpc.wta-playerzone.com/tpc/ui5" [L,NE]
|
||||
Use Rewrite 34.242.18.47 8888
|
||||
|
||||
<IfModule mod_mime.c>
|
||||
AddType text/css .css
|
||||
AddType application/x-javascript .js
|
||||
AddType text/x-component .htc
|
||||
AddType text/html .html .htm
|
||||
AddType text/richtext .rtf .rtx
|
||||
AddType image/svg+xml .svg .svgz
|
||||
AddType text/plain .txt
|
||||
AddType text/xsd .xsd
|
||||
AddType text/xsl .xsl
|
||||
AddType text/xml .xml
|
||||
AddType video/asf .asf .asx .wax .wmv .wmx
|
||||
AddType video/avi .avi
|
||||
AddType image/bmp .bmp
|
||||
AddType application/java .class
|
||||
AddType video/divx .divx
|
||||
AddType application/msword .doc .docx
|
||||
AddType application/vnd.ms-fontobject .eot
|
||||
AddType application/x-msdownload .exe
|
||||
AddType image/gif .gif
|
||||
AddType application/x-gzip .gz .gzip
|
||||
AddType image/x-icon .ico
|
||||
AddType image/jpeg .jpg .jpeg .jpe
|
||||
AddType application/vnd.ms-access .mdb
|
||||
AddType audio/midi .mid .midi
|
||||
AddType video/quicktime .mov .qt
|
||||
AddType audio/mpeg .mp3 .m4a
|
||||
AddType video/mp4 .mp4 .m4v
|
||||
AddType video/mpeg .mpeg .mpg .mpe
|
||||
AddType application/vnd.ms-project .mpp
|
||||
AddType application/x-font-otf .otf
|
||||
AddType application/vnd.oasis.opendocument.database .odb
|
||||
AddType application/vnd.oasis.opendocument.chart .odc
|
||||
AddType application/vnd.oasis.opendocument.formula .odf
|
||||
AddType application/vnd.oasis.opendocument.graphics .odg
|
||||
AddType application/vnd.oasis.opendocument.presentation .odp
|
||||
AddType application/vnd.oasis.opendocument.spreadsheet .ods
|
||||
AddType application/vnd.oasis.opendocument.text .odt
|
||||
AddType audio/ogg .ogg
|
||||
AddType application/pdf .pdf
|
||||
AddType image/png .png
|
||||
AddType application/vnd.ms-powerpoint .pot .pps .ppt .pptx
|
||||
AddType audio/x-realaudio .ra .ram
|
||||
AddType application/x-shockwave-flash .swf
|
||||
AddType application/x-tar .tar
|
||||
AddType image/tiff .tif .tiff
|
||||
AddType application/x-font-ttf .ttf .ttc
|
||||
AddType audio/wav .wav
|
||||
AddType audio/wma .wma
|
||||
AddType application/vnd.ms-write .wri
|
||||
AddType application/vnd.ms-excel .xla .xls .xlsx .xlt .xlw
|
||||
AddType application/zip .zip
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_deflate.c>
|
||||
# Force deflate for mangled headers developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping/
|
||||
<IfModule mod_setenvif.c>
|
||||
<IfModule mod_headers.c>
|
||||
SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
|
||||
RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
|
||||
</IfModule>
|
||||
</IfModule>
|
||||
|
||||
<IfModule filter_module>
|
||||
# HTML, TXT, CSS, JavaScript, JSON, XML, HTC:
|
||||
FilterDeclare COMPRESS
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$text/html'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$text/css'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$text/plain'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$text/xml'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$text/x-component'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$application/javascript'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$application/json'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$application/xml'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$application/xhtml+xml'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$application/rss+xml'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$application/atom+xml'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$application/vnd.ms-fontobject'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$image/svg+xml'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$image/x-icon'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$image/gif'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$image/jpeg'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$image/png'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$application/x-font-ttf'"
|
||||
FilterProvider COMPRESS DEFLATE "%{Content_Type} = '$font/opentype'"
|
||||
FilterChain COMPRESS
|
||||
FilterProtocol COMPRESS DEFLATE change=yes;byteranges=no
|
||||
</IfModule>
|
||||
|
||||
<IfModule !mod_filter.c>
|
||||
# Legacy versions of Apache
|
||||
AddOutputFilterByType DEFLATE text/html text/plain text/css application/json
|
||||
AddOutputFilterByType DEFLATE application/javascript
|
||||
AddOutputFilterByType DEFLATE text/xml application/xml text/x-component
|
||||
AddOutputFilterByType DEFLATE application/xhtml+xml application/rss+xml application/atom+xml
|
||||
AddOutputFilterByType DEFLATE image/x-icon image/svg+xml application/vnd.ms-fontobject application/x-font-ttf font/opentype
|
||||
</IfModule>
|
||||
|
||||
</IfModule>
|
||||
</VirtualHost>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
# sail-insight.com
|
||||
<VirtualHost *:80>
|
||||
ServerName sail-insight.com
|
||||
ServerAlias www.sail-insight.com
|
||||
RedirectPermanent / https://sail-insight.com/
|
||||
</VirtualHost>
|
||||
|
||||
<Macro SSL-sail-insight>
|
||||
SSLEngine On
|
||||
SSLCertificateFile /etc/letsencrypt/live/sail-insight.com/cert.pem
|
||||
SSLCertificateKeyFile /etc/letsencrypt/live/sail-insight.com/privkey.pem
|
||||
SSLCertificateChainFile /etc/letsencrypt/live/sail-insight.com/fullchain.pem
|
||||
</Macro>
|
||||
|
||||
<VirtualHost *:443>
|
||||
ServerName sail-insight.com
|
||||
ServerAlias www.sail-insight.com
|
||||
Use SSL-sail-insight
|
||||
CustomLog logs/services_log combined env=!original_client_ip
|
||||
CustomLog logs/services_log first_forwarded_for_ip env=original_client_ip
|
||||
Alias / /home/trac/sail-insight-website/
|
||||
<Directory /home/trac/sail-insight-website>
|
||||
Options Indexes FollowSymLinks MultiViews
|
||||
AllowOverride All
|
||||
Order allow,deny
|
||||
allow from all
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
@@ -0,0 +1 @@
|
||||
Use Event-ARCHIVE 49erEuros2023.sapsailing.com ebe42774-76e1-4f9d-8e3a-829cc263088e
|
||||
@@ -25,7 +25,6 @@ Alias /unique-visitors/ "/var/log/old/cache/unique-ips-per-referrer/stats/"
|
||||
#
|
||||
<VirtualHost *:80>
|
||||
ServerName awstats.sapsailing.com
|
||||
Use SSL
|
||||
CustomLog logs/awstats_access_log combined
|
||||
ErrorLog logs/awstats_error_log
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Use Home-ARCHIVE bundesliga2023.sapsailing.com
|
||||
@@ -0,0 +1 @@
|
||||
Use Event-ARCHIVE cnr2023.sapsailing.com 4e2b2383-ec2c-4a12-ae1d-61ba170b1b6f
|
||||
@@ -0,0 +1 @@
|
||||
Use Home-ARCHIVE danishleague2023.sapsailing.com
|
||||
@@ -0,0 +1 @@
|
||||
Use Home-ARCHIVE finalregionalny2023.sapsailing.com
|
||||
@@ -0,0 +1 @@
|
||||
Use Event-ARCHIVE frenchleague2023.sapsailing.com 289ee506-e8de-42e3-b726-f339fdba3b31
|
||||
@@ -0,0 +1 @@
|
||||
Use Home-ARCHIVE norwegianleague2023.sapsailing.com
|
||||
@@ -1,49 +0,0 @@
|
||||
LoadModule perl_module modules/mod_perl.so
|
||||
#
|
||||
# Mod_perl incorporates a Perl interpreter into the Apache web server,
|
||||
# so that the Apache web server can directly execute Perl code.
|
||||
# Mod_perl links the Perl runtime library into the Apache web server
|
||||
# and provides an object-oriented Perl interface for Apache's C
|
||||
# language API. The end result is a quicker CGI script turnaround
|
||||
# process, since no external Perl interpreter has to be started.
|
||||
#
|
||||
|
||||
# Uncomment this line to globally enable warnings, which will be
|
||||
# written to the server's error log. Warnings should be enabled
|
||||
# during the development process, but should be disabled on a
|
||||
# production server as they affect performance.
|
||||
#
|
||||
#PerlSwitches -w
|
||||
|
||||
# Uncomment this line to enable taint checking globally. When Perl is
|
||||
# running in taint mode various checks are performed to reduce the
|
||||
# risk of insecure data being passed to a subshell or being used to
|
||||
# modify the filesystem. Unfortunately many Perl modules are not
|
||||
# taint-safe, so you should exercise care before enabling it on a
|
||||
# production server.
|
||||
#
|
||||
#PerlSwitches -T
|
||||
|
||||
# This will allow execution of mod_perl to compile your scripts to
|
||||
# subroutines which it will execute directly, avoiding the costly
|
||||
# compile process for most requests.
|
||||
#
|
||||
#Alias /perl /var/www/perl
|
||||
#<Directory /var/www/perl>
|
||||
# SetHandler perl-script
|
||||
# PerlResponseHandler ModPerl::Registry
|
||||
# PerlOptions +ParseHeaders
|
||||
# Options +ExecCGI
|
||||
#</Directory>
|
||||
|
||||
# This will allow remote server configuration reports, with the URL of
|
||||
# http://servername/perl-status
|
||||
# Change the ".example.com" to match your domain to enable.
|
||||
#
|
||||
#<Location /perl-status>
|
||||
# SetHandler perl-script
|
||||
# PerlResponseHandler Apache2::Status
|
||||
# Order deny,allow
|
||||
# Deny from all
|
||||
# Allow from .example.com
|
||||
#</Location>
|
||||
@@ -0,0 +1 @@
|
||||
Use Home-ARCHIVE scl2023.sapsailing.com
|
||||
@@ -0,0 +1 @@
|
||||
Use Home-ARCHIVE trojmiejskaliga2023.sapsailing.com
|
||||
+5
-2
@@ -1,6 +1,9 @@
|
||||
<VirtualHost *:443>
|
||||
# The problem with this is that Wordpress seems to redirect to https,
|
||||
# leading to an endless redirect loop when the ALB then receives the
|
||||
# https request, does the SSL handling and forwards as an http request
|
||||
# to here again...
|
||||
<VirtualHost *:80>
|
||||
ServerName blog.sapsailing.com
|
||||
Use SSL
|
||||
CustomLog logs/blog_log combined
|
||||
DocumentRoot /home/wordpress/wordpress
|
||||
<Directory /home/wordpress/wordpress>
|
||||
@@ -0,0 +1 @@
|
||||
Use Home-ARCHIVE wow2023.sapsailing.com
|
||||
@@ -55,12 +55,12 @@ clean_httpd_logs() {
|
||||
echo "Clearing httpd logs" >>/var/log/sailing.err
|
||||
service httpd stop
|
||||
rm -rf /var/log/httpd/*
|
||||
rm /etc/httpd/conf.d/001-internals.conf
|
||||
rm -f /etc/httpd/conf.d/001-internals.conf
|
||||
}
|
||||
|
||||
clean_startup_logs() {
|
||||
echo "Clearing bootstrap logs" >>/var/log/sailing.err
|
||||
rm /var/log/sailing*
|
||||
rm -f /var/log/sailing*
|
||||
# Ensure that upon the next boot the reboot indicator is not present, indicating that it's the first boot
|
||||
rm "${REBOOT_INDICATOR}"
|
||||
}
|
||||
@@ -95,7 +95,7 @@ finalize() {
|
||||
else
|
||||
# Only clean ${LOGON_USER_HOME}/.ssh directory and /tmp/image-upgrade-finished if the next step is shutdown / image creation
|
||||
clean_root_ssh_dir_and_tmp
|
||||
rm /var/log/sailing.err
|
||||
rm -f /var/log/sailing.err
|
||||
shutdown -h now &
|
||||
fi
|
||||
}
|
||||
|
||||
Executable
+114
@@ -0,0 +1,114 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Purpose: Script is used to switch to the failover archive if the primary is unhealthy, by altering the macros
|
||||
# file and then reloading Httpd.
|
||||
# Crontab for every minute: * * * * * /path/to/switchoverArchive.sh
|
||||
help() {
|
||||
echo "$0 PATH_TO_HTTPD_MACROS_FILE TIMEOUT_FIRST_CURL_SECONDS TIMEOUT_SECOND_CURL_SECONDS"
|
||||
echo ""
|
||||
echo "Script used to automatically update the archive location (to the failover) in httpd if the primary is down."
|
||||
echo "Pass in the path to the macros file containing the archive definitions;"
|
||||
echo "the timeout of the first curl check in seconds; and the timeout of the second curl check, also in seconds."
|
||||
echo "Make sure the combined time taken is not longer than the crontab."
|
||||
exit 2
|
||||
}
|
||||
# $# is the number of arguments
|
||||
if [ $# -eq 0 ]; then
|
||||
help
|
||||
fi
|
||||
#The names of the variables in the macros file.
|
||||
ARCHIVE_IP_NAME="ARCHIVE_IP"
|
||||
ARCHIVE_FAILOVER_IP_NAME="ARCHIVE_FAILOVER_IP"
|
||||
PRODUCTION_ARCHIVE_NAME="PRODUCTION_ARCHIVE"
|
||||
ARCHIVE_PORT=8888
|
||||
MACROS_PATH=$1
|
||||
# The amount of time (in seconds) that must have elapsed, since the last httpd macros email, before notifying operators again.
|
||||
TIME_CHECK_SECONDS=$((15*60))
|
||||
# Connection timeouts for curl requests (the time waited for a connection to be established). The second should be longer
|
||||
# as we want to be confident the main archive is in fact "down" before switching.
|
||||
TIMEOUT1_IN_SECONDS=$2
|
||||
TIMEOUT2_IN_SECONDS=$3
|
||||
CACHE_LOCATION="/var/cache/lastIncorrectMacroUnixTime"
|
||||
# The following line checks if all the strings in "search" are present at the beginning of their own line. Note: grep uses BRE by default,
|
||||
# so the plus symbol must be escaped to refer to "one or more" of the previous character.
|
||||
for i in "^Define ${PRODUCTION_ARCHIVE_NAME}\>" \
|
||||
"^Define ${ARCHIVE_IP_NAME} [0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$" \
|
||||
"^Define ${ARCHIVE_FAILOVER_IP_NAME} [0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$"
|
||||
do
|
||||
if ! grep -q "${i}" "${MACROS_PATH}"; then
|
||||
currentUnixTime=$(date +"%s")
|
||||
if [[ ! -f ${CACHE_LOCATION} || $((currentUnixTime - $(cat "${CACHE_LOCATION}") )) -gt "$TIME_CHECK_SECONDS" ]]; then
|
||||
date +"%s" > "${CACHE_LOCATION}"
|
||||
echo "Macros file does not contain proper definitions for the archive and failover IPs. Expression ${i} not matched." | notify-operators "Incorrect httpd macros"
|
||||
fi
|
||||
logger -t archive "Necessary variable assignment pattern ${i} not found in macros"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
# These next lines get the current ip values for the archive and failover, plus they store the value of production,
|
||||
# which is a variable pointing to either the primary or failover value.
|
||||
archiveIp="$(sed -n -e "s/^Define ${ARCHIVE_IP_NAME} \(.*\)/\1/p" ${MACROS_PATH} | tr -d '[:space:]')"
|
||||
failoverIp="$(sed -n -e "s/^Define ${ARCHIVE_FAILOVER_IP_NAME} \(.*\)/\1/p" ${MACROS_PATH} | tr -d '[:space:]')"
|
||||
productionIp="$(sed -n -e "s/^Define ${PRODUCTION_ARCHIVE_NAME} \(.*\)/\1/p" ${MACROS_PATH} | tr -d '[:space:]')"
|
||||
# Checks if the macro.conf is set as healthy or unhealthy currently.
|
||||
if [[ "${productionIp}" == "\${${ARCHIVE_IP_NAME}}" ]]
|
||||
then
|
||||
alreadyHealthy=1
|
||||
logger -t archive "currently healthy"
|
||||
else
|
||||
alreadyHealthy=0
|
||||
logger -t archive "currently unhealthy"
|
||||
fi
|
||||
|
||||
setProduction() {
|
||||
# parameter $1: the name of the variable holding the IP of the archive instance to switch to
|
||||
sed -i -e "s/^Define ${PRODUCTION_ARCHIVE_NAME}\>.*$/Define ${PRODUCTION_ARCHIVE_NAME} \${${1}}/" ${MACROS_PATH}
|
||||
}
|
||||
|
||||
# Sets the production value to point to the variable defining the main archive IP, provided it isn't already set.
|
||||
setProductionMainIfNotSet() {
|
||||
if [[ $alreadyHealthy -eq 0 ]]
|
||||
then
|
||||
# currently unhealthy
|
||||
# set production to archive
|
||||
logger -t archive "Healthy: setting production to main archive"
|
||||
setProduction ${ARCHIVE_IP_NAME}
|
||||
systemctl reload httpd
|
||||
echo "The main archive server is healthy again. Switching to it." | notify-operators "Healthy: main archive online"
|
||||
else
|
||||
# If already healthy then no reload or notification occurs.
|
||||
logger -t archive "Healthy: already set, no change needed"
|
||||
fi
|
||||
}
|
||||
|
||||
setFailoverIfNotSet() {
|
||||
if [[ $alreadyHealthy -eq 1 ]]
|
||||
then
|
||||
# Set production to failover if not already. Separate if statement in case the curl statement
|
||||
# fails but the production is already set to point to the backup
|
||||
setProduction ${ARCHIVE_FAILOVER_IP_NAME}
|
||||
logger -t archive "Unhealthy: second check failed, switching to failover"
|
||||
systemctl reload httpd
|
||||
echo "Main archive is unhealthy. Switching to failover. Please urgently take a look at ${archiveIp}." | notify-operators "Unhealthy: main archive offline, failover in place"
|
||||
else
|
||||
logger -t archive "Unhealthy: second check still fails, failover already in use"
|
||||
fi
|
||||
}
|
||||
|
||||
logger -t archive "begin check"
|
||||
# --fail option ensures that, if a server error is returned (ie. 5xx/4xx status code), then the status code (stored in $?) will be non zero.
|
||||
# -L follows redirects
|
||||
curl -s -L --fail --connect-timeout ${TIMEOUT1_IN_SECONDS} "http://${archiveIp}:${ARCHIVE_PORT}/gwt/status" >> /dev/null
|
||||
if [[ $? -ne 0 ]]
|
||||
then
|
||||
logger -t archive "first check failed"
|
||||
curl -s -L --fail --connect-timeout ${TIMEOUT2_IN_SECONDS} "http://${archiveIp}:${ARCHIVE_PORT}/gwt/status" >> /dev/null
|
||||
if [[ $? -ne 0 ]]
|
||||
then
|
||||
setFailoverIfNotSet
|
||||
else
|
||||
setProductionMainIfNotSet
|
||||
fi
|
||||
else
|
||||
setProductionMainIfNotSet
|
||||
fi
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
ADMIN_EMAIL="axel.uhl@sap.com jan.hamann@sapsailing.com"
|
||||
|
||||
cd /home/wiki/gitwiki
|
||||
git pull >/tmp/wiki-git.out 2>/tmp/wiki-git.err
|
||||
if [ "$?" != "0" ]; then
|
||||
cat /tmp/wiki-git.out /tmp/wiki-git.err | mail -s "Wiki git problem" $ADMIN_EMAIL
|
||||
fi
|
||||
git push >>/tmp/wiki-git.out 2>/tmp/wiki-git.err
|
||||
if [ "$?" != "0" ]; then
|
||||
cat /tmp/wiki-git.out /tmp/wiki-git.err | mail -s "Wiki git problem" $ADMIN_EMAIL
|
||||
fi
|
||||
@@ -392,15 +392,45 @@ https://event3.tractrac.com/events/event_20221211_TestOceanR/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230223_TheOceanRa/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230328_TrofeoSARP/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230329_AllianzReg/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230329_SailingCha1/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230420_TheOceanRa/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230421_FrenchOlym/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230427_SailingCha1/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230505_NorskSeils/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230511_SegelBunde/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230517_Sejlsports/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230520_Sejlsports/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230603_TheOceanRa/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230607_HelgaCup/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230609_Sejlsports1/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230614_SailingCha1/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230614_TheOceanRa/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230616_Sejlsports/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230621_NorskSeils/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230629_TheOceanRa/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230706_ParisOlymp/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230721_SailingCha1/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230727_SegelBunde/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230801_NorskSeils/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230809_AllianzPar/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230809_AllianzSai1/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230812_CopyofSejl/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230812_Sejlsports/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230818_SegelBunde/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230818_Ungdomslig/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230826_Sejlsports/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230831_SailingCha1/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230902_Sejlsports/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230913_SailingCha1/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230914_SegelBunde/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230922_NorskSeils/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230923_XYachtsSta/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20230930_Ungdomslig/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20231005_CopyofSege/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20231011_LigueNatio/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20231012_MesternesM/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20231018_SegelBunde/jsonservice.php
|
||||
https://event3.tractrac.com/events/event_20231105_Europeaner/jsonservice.php
|
||||
https://event.tractrac.com/events/event_20170727_Travemnder2/jsonservice.php
|
||||
https://event.tractrac.com/events/event_20171013_DSLPokalGl/jsonservice.php
|
||||
https://event.tractrac.com/events/event_20181012_MstarnasMs/jsonservice.php
|
||||
@@ -475,6 +505,7 @@ https://event.tractrac.com/events/event_20211017_KornatiCup/jsonservice.php
|
||||
https://event.tractrac.com/events/event_20211115_ererFxNacr/jsonservice.php
|
||||
https://event.tractrac.com/events/event_20211210_YouthSaili/jsonservice.php
|
||||
https://event.tractrac.com/events/event_20220626_KielerWoch/jsonservice.php
|
||||
https://event.tractrac.com/events/event_20230324_SAILINGCha/jsonservice.php
|
||||
https://event.tractrac.com/events/event_20230531_ERERFXNACR/jsonservice.php
|
||||
https://event.tractrac.com/events/event_20230611_KielerWoch/jsonservice.php
|
||||
https://event.tractrac.com/events/event_20230622_KielerWoch/jsonservice.php
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
FROM docker.sapsailing.com/sapjvm8:8.1.095
|
||||
FROM docker.sapsailing.com/sapjvm8:8.1.096
|
||||
ARG RELEASE
|
||||
LABEL maintainer=axel.uhl@sap.com
|
||||
# Download and extract the release
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
FROM buildpack-deps:bullseye
|
||||
ARG SAPJVM_VERSION=8.1.095
|
||||
ARG SAPJVM_VERSION=8.1.096
|
||||
LABEL maintainer=axel.uhl@sap.com
|
||||
# Download and extract the SAP JVM 8
|
||||
ENV PATH=${PATH}:/opt/sapjvm_8/bin
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG SAPJVM_VERSION=8.1.095
|
||||
ARG SAPJVM_VERSION=8.1.096
|
||||
FROM docker.sapsailing.com/sapjvm8:${SAPJVM_VERSION}
|
||||
LABEL maintainer=axel.uhl@sap.com
|
||||
# Download and extract the release
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
version: "3.9"
|
||||
services:
|
||||
sailing-analytics:
|
||||
image: "docker.sapsailing.com:443/sapsailing:latest"
|
||||
image: "docker.sapsailing.com/sapsailing:latest"
|
||||
ports:
|
||||
- "8888:8888"
|
||||
- "6666:6666"
|
||||
|
||||
@@ -26,6 +26,7 @@ SAP is at the center of today’s technology revolution, developing innovations
|
||||
* [[User Management|wiki/info/landscape/usermanagement]]
|
||||
* [[Development Environment|wiki/info/landscape/development-environment]]
|
||||
* [[Production Environment|wiki/info/landscape/production-environment]]
|
||||
* [[Internationalization (i18n)|wiki/howto/development/i18n]]
|
||||
* [[Typical Development Scenarios|wiki/info/landscape/typical-development-scenarios]]
|
||||
* [[RaceLog Tracking Server Architecture|wiki/info/landscape/server]]
|
||||
* Environment Overview [[PDF|wiki/info/mobile/event-tracking/architecture.pdf]] | [[SVG|wiki/info/mobile/event-tracking/architecture.svg]]
|
||||
|
||||
+3
-2
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.competitorimport;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -32,7 +33,7 @@ public interface CompetitorProvider extends Named {
|
||||
* competitor names. Should the value for a key be <code>null</code>, competitors for the event may still
|
||||
* be available, only they may not be keyed per regatta in that case.
|
||||
*/
|
||||
Map<String, Set<String>> getHasCompetitorsForRegattasInEvent() throws IOException;
|
||||
Map<String, Set<String>> getHasCompetitorsForRegattasInEvent() throws IOException, URISyntaxException;
|
||||
|
||||
/**
|
||||
* Obtains competitor records from the source of import
|
||||
@@ -44,7 +45,7 @@ public interface CompetitorProvider extends Named {
|
||||
* <code>eventName</code>, or a regatta name as provided in the value set for the key
|
||||
* <code>eventName</code> as returned by {@link #getHasCompetitorsForRegattasInEvent()}.
|
||||
*/
|
||||
Iterable<CompetitorDescriptor> getCompetitorDescriptors(String eventName, String regattaName) throws JAXBException, IOException;
|
||||
Iterable<CompetitorDescriptor> getCompetitorDescriptors(String eventName, String regattaName) throws JAXBException, IOException, URISyntaxException;
|
||||
|
||||
/**
|
||||
* A hint for users about this competitor provider; ideally mapped to the user's locale with i18n support.
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.sap.sailing.datamining.shared;
|
||||
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.settings.SerializableSettings;
|
||||
|
||||
public class TackTypeSegmentsDataMiningSettings extends SerializableSettings {
|
||||
private static final long serialVersionUID = 3239182650750480678L;
|
||||
private final Duration minimumTackTypeSegmentDuration;
|
||||
private final Duration minimumDurationBetweenAdjacentTackTypeSegments;
|
||||
|
||||
public TackTypeSegmentsDataMiningSettings(Duration minimumTackTypeSegmentDuration, Duration minimumDurationBetweenAdjacentTackTypeSegments) {
|
||||
super();
|
||||
this.minimumTackTypeSegmentDuration = minimumTackTypeSegmentDuration;
|
||||
this.minimumDurationBetweenAdjacentTackTypeSegments = minimumDurationBetweenAdjacentTackTypeSegments;
|
||||
}
|
||||
|
||||
public Duration getMinimumTackTypeSegmentDuration() {
|
||||
return minimumTackTypeSegmentDuration;
|
||||
}
|
||||
public Duration getMinimumDurationBetweenAdjacentTackTypeSegments() {
|
||||
return minimumDurationBetweenAdjacentTackTypeSegments;
|
||||
}
|
||||
|
||||
public static TackTypeSegmentsDataMiningSettings createDefaultSettings() {
|
||||
return new TackTypeSegmentsDataMiningSettings(
|
||||
/* minimumTackTypeSegmentDuration */ null,
|
||||
/* minimumDurationBetweenAdjacentTackTypeSegments */ null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,5 +12,8 @@ Import-Package: junit.framework;version="4.8.2",
|
||||
Require-Bundle: org.mockito.mockito-core;bundle-version="4.8.1",
|
||||
org.hamcrest;bundle-version="2.2.0",
|
||||
com.sap.sse.common,
|
||||
org.objenesis;bundle-version="2.1.0"
|
||||
org.objenesis;bundle-version="2.1.0",
|
||||
net.bytebuddy.byte-buddy;bundle-version="1.12.18",
|
||||
net.bytebuddy.byte-buddy-agent;bundle-version="1.12.18",
|
||||
com.sap.sailing.domain.test
|
||||
Automatic-Module-Name: com.sap.sailing.datamining.test
|
||||
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
package com.sap.sailing.datamining.impl.components;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasLeaderboardContext;
|
||||
import com.sap.sailing.datamining.data.HasRaceOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.data.HasTackTypeSegmentContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
|
||||
import com.sap.sailing.datamining.impl.data.LeaderboardWithContext;
|
||||
import com.sap.sailing.datamining.impl.data.RaceOfCompetitorWithContext;
|
||||
import com.sap.sailing.datamining.impl.data.TrackedRaceWithContext;
|
||||
import com.sap.sailing.datamining.shared.TackTypeSegmentsDataMiningSettings;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.base.impl.CourseAreaImpl;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.impl.FlexibleLeaderboardImpl;
|
||||
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
|
||||
import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
|
||||
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
||||
import com.sap.sailing.domain.test.StoredTrackBasedTest;
|
||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
|
||||
import com.sap.sailing.domain.tracking.impl.MarkPassingImpl;
|
||||
import com.sap.sse.common.Distance;
|
||||
import com.sap.sse.common.Distance.NullDistance;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
public class TestSegmentsTackType extends StoredTrackBasedTest {
|
||||
|
||||
private DynamicTrackedRaceImpl trackedRace;
|
||||
private CompetitorWithBoat competitorA;
|
||||
private HasRaceOfCompetitorContext raceOfCompContext;
|
||||
private TackTypeSegmentRetrievalProcessor resultTTSegmentsRetrieval;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
competitorA = createCompetitorWithBoat("A");
|
||||
trackedRace = createTestTrackedRace("TestRegatta", "TestRace", "F18", createCompetitorAndBoatsMap(competitorA),
|
||||
MillisecondsTimePoint.now(), /* useMarkPassingCalculator */ true, null,
|
||||
OneDesignRankingMetric::new);
|
||||
final Leaderboard leaderboard = new FlexibleLeaderboardImpl("Test",
|
||||
new ThresholdBasedResultDiscardingRuleImpl(new int[0]), new LowPoint(),
|
||||
new CourseAreaImpl("Here", UUID.randomUUID(), /* centerPosition */ null, /* radius */ null));
|
||||
final HasLeaderboardContext leaderboardContext = new LeaderboardWithContext(leaderboard, null);
|
||||
final HasTrackedRaceContext trackedRaceContext = new TrackedRaceWithContext(leaderboardContext,
|
||||
trackedRace.getTrackedRegatta().getRegatta(), null, null, trackedRace);
|
||||
raceOfCompContext = new RaceOfCompetitorWithContext(trackedRaceContext, competitorA, TackTypeSegmentsDataMiningSettings.createDefaultSettings());
|
||||
resultTTSegmentsRetrieval = new TackTypeSegmentRetrievalProcessor(null, Collections.emptySet(), TackTypeSegmentsDataMiningSettings.createDefaultSettings(), 0, null);
|
||||
}
|
||||
|
||||
private Iterable<HasTackTypeSegmentContext> retrieveData() {
|
||||
return resultTTSegmentsRetrieval.retrieveData(raceOfCompContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testingSegmentsAreNotNull() {
|
||||
// set up GPS fixes for competitor, as well as mark passings:
|
||||
DynamicGPSFixTrack<Competitor, GPSFixMoving> competitorATrack = trackedRace.getTrack(competitorA);
|
||||
final KnotSpeedWithBearingImpl sogCog = new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(45));
|
||||
TimePoint timePoint = trackedRace.getStartOfTracking().plus(10);
|
||||
GPSFixMovingImpl currentGPS = new GPSFixMovingImpl(new DegreePosition(54.4680424, 10.234451), timePoint, sogCog);
|
||||
final Duration timeBetweenFixes = Duration.ofMillis(490);
|
||||
for (int i=0; i<20; i++) {
|
||||
competitorATrack.addGPSFix(currentGPS);
|
||||
final Position currentPosition = sogCog.travelTo(currentGPS.getPosition(), timeBetweenFixes);
|
||||
timePoint = timePoint.plus(timeBetweenFixes);
|
||||
currentGPS = new GPSFixMovingImpl(currentPosition, timePoint, sogCog);
|
||||
}
|
||||
TimePoint markPassingTimePoint = trackedRace.getStartOfTracking().plus(20);
|
||||
final List<MarkPassing> markPassingsForCompetitor = new ArrayList<>();
|
||||
final Duration legDuration = Duration.ofSeconds(60);
|
||||
for (Waypoint waypoint : trackedRace.getRace().getCourse().getWaypoints()) {
|
||||
markPassingsForCompetitor.add(new MarkPassingImpl(markPassingTimePoint, waypoint, competitorA));
|
||||
markPassingTimePoint = markPassingTimePoint.plus(legDuration);
|
||||
}
|
||||
trackedRace.updateMarkPassings(competitorA, markPassingsForCompetitor);
|
||||
assertNotNull(trackedRace.getEndOfRace());
|
||||
// now run the actual test:
|
||||
final Iterable<HasTackTypeSegmentContext> allTTSegments = retrieveData();
|
||||
Distance sumDistance = new NullDistance();
|
||||
for (HasTackTypeSegmentContext oneTTSegment : allTTSegments) {
|
||||
if (oneTTSegment != null) {
|
||||
sumDistance = sumDistance.add(oneTTSegment.getDistance());
|
||||
}
|
||||
}
|
||||
assertTrue(sumDistance.compareTo(Distance.NULL) > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testingMissingMarkPassing() {
|
||||
// set up GPS fixes for competitor, but no mark passings:
|
||||
DynamicGPSFixTrack<Competitor, GPSFixMoving> competitorATrack = trackedRace.getTrack(competitorA);
|
||||
final KnotSpeedWithBearingImpl sogCog = new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(45));
|
||||
TimePoint timePoint = trackedRace.getStartOfTracking().plus(10);
|
||||
GPSFixMovingImpl currentGPS = new GPSFixMovingImpl(new DegreePosition(54.4680424, 10.234451), timePoint, sogCog);
|
||||
final Duration timeBetweenFixes = Duration.ofMillis(490);
|
||||
for (int i=0; i<20; i++) {
|
||||
competitorATrack.addGPSFix(currentGPS);
|
||||
final Position currentPosition = sogCog.travelTo(currentGPS.getPosition(), timeBetweenFixes);
|
||||
timePoint = timePoint.plus(timeBetweenFixes);
|
||||
currentGPS = new GPSFixMovingImpl(currentPosition, timePoint, sogCog);
|
||||
}
|
||||
// now run the actual test:
|
||||
final Iterable<HasTackTypeSegmentContext> allTTSegments = retrieveData();
|
||||
assertTrue(Util.isEmpty(allTTSegments));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testingFixExactlyOnMarkPassingAndRaceOpenEnded() {
|
||||
final List<TimePoint> expectedSegmentStarts = new ArrayList<>();
|
||||
// set up GPS fixes for competitor, as well as mark passings:
|
||||
DynamicGPSFixTrack<Competitor, GPSFixMoving> competitorATrack = trackedRace.getTrack(competitorA);
|
||||
// start on port tack:
|
||||
final KnotSpeedWithBearingImpl sogCogPortTackUpwind = new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(45));
|
||||
TimePoint timePoint = trackedRace.getStartOfTracking().plus(10);
|
||||
final Position middleOfStartLine = trackedRace.getApproximatePosition(trackedRace.getRace().getCourse().getFirstWaypoint(), timePoint);
|
||||
final Position topMarkPosition = trackedRace.getApproximatePosition(Util.get(trackedRace.getRace().getCourse().getWaypoints(), 1), timePoint);
|
||||
// start straight "under" the top mark
|
||||
GPSFixMovingImpl currentGPS = new GPSFixMovingImpl(new DegreePosition(middleOfStartLine.getLatDeg(), topMarkPosition.getLngDeg()), timePoint, sogCogPortTackUpwind);
|
||||
expectedSegmentStarts.add(timePoint);
|
||||
final Duration timeBetweenFixes = Duration.ofMillis(490);
|
||||
for (int i=0; i<20; i++) {
|
||||
competitorATrack.addGPSFix(currentGPS);
|
||||
final Position currentPosition = sogCogPortTackUpwind.travelTo(currentGPS.getPosition(), timeBetweenFixes);
|
||||
timePoint = timePoint.plus(timeBetweenFixes);
|
||||
currentGPS = new GPSFixMovingImpl(currentPosition, timePoint, sogCogPortTackUpwind);
|
||||
}
|
||||
// now tack onto starboard tack:
|
||||
final KnotSpeedWithBearingImpl sogCogStarboardTackUpwind = new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(315));
|
||||
expectedSegmentStarts.add(timePoint);
|
||||
for (int i=0; i<20; i++) {
|
||||
competitorATrack.addGPSFix(currentGPS);
|
||||
final Position currentPosition = sogCogStarboardTackUpwind.travelTo(currentGPS.getPosition(), timeBetweenFixes);
|
||||
timePoint = timePoint.plus(timeBetweenFixes);
|
||||
currentGPS = new GPSFixMovingImpl(currentPosition, timePoint, sogCogStarboardTackUpwind);
|
||||
}
|
||||
final List<MarkPassing> markPassingsForCompetitor = new ArrayList<>();
|
||||
final TimePoint startMarkPassingTimePoint = trackedRace.getStartOfTracking().plus(20);
|
||||
markPassingsForCompetitor.add(new MarkPassingImpl(startMarkPassingTimePoint, trackedRace.getRace().getCourse().getFirstWaypoint(), competitorA));
|
||||
final TimePoint windwardMarkPassingTimePoint = timePoint; // exactly the time point of the last fix
|
||||
markPassingsForCompetitor.add(new MarkPassingImpl(windwardMarkPassingTimePoint, Util.get(trackedRace.getRace().getCourse().getWaypoints(), 1), competitorA));
|
||||
trackedRace.updateMarkPassings(competitorA, markPassingsForCompetitor);
|
||||
// continue sailing downwind:
|
||||
// start on starboard tack:
|
||||
final KnotSpeedWithBearingImpl sogCogStarboardTackDownwind = new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(225));
|
||||
expectedSegmentStarts.add(timePoint);
|
||||
for (int i=0; i<20; i++) {
|
||||
competitorATrack.addGPSFix(currentGPS);
|
||||
final Position currentPosition = sogCogStarboardTackDownwind.travelTo(currentGPS.getPosition(), timeBetweenFixes);
|
||||
timePoint = timePoint.plus(timeBetweenFixes);
|
||||
currentGPS = new GPSFixMovingImpl(currentPosition, timePoint, sogCogPortTackUpwind);
|
||||
}
|
||||
// now gybe onto port tack:
|
||||
final KnotSpeedWithBearingImpl sogCogPortTackDownwind = new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(135));
|
||||
expectedSegmentStarts.add(timePoint);
|
||||
for (int i=0; i<20; i++) {
|
||||
competitorATrack.addGPSFix(currentGPS);
|
||||
final Position currentPosition = sogCogPortTackDownwind.travelTo(currentGPS.getPosition(), timeBetweenFixes);
|
||||
timePoint = timePoint.plus(timeBetweenFixes);
|
||||
currentGPS = new GPSFixMovingImpl(currentPosition, timePoint, sogCogPortTackDownwind);
|
||||
}
|
||||
// now run the actual test:
|
||||
final Iterable<HasTackTypeSegmentContext> allTTSegments = retrieveData();
|
||||
assertEquals(4, Util.size(allTTSegments));
|
||||
// assert that all segments are of similar distance; they are not exactly equal
|
||||
// because due to smoothing of COG/SOG, tack type transitions are not exactly where COG goes from 45 to, say, 315
|
||||
final Distance distanceFirstSegment = allTTSegments.iterator().next().getDistance();
|
||||
for (final HasTackTypeSegmentContext ttSegment : allTTSegments) {
|
||||
assertEquals(distanceFirstSegment.getMeters(), ttSegment.getDistance().getMeters(), distanceFirstSegment.scale(0.2).getMeters() /* allow for 20% tolerance */);
|
||||
}
|
||||
}
|
||||
}
|
||||
+19
-2
@@ -24,7 +24,7 @@ Team=Team
|
||||
SearchTag=Search Tag
|
||||
LeaderboardSailingDomainRetrieverChain=Leaderboards
|
||||
RaceSailingDomainRetrieverChain=Races
|
||||
LegSailingDomainRetrieverChain=Legs
|
||||
LegOfCompetitorSailingDomainRetrieverChain=Legs of Competitors
|
||||
GPSFixSailingDomainRetrieverChain=GPS Fixes
|
||||
BravoFixSailingDomainRetrieverChain=Bravo Fixes
|
||||
BravoFixTrackSailingDomainRetrieverChain=Bravo Tracks
|
||||
@@ -254,4 +254,21 @@ CompetitorDaySailingDomainRetrieverChain=Competitor-Day for race
|
||||
LowestSpeed=Lowest Speed
|
||||
SpeedChange=Speed Change
|
||||
MaximumTurningRate=Maximum turning rate (°/s)
|
||||
AverageTurningRate=Average turning rate (°/s)
|
||||
AverageTurningRate=Average turning rate (°/s)
|
||||
LengthOfTheLeg=Length of the Leg
|
||||
LegSailingDomainRetrieverChain=Leg
|
||||
TackType=Long / short tack
|
||||
getTackTypeofRace=Long / short tack of the race
|
||||
tackTypeSegmentsRetrieverChainDefinition=Long/Short tack segments
|
||||
TackTypeSegments=Long/Short segments
|
||||
TackTypeSegmentName=Long/Short tack segments name
|
||||
TackTypeDuration=Long/Short tack duration
|
||||
TackTypeDistance=Long/Short tack distance
|
||||
InRace=In race
|
||||
InTrackingInterval=In tracking interval
|
||||
NumberOfCompetitors=Number of Competitors
|
||||
CompetitorInLeaderboard=Competitor in Leaderboard
|
||||
CompetitorSailingDomainRetrieverChain=Competitors in Leaderboards
|
||||
SmoothedSpeed=Smoothed Speed
|
||||
RatioDistanceLongVsShortTack=Ratio distance long tack / short tack
|
||||
RatioDurationLongVsShortTack=Ratio duration long tack / short tack
|
||||
+11
-1
@@ -24,7 +24,7 @@ Team=Tým
|
||||
SearchTag=Hledací znak
|
||||
LeaderboardSailingDomainRetrieverChain=Výsledkové tabule
|
||||
RaceSailingDomainRetrieverChain=Rozjížďky
|
||||
LegSailingDomainRetrieverChain=Úseky
|
||||
LegOfCompetitorSailingDomainRetrieverChain=Úseky závodníků
|
||||
GPSFixSailingDomainRetrieverChain=Záznamy polohy GPS
|
||||
BravoFixSailingDomainRetrieverChain=Záznamy polohy Bravo
|
||||
BravoFixTrackSailingDomainRetrieverChain=Dráhy Bravo
|
||||
@@ -255,3 +255,13 @@ LowestSpeed=Nejnižší rychlost
|
||||
SpeedChange=Změna rychlosti
|
||||
MaximumTurningRate=Maximální tempo změny kurzu (°/s)
|
||||
AverageTurningRate=Průměrné tempo změny kurzu (°/s)
|
||||
LengthOfTheLeg=Délka úseku
|
||||
LegSailingDomainRetrieverChain=Úsek
|
||||
TackType=Dlouhý/krátký obrat
|
||||
getTackTypeofRace=Dlouhý/krátký obrat rozjížďky
|
||||
InRace=In race
|
||||
InTrackingInterval=In tracking interval
|
||||
NumberOfCompetitors=Number of Competitors
|
||||
CompetitorInLeaderboard=Competitor in Leaderboard
|
||||
CompetitorSailingDomainRetrieverChain=Competitors in Leaderboards
|
||||
SmoothedSpeed=Smoothed Speed
|
||||
|
||||
+11
-1
@@ -24,7 +24,7 @@ Team=Team
|
||||
SearchTag=Søgetag
|
||||
LeaderboardSailingDomainRetrieverChain=Ranglister
|
||||
RaceSailingDomainRetrieverChain=Sejladser
|
||||
LegSailingDomainRetrieverChain=Ben
|
||||
LegOfCompetitorSailingDomainRetrieverChain=Ben for konkurrenter
|
||||
GPSFixSailingDomainRetrieverChain=GPS-registreringer
|
||||
BravoFixSailingDomainRetrieverChain=Bravo-registreringer
|
||||
BravoFixTrackSailingDomainRetrieverChain=Bravo-spor
|
||||
@@ -255,3 +255,13 @@ LowestSpeed=Laveste hastighed
|
||||
SpeedChange=Hastighedsændring
|
||||
MaximumTurningRate=Maks. drejehastighed (°/s)
|
||||
AverageTurningRate=Gennemsnitlig drejehastighed (°/s)
|
||||
LengthOfTheLeg=Længde på benet
|
||||
LegSailingDomainRetrieverChain=Ben
|
||||
TackType=Lang/kort stagvende
|
||||
getTackTypeofRace=Lang/kort stagvende for kapsejladsen
|
||||
InRace=In race
|
||||
InTrackingInterval=In tracking interval
|
||||
NumberOfCompetitors=Number of Competitors
|
||||
CompetitorInLeaderboard=Competitor in Leaderboard
|
||||
CompetitorSailingDomainRetrieverChain=Competitors in Leaderboards
|
||||
SmoothedSpeed=Smoothed Speed
|
||||
|
||||
+19
-7
@@ -10,8 +10,8 @@ Acronym=Abkürzung
|
||||
SailID=Segelnummer
|
||||
BoatName=Bootsname
|
||||
Color=Farbe
|
||||
LegNumber=Nummer des Schenkels
|
||||
LegType=Art des Schenkels
|
||||
LegNumber=Nummer des Bahnschenkels
|
||||
LegType=Art des Bahnschenkels
|
||||
Year=Jahr
|
||||
Regatta=Regatta
|
||||
CourseArea=Regattabahn
|
||||
@@ -21,7 +21,7 @@ RaceColumn=Rennspalte
|
||||
Race=Rennen
|
||||
LeaderboardSailingDomainRetrieverChain=Leaderboards
|
||||
RaceSailingDomainRetrieverChain=Rennen
|
||||
LegSailingDomainRetrieverChain=Schenkel
|
||||
LegOfCompetitorSailingDomainRetrieverChain=Bahnschenkel eines Teilnehmers
|
||||
GPSFixSailingDomainRetrieverChain=GPS-Fixes
|
||||
BravoFixSailingDomainRetrieverChain=Bravo-Fixes
|
||||
BravoFixTrackSailingDomainRetrieverChain=Bravo Messreihen
|
||||
@@ -35,9 +35,9 @@ RaceOfCompetitorSailingDomainRetrieverChain=Rennen eines Teilnehmers
|
||||
ManeuverSailingDomainRetrieverChain=Manöver
|
||||
LeaderboardGroup=Ranglisten Gruppe
|
||||
Leaderboard=Rangliste
|
||||
Leg=Schenkel
|
||||
Leg=Bahnschenkel
|
||||
MarkPassing=Tonnenrundung
|
||||
LegOfCompetitor=Schenkel eines Teilnehmers
|
||||
LegOfCompetitor=Bahnschenkel eines Teilnehmers
|
||||
GpsFix=GPS-Fix
|
||||
BravoFix=Bravo-Fix
|
||||
LineLengthAtStart=Länge der Startlinie zum Startzeitpunkt
|
||||
@@ -117,7 +117,7 @@ RankThirtySecondsAfterStart=Absolute Platzierung 30s nach dem Startzeitpunkt
|
||||
WindwardDistanceToAdvantageousEndOfLineAtStartOfRace=Windwärtige Distanz zum Bevorteilten Ende der Startlinie zum Start des Rennens
|
||||
WindwardDistanceToAdvantageousEndOfLineAtStartOfCompetitor=Windwärtige Distanz zum Bevorteilten Ende der Startlinie zum Start des Teilnehmers
|
||||
AbsoluteWindwardDistanceToStarboardSideAtStartOfCompetitor=Absolute Windwärtige Distanz zur Steuerbordseite beim Start des Teilnehmers
|
||||
RankAfterHalfOfTheFirstLeg=Platzierung nach der Hälfte des ersten Schenkels
|
||||
RankAfterHalfOfTheFirstLeg=Platzierung nach der Hälfte des ersten Bahnschenkels
|
||||
AdvantageousEndOfLine=Bevorteiltes Ende der Startlinie
|
||||
AdvantageOfStarboardSideOfStartLine=Vorteil der Steuerbord-Seite der Startlinie
|
||||
TrueWindAngleOfStartLineSeenFromStarboardSide=Winkel der Startlinie zum wahren Wind vom Steuerbord-Ende aus gesehen
|
||||
@@ -257,4 +257,16 @@ CompetitorDaySailingDomainRetrieverChain=Teilnehmer-Tag für Wettfahrt
|
||||
LowestSpeed=Niedrigste Geschwindigkeit
|
||||
SpeedChange=Geschwindigkeits-Änderung
|
||||
MaximumTurningRate=Maximale Drehgeschwindigkeit (°/s)
|
||||
AverageTurningRate=Durchschnittliche Drehgeschwindigkeit (°/s)
|
||||
AverageTurningRate=Durchschnittliche Drehgeschwindigkeit (°/s)
|
||||
LengthOfTheLeg=Länge eines Bahnschenkels
|
||||
LegSailingDomainRetrieverChain=Bahnschenkel
|
||||
TackType=Streck-/Holebug
|
||||
getTackTypeofRace=Streck-/Holebug des Rennens
|
||||
InRace=In der Wettfahrt
|
||||
InTrackingInterval=Im Tracking-Zeitraum der Wettfahrt
|
||||
NumberOfCompetitors=Anzahl Teilnehmer
|
||||
CompetitorInLeaderboard=Teilnehmer aus Rangliste
|
||||
CompetitorSailingDomainRetrieverChain=Teilnehmer in Ranglisten
|
||||
SmoothedSpeed=Geglättete Geschwindigkeit
|
||||
RatioDistanceLongVsShortTack=Verhältnis gesegelte Distanz auf Streck- zu Holebug
|
||||
RatioDurationLongVsShortTack=Verhältnis gesegelte Dauer auf Streck- zu Holebug
|
||||
+47
-37
@@ -16,15 +16,15 @@ Regatta=Regata
|
||||
CourseArea=Zona de regata
|
||||
BoatClass=Clase de bote
|
||||
Fleet=Flota
|
||||
RaceColumn=Columna de carrera
|
||||
Race=Carrera
|
||||
RaceColumn=Columna de prueba
|
||||
Race=Prueba
|
||||
Competitor=Competidor
|
||||
Boat=Bote
|
||||
Team=Equipo
|
||||
SearchTag=Etiqueta de búsqueda
|
||||
LeaderboardSailingDomainRetrieverChain=Clasificaciones
|
||||
RaceSailingDomainRetrieverChain=Carreras
|
||||
LegSailingDomainRetrieverChain=Tramos
|
||||
RaceSailingDomainRetrieverChain=Pruebas
|
||||
LegOfCompetitorSailingDomainRetrieverChain=Tramos de competidores
|
||||
GPSFixSailingDomainRetrieverChain=Puntos de GPS
|
||||
BravoFixSailingDomainRetrieverChain=Puntos de Bravo
|
||||
BravoFixTrackSailingDomainRetrieverChain=Seguimientos Bravo
|
||||
@@ -32,12 +32,12 @@ FoilingSegmentsSailingDomainRetrieverChain=Apéndices de foil
|
||||
FoilingSegmentName=Nombre de apéndice de foil
|
||||
WindFixSailingDomainRetrieverChain=Puntos de viento
|
||||
MarkPassingSailingDomainRetrieverChain=Superaciones de marca
|
||||
TrackedRaceResultOfCompetitorRetrieverChain=Carreras
|
||||
RaceResultSailingDomainRetrieverChain=Resultados de la carrera
|
||||
RaceOfCompetitorSailingDomainRetrieverChain=Carreras de los competidores
|
||||
TrackedRaceResultOfCompetitorRetrieverChain=Pruebas
|
||||
RaceResultSailingDomainRetrieverChain=Resultados de la prueba
|
||||
RaceOfCompetitorSailingDomainRetrieverChain=Pruebas de los competidores
|
||||
ManeuverSailingDomainRetrieverChain=Maniobra
|
||||
LeaderboardGroup=Grupo de clasificación
|
||||
LineLengthAtStart=Longitud de línea de salida al inicio de carrera
|
||||
LineLengthAtStart=Longitud de línea de salida al inicio de prueba
|
||||
Leaderboard=Clasificación
|
||||
Leg=Tramo
|
||||
MarkPassing=Superación de marca
|
||||
@@ -63,7 +63,7 @@ Bft11=Temporal duro
|
||||
Bft12=Huracán
|
||||
RelativeScore=Puntuación relativa (0 mejor; 1 peor)
|
||||
RelativeScoreInPercent=Puntuación relativa en %
|
||||
RelativeScoreInRaceInPercent=Puntuación relativa en carrera en %
|
||||
RelativeScoreInRaceInPercent=Puntuación relativa en prueba en %
|
||||
AbsoluteRank=Posición absoluta
|
||||
AbsoluteRankAfterFirstQuarter=Posición absoluta tras el primer cuarto
|
||||
AbsoluteRankAfterSecondQuarter=Posición absoluta tras el segundo cuarto
|
||||
@@ -87,7 +87,7 @@ SpeedWhenStarting=Velocidad al inicio
|
||||
SpeedTenSecondsBeforeStart=Velocidad 10 s antes del inicio
|
||||
RankAtFirstMark=Posición en la primera marca
|
||||
NumberOfManeuvers=Número de maniobras
|
||||
NumberOfTacks=Número de amuras
|
||||
NumberOfTacks=Número de bordos
|
||||
NumberOfJibes=Número de viradas en redondo
|
||||
NumberOfPenaltyCircles=Número de círculos de sanción
|
||||
RankGainsOrLosses=Aumentos y pérdidas de posición
|
||||
@@ -101,7 +101,7 @@ NumberOfCompetitorFixes=Número de puntos del competidor
|
||||
NumberOfMarkFixes=Número de puntos de la marca
|
||||
NumberOfWindFixes=Número de correcciones de viento
|
||||
ManeuverType=Tipo de maniobra
|
||||
Tack=Amura
|
||||
Tack=Bordo
|
||||
WindSpeedVsManeuverLoss=Velocidad de viento en nudos (X) vs. Pérdida en maniobra en metros (Y)
|
||||
SpeedBefore=Velocidad antes de maniobra
|
||||
SpeedAfter=Velocidad después de maniobra
|
||||
@@ -112,10 +112,10 @@ ToSide=Al lado (babor / estribor)
|
||||
ManeuverLoss=Pérdida en maniobra
|
||||
Waypoint=Punto de ruta
|
||||
PassingSide=Vía de paso
|
||||
TackAtStart=Amura al inicio
|
||||
TackAtStart=Bordo al inicio
|
||||
SpeedTenSecondsAfterStart=Velocidad 10 s después del inicio
|
||||
RankThirtySecondsAfterStart=Posición 30 segundos después del inicio
|
||||
WindwardDistanceToAdvantageousEndOfLineAtStartOfRace=Distancia a barlovento hasta extremo favorable al inicio de carrera
|
||||
WindwardDistanceToAdvantageousEndOfLineAtStartOfRace=Distancia a barlovento hasta extremo favorable al inicio de prueba
|
||||
WindwardDistanceToAdvantageousEndOfLineAtStartOfCompetitor=Distancia a barlovento a banda de estribor de línea al inicio de competidor
|
||||
RankAfterHalfOfTheFirstLeg=Posición tras la mitad del primer tramo
|
||||
AdvantageousEndOfLine=Extremo favorable
|
||||
@@ -125,11 +125,11 @@ StartLineLength=Longitud de línea de salida
|
||||
FinishLineLength=Longitud de línea de llegada
|
||||
TimeSpentInSeconds=Tiempo empleado en segundos
|
||||
MedalRace=Medal Race
|
||||
WindwardDistanceToAdvantageousEndOfLineAtStartOfRaceVsRelativeDistanceToAdvantageousEndOfLine=Distancia a barlovento hasta extremo favorable al inicio de carrera (X) vs. distancia relativa hasta extremo favorable al inicio de carrera (Y)
|
||||
WindwardDistanceToAdvantageousEndOfLineAtStartOfRaceVsRelativeDistanceToAdvantageousEndOfLine=Distancia a barlovento hasta extremo favorable al inicio de prueba (X) vs. distancia relativa hasta extremo favorable al inicio de prueba (Y)
|
||||
WindSourceType=Tipo de fuente de viento
|
||||
AbsoluteWindwardDistanceToStarboardSideAtStartOfCompetitor=Distancia a barlovento absoluta a banda de estribor de la línea al inicio del competidor
|
||||
WindSourceName=Nombre de fuente de viento
|
||||
RelativeDistanceToAdvantageousEndOfLineAtStartOfRace=Distancia relativa hasta extremo favorable al inicio de carrera
|
||||
RelativeDistanceToAdvantageousEndOfLineAtStartOfRace=Distancia relativa hasta extremo favorable al inicio de prueba
|
||||
windFrom=Dirección del viento real (TWD)
|
||||
windSpeedKnots=Velocidad del viento real (nudos)
|
||||
speedInKnots=Velocidad (nudos)
|
||||
@@ -211,7 +211,7 @@ RelativeBearingToNextMarkAfterManeuver=Rumbo relativo a la siguiente marca tras
|
||||
AbsRelativeBearingToNextMarkBeforeManeuver=Rumbo relativo absoluto a la siguiente marca antes de la maniobra
|
||||
AbsRelativeBearingToNextMarkAfterManeuver=Rumbo relativo absoluto a la siguiente marca tras la maniobra
|
||||
JibingCount=Recuento de trasluchadas
|
||||
TackingCount=Recuento de viradas
|
||||
TackingCount=Recuento de bordos
|
||||
AbsTwaAtMaxTurningRate=TWA absoluto en velocidad máxima de giro
|
||||
AbsTwaAtLowestSpeed=TWA absoluto en velocidad mínima
|
||||
AbsTwaAtHighestSpeed=TWA absoluto en velocidad máxima
|
||||
@@ -220,31 +220,31 @@ PercentageOfMainCurveProgressUntilHighestSpeed=Porcentaje de progreso de curva p
|
||||
PercentageOfMainCurveProgressUntilMaxTurningRate=Porcentaje de progreso de curva principal hasta velocidad máxima de giro
|
||||
AbsTwaAtManeuverMiddle=TWA absoluto en mitad de maniobra
|
||||
GpsSamplingRate=Velocidad de muestreo de GPS
|
||||
RaceDuration=Duración de carrera
|
||||
DistanceToAdvantageousSideAtStartOfRaceVsRankAtFirstMark=Distancia relativa hasta extremo favorable al inicio de la carrera (X) frente a posición con calificación más alta (Y)
|
||||
DistanceToAdvantageousSideAtStartOfRaceVsFinalRank=Distancia relativa hasta extremo favorable al inicio de la carrera (X) frente a posición final (Y)
|
||||
AverageRaceWindSpeed=Velocidad media de viento para la carrera
|
||||
VMG5SecondsBeforeStartOfRace=VMG 5 segundos antes del inicio de la carrera
|
||||
VMGAtStartOfRace=VMG al inicio de la carrera
|
||||
RaceDuration=Duración de prueba
|
||||
DistanceToAdvantageousSideAtStartOfRaceVsRankAtFirstMark=Distancia relativa hasta extremo favorable al inicio de la prueba (X) frente a posición con calificación más alta (Y)
|
||||
DistanceToAdvantageousSideAtStartOfRaceVsFinalRank=Distancia relativa hasta extremo favorable al inicio de la prueba (X) frente a posición final (Y)
|
||||
AverageRaceWindSpeed=Velocidad media de viento para la prueba
|
||||
VMG5SecondsBeforeStartOfRace=VMG 5 segundos antes del inicio de la prueba
|
||||
VMGAtStartOfRace=VMG al inicio de la prueba
|
||||
FinalRank=Posición final
|
||||
VMG5SecondsAfterStartOfRace=VMG 5 segundos tras el inicio de la carrera
|
||||
RankSixtySecondsAfterStart=Posición 60 segundos tras el inicio de la carrera
|
||||
RankNinetySecondsAfterStart=Posición 90 segundos tras el inicio de la carrera
|
||||
DistanceToStarboardSideAtStartOfRace=Distancia relativa hasta la banda de estribor en inicio de carrera
|
||||
BiasAtStartOfRace=Distorsión de línea de salida al inicio de la carrera en metros (negativo: PUERTO, positivo: ESTRIBOR)
|
||||
Bias30SecondsAfterRaceStart=Distorsión de línea de salida 30 segundos tras el inicio de la carrera en metros (negativo: PUERTO, positivo: ESTRIBOR)
|
||||
VMG5SecondsAfterStartOfRace=VMG 5 segundos tras el inicio de la prueba
|
||||
RankSixtySecondsAfterStart=Posición 60 segundos tras el inicio de la prueba
|
||||
RankNinetySecondsAfterStart=Posición 90 segundos tras el inicio de la prueba
|
||||
DistanceToStarboardSideAtStartOfRace=Distancia relativa hasta la banda de estribor en inicio de prueba
|
||||
BiasAtStartOfRace=Distorsión de línea de salida al inicio de la prueba en metros (negativo: BABOR, positivo: ESTRIBOR)
|
||||
Bias30SecondsAfterRaceStart=Distorsión de línea de salida 30 segundos tras el inicio de la prueba en metros (negativo: BABOR, positivo: ESTRIBOR)
|
||||
RankAtFirstMarkVsFinalRank=Posición en la primera marca (X) frente a posición final (Y)
|
||||
DistanceToStarboardSideOfStartLineProjectedOntoLineAtStart=Distancia a la banda de estribor de la línea de salida proyectada en la línea en la salida
|
||||
NormalizedDistanceToStarboardSideOfStartLineProjectedOntoLineAtStart=Distancia a la banda de estribor de la línea de salida proyectada en la línea en la salida dividida por la longitud de la línea de salida
|
||||
DistanceToNextBoatToPortProjectedToStartLineAtStartOfRace=Distancia a la siguiente embarcación a babor en el inicio de la carrera, proyectada sobre la línea de salida
|
||||
DistanceToNextBoatToStarboardProjectedToStartLineAtStartOfRace=Distancia a la siguiente embarcación a estribor en el inicio de la carrera, proyectada sobre la línea de salida
|
||||
WindwardDistanceToNextBoatToPortAtStartOfRace=Distancia a barlovento a siguiente embarcación a babor en el inicio de la carrera
|
||||
WindwardDistanceToNextBoatToStarboardAtStartOfRace=Distancia a barlovento a siguiente embarcación a estribor en el inicio de la carrera
|
||||
DistanceToNextBoatToPortAtStartOfRacePerpendicularToStartLine=Distancia a la siguiente embarcación a babor en el inicio de la carrera, perpendicular a la línea de salida
|
||||
DistanceToNextBoatToStarboardAtStartOfRacePerpendicularToStartLine=Distancia a la siguiente embarcación a estribor en el inicio de la carrera, perpendicular a la línea de salida
|
||||
TotalDistanceToNeighboursPerpendicularToStarLineAtStartOfRace=Total de distancias absolutas para los vecinos en la línea de salida en el inicio de la carrera, perpendiculares en la línea de salida
|
||||
TotalWindwardDistanceToNeighboursAtStartOfRace=Total de distancias absolutas a barlovento para los vecinos en la línea de salida en el inicio de la carrera
|
||||
TotalDistanceToNeighboursProjectedToStartLineAtStartOfRace=Total de distancias a lo largo de la línea para los vecinos en la línea de salida (o en posición final, respectivamente) en el inicio de la carrera
|
||||
DistanceToNextBoatToPortProjectedToStartLineAtStartOfRace=Distancia a la siguiente embarcación a babor en el inicio de la prueba, proyectada sobre la línea de salida
|
||||
DistanceToNextBoatToStarboardProjectedToStartLineAtStartOfRace=Distancia a la siguiente embarcación a estribor en el inicio de la prueba, proyectada sobre la línea de salida
|
||||
WindwardDistanceToNextBoatToPortAtStartOfRace=Distancia a barlovento a siguiente embarcación a babor en el inicio de la prueba
|
||||
WindwardDistanceToNextBoatToStarboardAtStartOfRace=Distancia a barlovento a siguiente embarcación a estribor en el inicio de la prueba
|
||||
DistanceToNextBoatToPortAtStartOfRacePerpendicularToStartLine=Distancia a la siguiente embarcación a babor en el inicio de la prueba, perpendicular a la línea de salida
|
||||
DistanceToNextBoatToStarboardAtStartOfRacePerpendicularToStartLine=Distancia a la siguiente embarcación a estribor en el inicio de la prueba, perpendicular a la línea de salida
|
||||
TotalDistanceToNeighboursPerpendicularToStarLineAtStartOfRace=Total de distancias absolutas para los vecinos en la línea de salida en el inicio de la prueba, perpendiculares en la línea de salida
|
||||
TotalWindwardDistanceToNeighboursAtStartOfRace=Total de distancias absolutas a barlovento para los vecinos en la línea de salida en el inicio de la prueba
|
||||
TotalDistanceToNeighboursProjectedToStartLineAtStartOfRace=Total de distancias a lo largo de la línea para los vecinos en la línea de salida (o en posición final, respectivamente) en el inicio de la prueba
|
||||
IRM=Código IRM (OCS, DNC, DNF, etc.)
|
||||
XTE=Error de recorrido
|
||||
AbsoluteXTE=Error de recorrido absoluto
|
||||
@@ -255,3 +255,13 @@ LowestSpeed=Velocidad más baja
|
||||
SpeedChange=Cambio de velocidad
|
||||
MaximumTurningRate=Velocidad máxima de giro (°/s)
|
||||
AverageTurningRate=Velocidad media de giro (°/s)
|
||||
LengthOfTheLeg=Longitud del tramo
|
||||
LegSailingDomainRetrieverChain=Tramo
|
||||
TackType=Bordo largo/corto
|
||||
getTackTypeofRace=Bordo largo/corto de la prueba
|
||||
InRace=In race
|
||||
InTrackingInterval=In tracking interval
|
||||
NumberOfCompetitors=Number of Competitors
|
||||
CompetitorInLeaderboard=Competitor in Leaderboard
|
||||
CompetitorSailingDomainRetrieverChain=Competitors in Leaderboards
|
||||
SmoothedSpeed=Smoothed Speed
|
||||
|
||||
+13
-3
@@ -24,7 +24,7 @@ Team=Équipe
|
||||
SearchTag=Balise de recherche
|
||||
LeaderboardSailingDomainRetrieverChain=Palmarès
|
||||
RaceSailingDomainRetrieverChain=Courses
|
||||
LegSailingDomainRetrieverChain=Portions de parcours
|
||||
LegOfCompetitorSailingDomainRetrieverChain=Portions de parcours des concurrents
|
||||
GPSFixSailingDomainRetrieverChain=Positions GPS
|
||||
BravoFixSailingDomainRetrieverChain=Positions Bravo
|
||||
BravoFixTrackSailingDomainRetrieverChain=Enregistrements Bravo
|
||||
@@ -249,9 +249,19 @@ IRM=Code IRM (OCS, DNC, DNF, etc.)
|
||||
XTE=Écart de route
|
||||
AbsoluteXTE=Écart de route absolu
|
||||
Day=Jour
|
||||
CompetitorDay=Jour des concurrents
|
||||
CompetitorDaySailingDomainRetrieverChain=Jour des concurrents pour la course
|
||||
CompetitorDay=Jours par concurrent
|
||||
CompetitorDaySailingDomainRetrieverChain=Jours par concurrent pour la course
|
||||
LowestSpeed=Vitesse la plus basse
|
||||
SpeedChange=Changement de vitesse
|
||||
MaximumTurningRate=Vitesse angulaire maximale (°/s)
|
||||
AverageTurningRate=Vitesse angulaire moyenne (°/s)
|
||||
LengthOfTheLeg=Longueur de la portion de parcours
|
||||
LegSailingDomainRetrieverChain=Portion de parcours
|
||||
TackType=Virement long/court
|
||||
getTackTypeofRace=Virement long/court de la course
|
||||
InRace=In race
|
||||
InTrackingInterval=In tracking interval
|
||||
NumberOfCompetitors=Number of Competitors
|
||||
CompetitorInLeaderboard=Competitor in Leaderboard
|
||||
CompetitorSailingDomainRetrieverChain=Competitors in Leaderboards
|
||||
SmoothedSpeed=Smoothed Speed
|
||||
|
||||
+13
-3
@@ -24,7 +24,7 @@ Team=Squadra
|
||||
SearchTag=Tag di ricerca
|
||||
LeaderboardSailingDomainRetrieverChain=Classifiche
|
||||
RaceSailingDomainRetrieverChain=Gare
|
||||
LegSailingDomainRetrieverChain=Tratte
|
||||
LegOfCompetitorSailingDomainRetrieverChain=Tratte dei concorrenti
|
||||
GPSFixSailingDomainRetrieverChain=Punti nave GPS
|
||||
BravoFixSailingDomainRetrieverChain=Punti nave Bravo
|
||||
BravoFixTrackSailingDomainRetrieverChain=Tracce Bravo
|
||||
@@ -249,9 +249,19 @@ IRM=Codice IRM (OCS, DNC, DNF, ecc.)
|
||||
XTE=Errore di fuori rotta
|
||||
AbsoluteXTE=Errore assoluto di fuori rotta
|
||||
Day=Giorno
|
||||
CompetitorDay=Giorno del concorrente
|
||||
CompetitorDaySailingDomainRetrieverChain=Giorno di gara del concorrente
|
||||
CompetitorDay=Giorno concorrente
|
||||
CompetitorDaySailingDomainRetrieverChain=Giorni concorrente per ciascuna gara
|
||||
LowestSpeed=Velocità più bassa
|
||||
SpeedChange=Cambio di velocità
|
||||
MaximumTurningRate=Velocità di virata massima (°/s)
|
||||
AverageTurningRate=Velocità di virata media (°/s)
|
||||
LengthOfTheLeg=Lunghezza della tratta
|
||||
LegSailingDomainRetrieverChain=Tratta
|
||||
TackType=Bordo lungo/corto
|
||||
getTackTypeofRace=Bordo lungo/corto della gara
|
||||
InRace=In race
|
||||
InTrackingInterval=In tracking interval
|
||||
NumberOfCompetitors=Number of Competitors
|
||||
CompetitorInLeaderboard=Competitor in Leaderboard
|
||||
CompetitorSailingDomainRetrieverChain=Competitors in Leaderboards
|
||||
SmoothedSpeed=Smoothed Speed
|
||||
|
||||
+11
-1
@@ -24,7 +24,7 @@ Team=チーム
|
||||
SearchTag=検索タグ
|
||||
LeaderboardSailingDomainRetrieverChain=リーダーボード
|
||||
RaceSailingDomainRetrieverChain=レース
|
||||
LegSailingDomainRetrieverChain=レグ
|
||||
LegOfCompetitorSailingDomainRetrieverChain=競技者のレグ
|
||||
GPSFixSailingDomainRetrieverChain=GPS フィックス
|
||||
BravoFixSailingDomainRetrieverChain=Bravo フィックス
|
||||
BravoFixTrackSailingDomainRetrieverChain=Bravo トラック
|
||||
@@ -255,3 +255,13 @@ LowestSpeed=最低速度
|
||||
SpeedChange=速度変更
|
||||
MaximumTurningRate=最大回転率 (°/s)
|
||||
AverageTurningRate=平均回転率 (°/s)
|
||||
LengthOfTheLeg=レグの長さ
|
||||
LegSailingDomainRetrieverChain=レグ
|
||||
TackType=ロング/ショートタック
|
||||
getTackTypeofRace=レースのロング/ショートタック
|
||||
InRace=In race
|
||||
InTrackingInterval=In tracking interval
|
||||
NumberOfCompetitors=Number of Competitors
|
||||
CompetitorInLeaderboard=Competitor in Leaderboard
|
||||
CompetitorSailingDomainRetrieverChain=Competitors in Leaderboards
|
||||
SmoothedSpeed=Smoothed Speed
|
||||
|
||||
+11
-1
@@ -24,7 +24,7 @@ Team=Equipe
|
||||
SearchTag=Etiqueta de pesquisa
|
||||
LeaderboardSailingDomainRetrieverChain=Painéis de classificação
|
||||
RaceSailingDomainRetrieverChain=Corridas
|
||||
LegSailingDomainRetrieverChain=Pernas
|
||||
LegOfCompetitorSailingDomainRetrieverChain=Pernas de competidores
|
||||
GPSFixSailingDomainRetrieverChain=Pontos fixos de GPS
|
||||
BravoFixSailingDomainRetrieverChain=Pontos fixos Bravo
|
||||
BravoFixTrackSailingDomainRetrieverChain=Pistas Bravo
|
||||
@@ -255,3 +255,13 @@ LowestSpeed=Velocidade mais baixa
|
||||
SpeedChange=Mudança de velocidade
|
||||
MaximumTurningRate=Taxa de viragem máxima (°/s)
|
||||
AverageTurningRate=Taxa de viragem média (°/s)
|
||||
LengthOfTheLeg=Comprimento da perna
|
||||
LegSailingDomainRetrieverChain=Perna
|
||||
TackType=Cambada longa/curta
|
||||
getTackTypeofRace=Cambada longa/curta da corrida
|
||||
InRace=In race
|
||||
InTrackingInterval=In tracking interval
|
||||
NumberOfCompetitors=Number of Competitors
|
||||
CompetitorInLeaderboard=Competitor in Leaderboard
|
||||
CompetitorSailingDomainRetrieverChain=Competitors in Leaderboards
|
||||
SmoothedSpeed=Smoothed Speed
|
||||
|
||||
+11
-1
@@ -24,7 +24,7 @@ Team=Команда
|
||||
SearchTag=Тег поиска
|
||||
LeaderboardSailingDomainRetrieverChain=Таблицы лидеров
|
||||
RaceSailingDomainRetrieverChain=Гонки
|
||||
LegSailingDomainRetrieverChain=Отрезки
|
||||
LegOfCompetitorSailingDomainRetrieverChain=Отрезки участников
|
||||
GPSFixSailingDomainRetrieverChain=Замеры GPS
|
||||
BravoFixSailingDomainRetrieverChain=Замеры Bravo
|
||||
BravoFixTrackSailingDomainRetrieverChain=Отслеживания Bravo
|
||||
@@ -255,3 +255,13 @@ LowestSpeed=Наименьшая скорость
|
||||
SpeedChange=Изменение скорости
|
||||
MaximumTurningRate=Максимальная скорость поворота (°/c)
|
||||
AverageTurningRate=Средняя скорость поворота (°/c)
|
||||
LengthOfTheLeg=Длина отрезка
|
||||
LegSailingDomainRetrieverChain=Отрезок
|
||||
TackType=Длинный /короткий галс
|
||||
getTackTypeofRace=Длинный /короткий галс гонки
|
||||
InRace=In race
|
||||
InTrackingInterval=In tracking interval
|
||||
NumberOfCompetitors=Number of Competitors
|
||||
CompetitorInLeaderboard=Competitor in Leaderboard
|
||||
CompetitorSailingDomainRetrieverChain=Competitors in Leaderboards
|
||||
SmoothedSpeed=Smoothed Speed
|
||||
|
||||
+11
-1
@@ -24,7 +24,7 @@ Team=Ekipa
|
||||
SearchTag=Oznaka iskanja
|
||||
LeaderboardSailingDomainRetrieverChain=Lestvice vodilnih
|
||||
RaceSailingDomainRetrieverChain=Plovi
|
||||
LegSailingDomainRetrieverChain=Stranice
|
||||
LegOfCompetitorSailingDomainRetrieverChain=Stranice tekmovalcev
|
||||
GPSFixSailingDomainRetrieverChain=GPS-položaj
|
||||
BravoFixSailingDomainRetrieverChain=Bravo-položaji
|
||||
BravoFixTrackSailingDomainRetrieverChain=Bravo-sledi
|
||||
@@ -255,3 +255,13 @@ LowestSpeed=Najnižja hitrost
|
||||
SpeedChange=Sprememba hitrosti
|
||||
MaximumTurningRate=Maksimalna hitrost obračanja (°/s)
|
||||
AverageTurningRate=Povprečna hitrost obračanja (°/s)
|
||||
LengthOfTheLeg=Dolžina stranice
|
||||
LegSailingDomainRetrieverChain=Stranica
|
||||
TackType=Dolgo/kratko prečenje
|
||||
getTackTypeofRace=Dolgo/kratko prečenje plova
|
||||
InRace=In race
|
||||
InTrackingInterval=In tracking interval
|
||||
NumberOfCompetitors=Number of Competitors
|
||||
CompetitorInLeaderboard=Competitor in Leaderboard
|
||||
CompetitorSailingDomainRetrieverChain=Competitors in Leaderboards
|
||||
SmoothedSpeed=Smoothed Speed
|
||||
|
||||
+13
-3
@@ -24,7 +24,7 @@ Team=团队
|
||||
SearchTag=搜索标记
|
||||
LeaderboardSailingDomainRetrieverChain=积分榜
|
||||
RaceSailingDomainRetrieverChain=比赛轮次
|
||||
LegSailingDomainRetrieverChain=航段
|
||||
LegOfCompetitorSailingDomainRetrieverChain=参赛队的航段
|
||||
GPSFixSailingDomainRetrieverChain=GPS 修复
|
||||
BravoFixSailingDomainRetrieverChain=Bravo 修复
|
||||
BravoFixTrackSailingDomainRetrieverChain=Bravo 跟踪
|
||||
@@ -249,9 +249,19 @@ IRM=IRM 代码(OCS、DNC、DNF 等)
|
||||
XTE=交叉轨道误差
|
||||
AbsoluteXTE=绝对交叉轨道误差
|
||||
Day=天
|
||||
CompetitorDay=参赛队日
|
||||
CompetitorDaySailingDomainRetrieverChain=比赛轮次的参赛队日
|
||||
CompetitorDay=参赛队天
|
||||
CompetitorDaySailingDomainRetrieverChain=比赛轮次的参赛队天
|
||||
LowestSpeed=最低速度
|
||||
SpeedChange=速度变化
|
||||
MaximumTurningRate=最大回转率 (°/s)
|
||||
AverageTurningRate=平均回转率 (°/s)
|
||||
LengthOfTheLeg=航段长度
|
||||
LegSailingDomainRetrieverChain=航段
|
||||
TackType=长程/短程迎风转向
|
||||
getTackTypeofRace=比赛轮次的长程/短程迎风转向
|
||||
InRace=In race
|
||||
InTrackingInterval=In tracking interval
|
||||
NumberOfCompetitors=Number of Competitors
|
||||
CompetitorInLeaderboard=Competitor in Leaderboard
|
||||
CompetitorSailingDomainRetrieverChain=Competitors in Leaderboards
|
||||
SmoothedSpeed=Smoothed Speed
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.osgi.framework.BundleContext;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasBravoFixContext;
|
||||
import com.sap.sailing.datamining.data.HasBravoFixTrackContext;
|
||||
import com.sap.sailing.datamining.data.HasCompetitorContext;
|
||||
import com.sap.sailing.datamining.data.HasCompetitorDayContext;
|
||||
import com.sap.sailing.datamining.data.HasCompleteManeuverCurveWithEstimationDataContext;
|
||||
import com.sap.sailing.datamining.data.HasFoilingSegmentContext;
|
||||
@@ -21,6 +22,7 @@ import com.sap.sailing.datamining.data.HasManeuverSpeedDetailsContext;
|
||||
import com.sap.sailing.datamining.data.HasMarkPassingContext;
|
||||
import com.sap.sailing.datamining.data.HasRaceOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.data.HasRaceResultOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.data.HasTackTypeSegmentContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedLegContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
|
||||
@@ -111,6 +113,7 @@ public class Activator extends AbstractDataMiningActivatorWithPredefinedQueries
|
||||
internalClasses.add(HasBravoFixContext.class);
|
||||
internalClasses.add(HasBravoFixTrackContext.class);
|
||||
internalClasses.add(HasFoilingSegmentContext.class);
|
||||
internalClasses.add(HasTackTypeSegmentContext.class);
|
||||
internalClasses.add(HasManeuverContext.class);
|
||||
internalClasses.add(HasManeuverSpeedDetailsContext.class);
|
||||
internalClasses.add(HasCompleteManeuverCurveWithEstimationDataContext.class);
|
||||
@@ -119,6 +122,7 @@ public class Activator extends AbstractDataMiningActivatorWithPredefinedQueries
|
||||
internalClasses.add(HasCompetitorDayContext.class);
|
||||
internalClasses.add(HasLeaderboardGroupContext.class);
|
||||
internalClasses.add(HasLeaderboardContext.class);
|
||||
internalClasses.add(HasCompetitorContext.class);
|
||||
return internalClasses;
|
||||
}
|
||||
|
||||
|
||||
+29
-4
@@ -5,6 +5,7 @@ import java.util.Collection;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasBravoFixContext;
|
||||
import com.sap.sailing.datamining.data.HasBravoFixTrackContext;
|
||||
import com.sap.sailing.datamining.data.HasCompetitorContext;
|
||||
import com.sap.sailing.datamining.data.HasCompetitorDayContext;
|
||||
import com.sap.sailing.datamining.data.HasCompleteManeuverCurveWithEstimationDataContext;
|
||||
import com.sap.sailing.datamining.data.HasFoilingSegmentContext;
|
||||
@@ -16,6 +17,7 @@ import com.sap.sailing.datamining.data.HasManeuverSpeedDetailsContext;
|
||||
import com.sap.sailing.datamining.data.HasMarkPassingContext;
|
||||
import com.sap.sailing.datamining.data.HasRaceOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.data.HasRaceResultOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.data.HasTackTypeSegmentContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedLegContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
|
||||
@@ -25,6 +27,7 @@ import com.sap.sailing.datamining.impl.components.BravoFixRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.BravoFixTrackRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.CompetitorDayRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.CompetitorOfRaceInLeaderboardRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.CompetitorRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.CompleteManeuverCurveWithEstimationDataRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.FoilingSegmentRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.GPSFixRetrievalProcessor;
|
||||
@@ -34,6 +37,7 @@ import com.sap.sailing.datamining.impl.components.ManeuverRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.ManeuverSpeedDetailsRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.MarkPassingRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.RaceOfCompetitorRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.TackTypeSegmentRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.TrackedLegOfCompetitorRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.TrackedLegRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.TrackedRaceRetrievalProcessor;
|
||||
@@ -44,6 +48,7 @@ import com.sap.sailing.datamining.shared.ManeuverSettings;
|
||||
import com.sap.sailing.datamining.shared.ManeuverSettingsImpl;
|
||||
import com.sap.sailing.datamining.shared.ManeuverSpeedDetailsSettings;
|
||||
import com.sap.sailing.datamining.shared.ManeuverSpeedDetailsSettingsImpl;
|
||||
import com.sap.sailing.datamining.shared.TackTypeSegmentsDataMiningSettings;
|
||||
import com.sap.sailing.server.interfaces.RacingEventService;
|
||||
import com.sap.sse.datamining.components.DataRetrieverChainDefinition;
|
||||
import com.sap.sse.datamining.impl.components.SimpleDataRetrieverChainDefinition;
|
||||
@@ -59,6 +64,12 @@ public class SailingDataRetrievalChainDefinitions {
|
||||
leaderboardRetrieverChainDefinition.startWith(LeaderboardGroupRetrievalProcessor.class, HasLeaderboardGroupContext.class, "LeaderboardGroup");
|
||||
leaderboardRetrieverChainDefinition.endWith(LeaderboardGroupRetrievalProcessor.class, LeaderboardRetrievalProcessor.class,
|
||||
HasLeaderboardContext.class, "Leaderboard");
|
||||
dataRetrieverChainDefinitions.add(leaderboardRetrieverChainDefinition);
|
||||
//
|
||||
final DataRetrieverChainDefinition<RacingEventService, HasCompetitorContext> competitorRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
|
||||
leaderboardRetrieverChainDefinition, HasCompetitorContext.class, "CompetitorSailingDomainRetrieverChain");
|
||||
competitorRetrieverChainDefinition.endWith(LeaderboardRetrievalProcessor.class, CompetitorRetrievalProcessor.class, HasCompetitorContext.class, "CompetitorInLeaderboard");
|
||||
dataRetrieverChainDefinitions.add(competitorRetrieverChainDefinition);
|
||||
//
|
||||
final DataRetrieverChainDefinition<RacingEventService, HasTrackedRaceContext> trackedRaceResultOfCompetitorRetrieverChainDefinition =
|
||||
new SimpleDataRetrieverChainDefinition<>(leaderboardRetrieverChainDefinition, HasTrackedRaceContext.class, "TrackedRaceResultOfCompetitorRetrieverChain");
|
||||
@@ -78,7 +89,9 @@ public class SailingDataRetrievalChainDefinitions {
|
||||
//
|
||||
final DataRetrieverChainDefinition<RacingEventService, HasRaceOfCompetitorContext> raceOfCompetitorRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
|
||||
trackedRaceRetrieverChainDefinition, HasRaceOfCompetitorContext.class, "RaceOfCompetitorSailingDomainRetrieverChain");
|
||||
raceOfCompetitorRetrieverChainDefinition.endWith(TrackedRaceRetrievalProcessor.class, RaceOfCompetitorRetrievalProcessor.class, HasRaceOfCompetitorContext.class, "Competitor");
|
||||
// use TackTypeSegmentsDataMiningSettings here to support the per-leg statistics about tack type segments
|
||||
raceOfCompetitorRetrieverChainDefinition.endWith(TrackedRaceRetrievalProcessor.class, RaceOfCompetitorRetrievalProcessor.class, HasRaceOfCompetitorContext.class,
|
||||
TackTypeSegmentsDataMiningSettings.class, TackTypeSegmentsDataMiningSettings.createDefaultSettings(), "Competitor");
|
||||
dataRetrieverChainDefinitions.add(raceOfCompetitorRetrieverChainDefinition);
|
||||
//
|
||||
final DataRetrieverChainDefinition<RacingEventService, HasCompetitorDayContext> competitorDayRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
|
||||
@@ -98,11 +111,23 @@ public class SailingDataRetrievalChainDefinitions {
|
||||
HasFoilingSegmentContext.class, FoilingSegmentsDataMiningSettings.class, FoilingSegmentsDataMiningSettings.createDefaultSettings(), "FoilingSegments");
|
||||
dataRetrieverChainDefinitions.add(foilingSegmentsRetrieverChainDefinition);
|
||||
//
|
||||
final DataRetrieverChainDefinition<RacingEventService, HasTackTypeSegmentContext> tackTypeSegmentsRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
|
||||
raceOfCompetitorRetrieverChainDefinition, HasTackTypeSegmentContext.class, "tackTypeSegmentsRetrieverChainDefinition");
|
||||
tackTypeSegmentsRetrieverChainDefinition.endWith(RaceOfCompetitorRetrievalProcessor.class, TackTypeSegmentRetrievalProcessor.class,
|
||||
HasTackTypeSegmentContext.class, TackTypeSegmentsDataMiningSettings.class, TackTypeSegmentsDataMiningSettings.createDefaultSettings(), "TackTypeSegments");
|
||||
dataRetrieverChainDefinitions.add(tackTypeSegmentsRetrieverChainDefinition);
|
||||
//
|
||||
final DataRetrieverChainDefinition<RacingEventService, HasTrackedLegContext> legRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
|
||||
trackedRaceRetrieverChainDefinition, HasTrackedLegContext.class, "LegSailingDomainRetrieverChain");
|
||||
legRetrieverChainDefinition.endWith(TrackedRaceRetrievalProcessor.class, TrackedLegRetrievalProcessor.class,
|
||||
HasTrackedLegContext.class, "Leg");
|
||||
dataRetrieverChainDefinitions.add(legRetrieverChainDefinition);
|
||||
//
|
||||
final DataRetrieverChainDefinition<RacingEventService, HasTrackedLegOfCompetitorContext> legOfCompetitorRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
|
||||
trackedRaceRetrieverChainDefinition, HasTrackedLegOfCompetitorContext.class, "LegSailingDomainRetrieverChain");
|
||||
legOfCompetitorRetrieverChainDefinition.addAfter(TrackedRaceRetrievalProcessor.class, TrackedLegRetrievalProcessor.class, HasTrackedLegContext.class, "Leg");
|
||||
legRetrieverChainDefinition, HasTrackedLegOfCompetitorContext.class, "LegOfCompetitorSailingDomainRetrieverChain");
|
||||
// use TackTypeSegmentsDataMiningSettings here to support the per-leg statistics about tack type segments
|
||||
legOfCompetitorRetrieverChainDefinition.endWith(TrackedLegRetrievalProcessor.class, TrackedLegOfCompetitorRetrievalProcessor.class,
|
||||
HasTrackedLegOfCompetitorContext.class, "LegOfCompetitor");
|
||||
HasTrackedLegOfCompetitorContext.class, TackTypeSegmentsDataMiningSettings.class, TackTypeSegmentsDataMiningSettings.createDefaultSettings(), "LegOfCompetitor");
|
||||
dataRetrieverChainDefinitions.add(legOfCompetitorRetrieverChainDefinition);
|
||||
//
|
||||
final DataRetrieverChainDefinition<RacingEventService, HasGPSFixContext> gpsFixRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sse.datamining.annotations.Connector;
|
||||
|
||||
public interface HasCompetitorContext {
|
||||
@Connector(messageKey="Leaderboard")
|
||||
HasLeaderboardContext getLeaderboardContext();
|
||||
|
||||
@Connector
|
||||
Competitor getCompetitor();
|
||||
}
|
||||
+11
-2
@@ -2,18 +2,24 @@ package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.TackType;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.Distance;
|
||||
import com.sap.sse.common.Speed;
|
||||
import com.sap.sse.datamining.annotations.Connector;
|
||||
import com.sap.sse.datamining.annotations.Dimension;
|
||||
import com.sap.sse.datamining.annotations.Statistic;
|
||||
|
||||
public interface HasGPSFixContext {
|
||||
@Connector(scanForStatistics = false)
|
||||
public HasTrackedLegOfCompetitorContext getTrackedLegOfCompetitorContext();
|
||||
HasTrackedLegOfCompetitorContext getTrackedLegOfCompetitorContext();
|
||||
|
||||
@Connector(ordinal = 1)
|
||||
public GPSFixMoving getGPSFix();
|
||||
GPSFixMoving getGPSFix();
|
||||
|
||||
@Dimension(messageKey="TackType", ordinal=6)
|
||||
TackType getTackType() throws NoWindException;
|
||||
|
||||
@Statistic(messageKey = "TrueWindAngle")
|
||||
Bearing getTrueWindAngle() throws NoWindException;
|
||||
@@ -29,4 +35,7 @@ public interface HasGPSFixContext {
|
||||
|
||||
@Statistic(messageKey = "AbsoluteXTE", resultDecimals = 2)
|
||||
Distance getAbsoluteXTE();
|
||||
|
||||
@Statistic(messageKey = "SmoothedSpeed", resultDecimals = 2)
|
||||
Speed getSmoothedSpeed();
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||
import com.sap.sse.datamining.annotations.Connector;
|
||||
|
||||
public interface HasGPSFixTrackContext {
|
||||
@Connector(scanForStatistics=false)
|
||||
HasRaceOfCompetitorContext getRaceOfCompetitorContext();
|
||||
|
||||
GPSFixTrack<Competitor, GPSFixMoving> getGPSFixTrack();
|
||||
}
|
||||
+8
-1
@@ -2,8 +2,10 @@ package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.datamining.annotations.Connector;
|
||||
import com.sap.sse.datamining.annotations.Dimension;
|
||||
import com.sap.sse.datamining.annotations.Statistic;
|
||||
|
||||
public interface HasLeaderboardContext {
|
||||
@Connector(scanForStatistics=false)
|
||||
@@ -15,9 +17,14 @@ public interface HasLeaderboardContext {
|
||||
default String getName() {
|
||||
return getLeaderboard().getName();
|
||||
}
|
||||
|
||||
|
||||
@Connector(messageKey="BoatClass", ordinal=2)
|
||||
default BoatClass getBoatClass() {
|
||||
return getLeaderboard().getBoatClass();
|
||||
}
|
||||
|
||||
@Statistic(messageKey="NumberOfCompetitors", ordinal=3)
|
||||
default int getNumberOfCompetitors() {
|
||||
return Util.size(getLeaderboard().getCompetitors());
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -172,4 +172,10 @@ public interface HasRaceOfCompetitorContext {
|
||||
|
||||
@Statistic(messageKey="AverageRaceWindSpeed")
|
||||
Speed getAverageRaceWindSpeed();
|
||||
|
||||
@Statistic(messageKey="RatioDurationLongVsShortTack", resultDecimals=2)
|
||||
public double getRatioDurationLongVsShortTack();
|
||||
|
||||
@Statistic(messageKey="RatioDistanceLongVsShortTack", resultDecimals=2)
|
||||
public double getRatioDistanceLongVsShortTack();
|
||||
}
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.common.LegType;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.TackType;
|
||||
import com.sap.sse.common.Distance;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.datamining.annotations.Connector;
|
||||
import com.sap.sse.datamining.annotations.Dimension;
|
||||
import com.sap.sse.datamining.annotations.Statistic;
|
||||
|
||||
public interface HasTackTypeSegmentContext {
|
||||
@Connector(scanForStatistics=false)
|
||||
HasGPSFixTrackContext getGPSFixTrackContext();
|
||||
|
||||
TimePoint getStartOfTackTypeSegment();
|
||||
|
||||
TimePoint getEndOfTackTypeSegment();
|
||||
|
||||
@Dimension(messageKey="TackType")
|
||||
TackType getTackType();
|
||||
|
||||
@Dimension(messageKey="LegType")
|
||||
LegType getLegType() throws NoWindException;
|
||||
|
||||
@Dimension(messageKey="LegNumber")
|
||||
int getLegNumber();
|
||||
|
||||
@Dimension(messageKey="TackTypeSegmentName")
|
||||
String getName();
|
||||
|
||||
@Statistic(messageKey="TackTypeDuration")
|
||||
Duration getDuration();
|
||||
|
||||
@Statistic(messageKey="TackTypeDistance")
|
||||
Distance getDistance();
|
||||
}
|
||||
+4
-1
@@ -2,8 +2,10 @@ package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.common.LegType;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
import com.sap.sse.common.Distance;
|
||||
import com.sap.sse.datamining.annotations.Connector;
|
||||
import com.sap.sse.datamining.annotations.Dimension;
|
||||
import com.sap.sse.datamining.annotations.Statistic;
|
||||
|
||||
public interface HasTrackedLegContext {
|
||||
|
||||
@@ -16,5 +18,6 @@ public interface HasTrackedLegContext {
|
||||
public LegType getLegType();
|
||||
@Dimension(messageKey="LegNumber", ordinal=7)
|
||||
public int getLegNumber();
|
||||
|
||||
@Statistic(messageKey = "LengthOfTheLeg", resultDecimals = 2)
|
||||
Distance getLegLength();
|
||||
}
|
||||
+6
@@ -109,4 +109,10 @@ public interface HasTrackedLegOfCompetitorContext extends HasWindOnTrackedLeg {
|
||||
|
||||
@Statistic(messageKey="VMG", resultDecimals=2)
|
||||
public Speed getVelocityMadeGood();
|
||||
|
||||
@Statistic(messageKey="RatioDurationLongVsShortTack", resultDecimals=2)
|
||||
public double getRatioDurationLongVsShortTack();
|
||||
|
||||
@Statistic(messageKey="RatioDistanceLongVsShortTack", resultDecimals=2)
|
||||
public double getRatioDistanceLongVsShortTack();
|
||||
}
|
||||
+6
@@ -19,6 +19,12 @@ public interface HasWindFixContext extends HasWind {
|
||||
|
||||
@Statistic(messageKey="windSpeedKnots", resultDecimals=1, ordinal=2)
|
||||
double getWindSpeedInKnots();
|
||||
|
||||
@Dimension(messageKey="InTrackingInterval")
|
||||
boolean isInTrackingInterval();
|
||||
|
||||
@Dimension(messageKey="InRace")
|
||||
boolean isInRace();
|
||||
|
||||
@Override
|
||||
default TimePoint getTimePoint() {
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.sap.sailing.datamining.impl.components;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasCompetitorContext;
|
||||
import com.sap.sailing.datamining.data.HasLeaderboardContext;
|
||||
import com.sap.sailing.datamining.impl.data.CompetitorWithContext;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.datamining.components.Processor;
|
||||
import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor;
|
||||
|
||||
public class CompetitorRetrievalProcessor extends AbstractRetrievalProcessor<HasLeaderboardContext, HasCompetitorContext> {
|
||||
public CompetitorRetrievalProcessor(ExecutorService executor,
|
||||
Collection<Processor<HasCompetitorContext, ?>> resultReceivers, int retrievalLevel,
|
||||
String retrievedDataTypeMessageKey) {
|
||||
super(HasLeaderboardContext.class, HasCompetitorContext.class, executor, resultReceivers, retrievalLevel,
|
||||
retrievedDataTypeMessageKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<HasCompetitorContext> retrieveData(HasLeaderboardContext element) {
|
||||
return Util.map(element.getLeaderboard().getCompetitors(), c->new CompetitorWithContext(c, element));
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -51,7 +51,7 @@ public class FoilingSegmentRetrievalProcessor extends AbstractRetrievalProcessor
|
||||
TimePoint startOfSegment = null;
|
||||
bravoFixTrack.lockForRead();
|
||||
try {
|
||||
for (final BravoFix bravoFix : bravoFixTrack.getFixes(startOfRace, /* fromInclusive */ true, end, /* toInclusive */ false)) {
|
||||
for (final BravoFix bravoFix : bravoFixTrack.getFixes(startOfRace, /* fromInclusive */ true, end, /* toInclusive */ false)) { //geht ganzes Rennen durch
|
||||
if (isAborted()) {
|
||||
break;
|
||||
}
|
||||
@@ -61,10 +61,10 @@ public class FoilingSegmentRetrievalProcessor extends AbstractRetrievalProcessor
|
||||
element.getTrackedRaceContext().getTrackedRace().getTrack(element.getCompetitor()).getEstimatedSpeed(bravoFix.getTimePoint())) <= 0)) ||
|
||||
(settings.getMaximumSpeedNotFoiling() != null && settings.getMaximumSpeedNotFoiling().compareTo(
|
||||
element.getTrackedRaceContext().getTrackedRace().getTrack(element.getCompetitor()).getEstimatedSpeed(bravoFix.getTimePoint())) <= 0);
|
||||
if (currentFixIsFoiling != isFoiling) {
|
||||
if (currentFixIsFoiling) {
|
||||
if (currentFixIsFoiling != isFoiling) { //checken ob boot zum loop davor mit voherigem fix immernoch am fliegen ist, wenn nicht dann muss segment gemacht werden, wenn ja dann wird es zum segment ergänzt
|
||||
if (currentFixIsFoiling) { //wenn ich vorher nicht am fliegen war und jetzt schon start von segment
|
||||
startOfSegment = bravoFix.getTimePoint();
|
||||
} else {
|
||||
} else { // wenn ich vorher am fliegen war und jetzt nicht mehr, segment muss gebildet werden!!!!!
|
||||
if (settings.getMinimumFoilingSegmentDuration() == null ||
|
||||
startOfSegment.until(last).compareTo(settings.getMinimumFoilingSegmentDuration()) >= 0) {
|
||||
addOrMergeFoilingSegment(element, foilingSegments, bravoFixTrack, startOfSegment,
|
||||
@@ -72,7 +72,7 @@ public class FoilingSegmentRetrievalProcessor extends AbstractRetrievalProcessor
|
||||
}
|
||||
startOfSegment = null;
|
||||
}
|
||||
isFoiling = currentFixIsFoiling;
|
||||
isFoiling = currentFixIsFoiling; //aktualisiert das es vorher nicht gleich war also entweder fliegen zuende oder gerade beginnt
|
||||
}
|
||||
last = bravoFix.getTimePoint();
|
||||
}
|
||||
|
||||
+3
-3
@@ -26,17 +26,17 @@ public class GPSFixRetrievalProcessor extends AbstractRetrievalProcessor<HasTrac
|
||||
|
||||
@Override
|
||||
protected Iterable<HasGPSFixContext> retrieveData(HasTrackedLegOfCompetitorContext element) {
|
||||
Collection<HasGPSFixContext> gpsFixesWithContext = new ArrayList<>();
|
||||
final Collection<HasGPSFixContext> gpsFixesWithContext = new ArrayList<>();
|
||||
final GPSFixTrack<Competitor, GPSFixMoving> competitorTrack = element.getTrackedLegContext().getTrackedRaceContext().getTrackedRace().getTrack(element.getCompetitor());
|
||||
competitorTrack.lockForRead();
|
||||
try {
|
||||
TrackedLegOfCompetitor trackedLegOfCompetitor = element.getTrackedLegOfCompetitor();
|
||||
final TrackedLegOfCompetitor trackedLegOfCompetitor = element.getTrackedLegOfCompetitor();
|
||||
if (trackedLegOfCompetitor.getStartTime() != null && trackedLegOfCompetitor.getFinishTime() != null) {
|
||||
for (GPSFixMoving gpsFix : competitorTrack.getFixes(trackedLegOfCompetitor.getStartTime(), true, trackedLegOfCompetitor.getFinishTime(), true)) {
|
||||
if (isAborted()) {
|
||||
break;
|
||||
}
|
||||
HasGPSFixContext gpsFixWithContext = new GPSFixWithContext(new TrackedLegOfCompetitorWithSpecificTimePointWithContext(
|
||||
final HasGPSFixContext gpsFixWithContext = new GPSFixWithContext(new TrackedLegOfCompetitorWithSpecificTimePointWithContext(
|
||||
element.getTrackedLegContext(), element.getTrackedLegOfCompetitor(), gpsFix.getTimePoint()), gpsFix);
|
||||
gpsFixesWithContext.add(gpsFixWithContext);
|
||||
}
|
||||
|
||||
+13
-4
@@ -7,17 +7,26 @@ import java.util.concurrent.ExecutorService;
|
||||
import com.sap.sailing.datamining.data.HasRaceOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
|
||||
import com.sap.sailing.datamining.impl.data.RaceOfCompetitorWithContext;
|
||||
import com.sap.sailing.datamining.shared.TackTypeSegmentsDataMiningSettings;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sse.datamining.components.Processor;
|
||||
import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor;
|
||||
|
||||
public class RaceOfCompetitorRetrievalProcessor extends AbstractRetrievalProcessor<HasTrackedRaceContext, HasRaceOfCompetitorContext> {
|
||||
/**
|
||||
* Settings will be used to control the retrieval of tack type segments for the
|
||||
* corresponding statistics such as distance/duration relation between long and
|
||||
* short tack for the race of the competitor
|
||||
*/
|
||||
private final TackTypeSegmentsDataMiningSettings settings;
|
||||
|
||||
public RaceOfCompetitorRetrievalProcessor(ExecutorService executor,
|
||||
Collection<Processor<HasRaceOfCompetitorContext, ?>> resultReceivers, int retrievalLevel,
|
||||
String retrievedDataTypeMessageKey) {
|
||||
super(HasTrackedRaceContext.class, HasRaceOfCompetitorContext.class, executor, resultReceivers, retrievalLevel,
|
||||
Collection<Processor<HasRaceOfCompetitorContext, ?>> resultReceivers,
|
||||
TackTypeSegmentsDataMiningSettings settings, int retrievalLevel, String retrievedDataTypeMessageKey) {
|
||||
super(HasTrackedRaceContext.class,
|
||||
HasRaceOfCompetitorContext.class, executor, resultReceivers, retrievalLevel,
|
||||
retrievedDataTypeMessageKey);
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -28,7 +37,7 @@ public class RaceOfCompetitorRetrievalProcessor extends AbstractRetrievalProcess
|
||||
if (isAborted()) {
|
||||
break;
|
||||
}
|
||||
HasRaceOfCompetitorContext raceOfCompetitorWithContext = new RaceOfCompetitorWithContext(element, competitor);
|
||||
HasRaceOfCompetitorContext raceOfCompetitorWithContext = new RaceOfCompetitorWithContext(element, competitor, settings);
|
||||
raceOfCompetitorsWithContext.add(raceOfCompetitorWithContext);
|
||||
}
|
||||
}
|
||||
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
package com.sap.sailing.datamining.impl.components;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasRaceOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.data.HasTackTypeSegmentContext;
|
||||
import com.sap.sailing.datamining.impl.data.GPSFixTrackWithContext;
|
||||
import com.sap.sailing.datamining.impl.data.TackTypeSegmentWithContext;
|
||||
import com.sap.sailing.datamining.shared.TackTypeSegmentsDataMiningSettings;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.TackType;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.datamining.components.Processor;
|
||||
import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor;
|
||||
|
||||
public class TackTypeSegmentRetrievalProcessor extends AbstractRetrievalProcessor<HasRaceOfCompetitorContext, HasTackTypeSegmentContext> {
|
||||
private final TackTypeSegmentsDataMiningSettings settings;
|
||||
|
||||
public TackTypeSegmentRetrievalProcessor(ExecutorService executor,
|
||||
Collection<Processor<HasTackTypeSegmentContext, ?>> resultReceivers,
|
||||
TackTypeSegmentsDataMiningSettings settings, int retrievalLevel, String retrievedDataTypeMessageKey) {
|
||||
super(HasRaceOfCompetitorContext.class, HasTackTypeSegmentContext.class, executor, resultReceivers,
|
||||
retrievalLevel, retrievedDataTypeMessageKey);
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<HasTackTypeSegmentContext> retrieveData(HasRaceOfCompetitorContext element) {
|
||||
List<HasTackTypeSegmentContext> tackTypeSegments = new ArrayList<>();
|
||||
final TrackedRace trackedRace = element.getTrackedRaceContext().getTrackedRace();
|
||||
final TimePoint startOfRace = element.getTrackedRaceContext().getTrackedRace().getStartOfRace();
|
||||
final Competitor competitor = element.getCompetitor();
|
||||
if (startOfRace != null) {
|
||||
final GPSFixTrack<Competitor, GPSFixMoving> gpsFixTrack = trackedRace.getTrack(element.getCompetitor());
|
||||
if (gpsFixTrack != null) {
|
||||
final Iterator<MarkPassing> markPassingIterator = trackedRace.getMarkPassings(competitor).iterator();
|
||||
if (markPassingIterator.hasNext()) { // only search for tack type segments if the competitor has started the race
|
||||
MarkPassing legStartMarkPassing = markPassingIterator.next();
|
||||
TrackedLegOfCompetitor trackedLegOfCompetitor = trackedRace.getTrackedLegStartingAt(legStartMarkPassing.getWaypoint()).getTrackedLeg(competitor);
|
||||
MarkPassing nextMarkPassing = markPassingIterator.hasNext() ? markPassingIterator.next() : null;
|
||||
final Waypoint finish = trackedRace.getRace().getCourse().getLastWaypoint();
|
||||
TackType currentTackType = null;
|
||||
boolean segmentEmpty = true;
|
||||
TackType nextTackType = null;
|
||||
TimePoint startOfCurrentSegment = legStartMarkPassing.getTimePoint();
|
||||
GPSFix gpsFix = null;
|
||||
gpsFixTrack.lockForRead();
|
||||
try {
|
||||
// run through all of the competitor's fixes, starting at the first mark passing and finishing when there are
|
||||
// no more fixes left or the finish mark passing has been reached
|
||||
for (final Iterator<GPSFixMoving> i=gpsFixTrack.getFixesIterator(startOfCurrentSegment, /* fromInclusive */ true);
|
||||
i.hasNext() && legStartMarkPassing.getWaypoint() != finish; ) {
|
||||
if (isAborted()) {
|
||||
break;
|
||||
}
|
||||
gpsFix = i.next();
|
||||
while (nextMarkPassing != null && !gpsFix.getTimePoint().before(nextMarkPassing.getTimePoint())) {
|
||||
// reached leg's end; complete the current segment if not empty and move through mark passings
|
||||
// iterator until having found the leg the gpsFix is in, while moving the trackedLegOfCompetitor along
|
||||
legStartMarkPassing = nextMarkPassing;
|
||||
if (!segmentEmpty) {
|
||||
addOrMergeTackTypeSegment(element, tackTypeSegments, gpsFixTrack, startOfCurrentSegment,
|
||||
nextMarkPassing.getTimePoint(), currentTackType);
|
||||
segmentEmpty = gpsFix.getTimePoint().equals(nextMarkPassing.getTimePoint()); // if the fix is exactly at leg start
|
||||
startOfCurrentSegment = nextMarkPassing.getTimePoint();
|
||||
}
|
||||
// if nextMarkPassing is last MarkPassing there will be no leg after, trackedLeg is null
|
||||
trackedLegOfCompetitor = nextMarkPassing.getWaypoint()==finish ? null : trackedRace.getTrackedLegStartingAt(nextMarkPassing.getWaypoint()).getTrackedLeg(competitor);
|
||||
nextMarkPassing = markPassingIterator.hasNext() ? markPassingIterator.next() : null;
|
||||
}
|
||||
try {
|
||||
// no null case like line 87, because for loop checks that mark passing at leg start is not finish mark passing
|
||||
nextTackType = trackedLegOfCompetitor == null ? null : trackedLegOfCompetitor.getTackType(gpsFix.getTimePoint());
|
||||
} catch (NoWindException e) {
|
||||
nextTackType = null;
|
||||
}
|
||||
// invariant: nextMarkPassing is either null or after gpsFix's time and representing the passing of the mark at the end
|
||||
// of the leg gpsFix is in; trackedLegOfCompetitor corresponds to the leg gpsFix is in
|
||||
if (!segmentEmpty && nextTackType != currentTackType) {
|
||||
addOrMergeTackTypeSegment(element, tackTypeSegments, gpsFixTrack, startOfCurrentSegment,
|
||||
gpsFix.getTimePoint() /* don't include the last interval ending at the non-TackType fix */, currentTackType);
|
||||
segmentEmpty = true; // because gpsFix is now exactly at the beginning of the new segment
|
||||
startOfCurrentSegment = gpsFix.getTimePoint();
|
||||
} else {
|
||||
segmentEmpty = false; // gpsFix is in the current segment
|
||||
}
|
||||
currentTackType = nextTackType;
|
||||
}
|
||||
} finally {
|
||||
gpsFixTrack.unlockAfterRead();
|
||||
}
|
||||
if (!segmentEmpty) {
|
||||
addOrMergeTackTypeSegment(element, tackTypeSegments, gpsFixTrack, startOfCurrentSegment, gpsFix.getTimePoint(), currentTackType);
|
||||
// no need to update segmentEmpty / startOfCurrentSegment / lastTackType because now we're done
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return tackTypeSegments;
|
||||
}
|
||||
|
||||
private void addOrMergeTackTypeSegment(HasRaceOfCompetitorContext element,
|
||||
List<HasTackTypeSegmentContext> tackTypeSegments, final GPSFixTrack<Competitor, GPSFixMoving> gpsFixTrack,
|
||||
TimePoint startOfSegment, TimePoint endOfSegment, TackType tackType) {
|
||||
if (settings.getMinimumTackTypeSegmentDuration() == null || startOfSegment.until(endOfSegment)
|
||||
.compareTo(settings.getMinimumTackTypeSegmentDuration()) >= 0) {
|
||||
if (tackTypeSegments.isEmpty() || settings.getMinimumDurationBetweenAdjacentTackTypeSegments() == null) {
|
||||
tackTypeSegments.add(createTackTypeSegment(startOfSegment, endOfSegment, element, gpsFixTrack, tackType));
|
||||
} else {
|
||||
// we wouldn't want to merge segments with different tack types; different from foiling segments where you *would* want to join to closely-adjacent foiled segments
|
||||
final HasTackTypeSegmentContext previousSegment = tackTypeSegments.get(tackTypeSegments.size()-1);
|
||||
final TimePoint previousEnd = previousSegment.getEndOfTackTypeSegment();
|
||||
if (previousSegment.getTackType() == tackType && previousEnd.until(startOfSegment).compareTo(settings.getMinimumDurationBetweenAdjacentTackTypeSegments()) < 0) {
|
||||
// merge:
|
||||
tackTypeSegments.set(tackTypeSegments.size()-1, createTackTypeSegment(previousSegment.getStartOfTackTypeSegment(), endOfSegment, element, gpsFixTrack, tackType));
|
||||
} else {
|
||||
// add; duration between the segments is large enough or tack type is different
|
||||
tackTypeSegments.add(createTackTypeSegment(startOfSegment, endOfSegment, element, gpsFixTrack, tackType));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private HasTackTypeSegmentContext createTackTypeSegment(TimePoint startOfSegment, TimePoint endOfSegment,
|
||||
HasRaceOfCompetitorContext raceOfCompetitorContext, GPSFixTrack<Competitor, GPSFixMoving> gpsFixTrack, TackType tackType) {
|
||||
return new TackTypeSegmentWithContext(new GPSFixTrackWithContext(raceOfCompetitorContext, gpsFixTrack), startOfSegment, endOfSegment, tackType);
|
||||
}
|
||||
|
||||
}
|
||||
+11
-3
@@ -7,17 +7,25 @@ import java.util.concurrent.ExecutorService;
|
||||
import com.sap.sailing.datamining.data.HasTrackedLegContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.impl.data.TrackedLegOfCompetitorWithContext;
|
||||
import com.sap.sailing.datamining.shared.TackTypeSegmentsDataMiningSettings;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sse.datamining.components.Processor;
|
||||
import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor;
|
||||
|
||||
public class TrackedLegOfCompetitorRetrievalProcessor extends AbstractRetrievalProcessor<HasTrackedLegContext, HasTrackedLegOfCompetitorContext> {
|
||||
/**
|
||||
* Settings will be used to control the retrieval of tack type segments for the
|
||||
* corresponding statistics such as distance/duration relation between long and
|
||||
* short tack for the leg of the competitor
|
||||
*/
|
||||
private final TackTypeSegmentsDataMiningSettings settings;
|
||||
|
||||
public TrackedLegOfCompetitorRetrievalProcessor(ExecutorService executor,
|
||||
Collection<Processor<HasTrackedLegOfCompetitorContext, ?>> resultReceivers, int retrievalLevel,
|
||||
String retrievedDataTypeMessageKey) {
|
||||
Collection<Processor<HasTrackedLegOfCompetitorContext, ?>> resultReceivers,
|
||||
TackTypeSegmentsDataMiningSettings settings, int retrievalLevel, String retrievedDataTypeMessageKey) {
|
||||
super(HasTrackedLegContext.class, HasTrackedLegOfCompetitorContext.class, executor, resultReceivers,
|
||||
retrievalLevel, retrievedDataTypeMessageKey);
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -27,7 +35,7 @@ public class TrackedLegOfCompetitorRetrievalProcessor extends AbstractRetrievalP
|
||||
if (isAborted()) {
|
||||
break;
|
||||
}
|
||||
HasTrackedLegOfCompetitorContext trackedLegOfCompetitorWithContext = new TrackedLegOfCompetitorWithContext(element, element.getTrackedLeg().getTrackedLeg(competitor));
|
||||
HasTrackedLegOfCompetitorContext trackedLegOfCompetitorWithContext = new TrackedLegOfCompetitorWithContext(element, element.getTrackedLeg().getTrackedLeg(competitor), settings);
|
||||
trackedLegOfCompetitorsWithContext.add(trackedLegOfCompetitorWithContext);
|
||||
}
|
||||
return trackedLegOfCompetitorsWithContext;
|
||||
|
||||
+4
-3
@@ -17,9 +17,10 @@ import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor;
|
||||
public class TrackedRaceRetrievalProcessor extends AbstractRetrievalProcessor<HasLeaderboardContext, HasTrackedRaceContext> {
|
||||
|
||||
public TrackedRaceRetrievalProcessor(ExecutorService executor,
|
||||
Collection<Processor<HasTrackedRaceContext, ?>> resultReceivers, int retrievalLevel,
|
||||
String retrievedDataTypeMessageKey) {
|
||||
super(HasLeaderboardContext.class, HasTrackedRaceContext.class, executor, resultReceivers, retrievalLevel,
|
||||
Collection<Processor<HasTrackedRaceContext, ?>> resultReceivers,
|
||||
int retrievalLevel, String retrievedDataTypeMessageKey) {
|
||||
super(HasLeaderboardContext.class,
|
||||
HasTrackedRaceContext.class, executor, resultReceivers, retrievalLevel,
|
||||
retrievedDataTypeMessageKey);
|
||||
}
|
||||
|
||||
|
||||
-1
@@ -38,5 +38,4 @@ public class CompetitorDayWithContext implements HasCompetitorDayContext {
|
||||
public String getDayAsISO() {
|
||||
return raceOfCompetitor.getTrackedRaceContext().getDayAsISO();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasCompetitorContext;
|
||||
import com.sap.sailing.datamining.data.HasLeaderboardContext;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
|
||||
public class CompetitorWithContext implements HasCompetitorContext {
|
||||
private final Competitor competitor;
|
||||
private final HasLeaderboardContext leaderboardContext;
|
||||
|
||||
public CompetitorWithContext(Competitor competitor, HasLeaderboardContext leaderboardContext) {
|
||||
super();
|
||||
this.competitor = competitor;
|
||||
this.leaderboardContext = leaderboardContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Competitor getCompetitor() {
|
||||
return competitor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HasLeaderboardContext getLeaderboardContext() {
|
||||
return leaderboardContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((competitor == null) ? 0 : competitor.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
CompetitorWithContext other = (CompetitorWithContext) obj;
|
||||
if (competitor == null) {
|
||||
if (other.competitor != null)
|
||||
return false;
|
||||
} else if (!competitor.equals(other.competitor))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasGPSFixTrackContext;
|
||||
import com.sap.sailing.datamining.data.HasRaceOfCompetitorContext;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||
|
||||
public class GPSFixTrackWithContext implements HasGPSFixTrackContext {
|
||||
|
||||
private final HasRaceOfCompetitorContext raceOfCompetitorContext;
|
||||
|
||||
private final GPSFixTrack<Competitor, GPSFixMoving> gpsFixTrack;
|
||||
|
||||
public GPSFixTrackWithContext(HasRaceOfCompetitorContext raceOfCompetitorContext, GPSFixTrack<Competitor, GPSFixMoving> gpsFixTrack) {
|
||||
this.raceOfCompetitorContext = raceOfCompetitorContext;
|
||||
this.gpsFixTrack = gpsFixTrack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HasRaceOfCompetitorContext getRaceOfCompetitorContext() {
|
||||
return raceOfCompetitorContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GPSFixTrack<Competitor, GPSFixMoving> getGPSFixTrack() {
|
||||
return gpsFixTrack;
|
||||
}
|
||||
}
|
||||
+18
@@ -4,10 +4,12 @@ import com.sap.sailing.datamining.data.HasGPSFixContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.TackType;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.Distance;
|
||||
import com.sap.sse.common.Speed;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
/**
|
||||
@@ -89,4 +91,20 @@ public class GPSFixWithContext implements HasGPSFixContext {
|
||||
public Distance getAbsoluteXTE() {
|
||||
return getTrackedLegOfCompetitorContext().getTrackedLegOfCompetitor().getAbsoluteCrossTrackError(getTimePoint());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TackType getTackType() throws NoWindException {
|
||||
return getTrackedLegOfCompetitorContext().getTrackedLegOfCompetitor().getTackType(getTimePoint());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Speed getSmoothedSpeed() {
|
||||
final SpeedWithBearing result;
|
||||
if (getGPSFix().isEstimatedSpeedCached()) {
|
||||
result = getGPSFix().getCachedEstimatedSpeed();
|
||||
} else {
|
||||
result = getTrackedLegOfCompetitorContext().getTrackedRace().getTrack(getTrackedLegOfCompetitorContext().getCompetitor()).getEstimatedSpeed(getTimePoint());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+53
-1
@@ -11,7 +11,10 @@ import java.util.function.BiFunction;
|
||||
import com.sap.sailing.datamining.Activator;
|
||||
import com.sap.sailing.datamining.SailingClusterGroups;
|
||||
import com.sap.sailing.datamining.data.HasRaceOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.data.HasTackTypeSegmentContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
|
||||
import com.sap.sailing.datamining.impl.components.TackTypeSegmentRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.shared.TackTypeSegmentsDataMiningSettings;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Course;
|
||||
@@ -53,10 +56,12 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext {
|
||||
|
||||
private final HasTrackedRaceContext trackedRaceContext;
|
||||
private final Competitor competitor;
|
||||
private final TackTypeSegmentsDataMiningSettings settings;
|
||||
|
||||
public RaceOfCompetitorWithContext(HasTrackedRaceContext trackedRaceContext, Competitor competitor) {
|
||||
public RaceOfCompetitorWithContext(HasTrackedRaceContext trackedRaceContext, Competitor competitor, TackTypeSegmentsDataMiningSettings settings) {
|
||||
this.trackedRaceContext = trackedRaceContext;
|
||||
this.competitor = competitor;
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -662,4 +667,51 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext {
|
||||
Integer rank = getTrackedRace().getRank(getCompetitor(), timePoint);
|
||||
return rank == 0 ? null : rank;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getRatioDurationLongVsShortTack() {
|
||||
final TackTypeRatioCollector<Duration> resultProcessor = new TackTypeRatioCollector<Duration>(Duration.NULL) {
|
||||
@Override
|
||||
protected Duration add(Duration a, Duration b) {
|
||||
return a.plus(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double divide(Duration a, Duration b) {
|
||||
return a.divide(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Duration getAddable(HasTackTypeSegmentContext element) {
|
||||
return element.getDuration();
|
||||
}
|
||||
};
|
||||
final TackTypeSegmentRetrievalProcessor tackTypeSegmentRetriever = new TackTypeSegmentRetrievalProcessor(
|
||||
/* executor */ null,
|
||||
Collections.emptySet(), settings, 0, "TackTypeSegments");
|
||||
return Util.stream(tackTypeSegmentRetriever.retrieveData(this)).collect(resultProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getRatioDistanceLongVsShortTack() {
|
||||
final TackTypeRatioCollector<Distance> resultProcessor = new TackTypeRatioCollector<Distance>(Distance.NULL) {
|
||||
@Override
|
||||
protected Distance add(Distance a, Distance b) {
|
||||
return a.add(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double divide(Distance a, Distance b) {
|
||||
return a.divide(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Distance getAddable(HasTackTypeSegmentContext element) {
|
||||
return element.getDistance();
|
||||
}
|
||||
};
|
||||
final TackTypeSegmentRetrievalProcessor tackTypeSegmentRetriever = new TackTypeSegmentRetrievalProcessor(/* executor */ null,
|
||||
Collections.emptySet(), settings, 0, "TackTypeSegments");
|
||||
return Util.stream(tackTypeSegmentRetriever.retrieveData(this)).collect(resultProcessor);
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collector;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasTackTypeSegmentContext;
|
||||
import com.sap.sailing.domain.common.TackType;
|
||||
|
||||
public abstract class TackTypeRatioCollector<ADDABLE> implements Collector<HasTackTypeSegmentContext, Map<TackType, ADDABLE>, Double> {
|
||||
|
||||
private final ADDABLE nullValue;
|
||||
|
||||
public TackTypeRatioCollector(ADDABLE nullValue) {
|
||||
this.nullValue = nullValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Supplier<Map<TackType, ADDABLE>> supplier() {
|
||||
return ()->{
|
||||
final Map<TackType, ADDABLE> result = new HashMap<>();
|
||||
for (final TackType tt : TackType.values()) {
|
||||
result.put(tt, nullValue);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiConsumer<Map<TackType, ADDABLE>, HasTackTypeSegmentContext> accumulator() {
|
||||
return (sumPerTackType, element)->{
|
||||
final TackType tt = element.getTackType();
|
||||
synchronized (this) {
|
||||
sumPerTackType.put(tt, add(sumPerTackType.get(tt), getAddable(element)));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BinaryOperator<Map<TackType, ADDABLE>> combiner() {
|
||||
return (r1, r2) -> {
|
||||
for (final Entry<TackType, ADDABLE> e : r1.entrySet()) {
|
||||
r2.put(e.getKey(), add(e.getValue(), r2.get(e.getKey())));
|
||||
}
|
||||
return r2;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Function<Map<TackType, ADDABLE>, Double> finisher() {
|
||||
return sumPerTackType->{
|
||||
final ADDABLE shortTackSum = sumPerTackType.get(TackType.SHORTTACK);
|
||||
return shortTackSum.equals(nullValue) ? null : divide(sumPerTackType.get(TackType.LONGTACK), shortTackSum);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<Characteristics> characteristics() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
protected abstract ADDABLE add(ADDABLE a, ADDABLE b);
|
||||
|
||||
protected abstract double divide(ADDABLE a, ADDABLE b);
|
||||
|
||||
protected abstract ADDABLE getAddable(HasTackTypeSegmentContext element);
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasGPSFixTrackContext;
|
||||
import com.sap.sailing.datamining.data.HasTackTypeSegmentContext;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.LegType;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.TackType;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sse.common.Distance;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
public class TackTypeSegmentWithContext implements HasTackTypeSegmentContext {
|
||||
private final HasGPSFixTrackContext gpsFixTrackContext;
|
||||
private final TimePoint startOfTackTypeSegment;
|
||||
private final TimePoint endOfTackTypeSegment; // TODO is this exclusive or inclusive? Suggestion: it should be exclusive, as usual in most Java interval specifications; please comment accordingly
|
||||
private final TackType tackType;
|
||||
private static final SimpleDateFormat TIMEPOINT_FORMATTER = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
|
||||
|
||||
public TackTypeSegmentWithContext(GPSFixTrackWithContext gpsFixTrackWithContext, TimePoint startOfTackTypeSegment,
|
||||
TimePoint endOfTackTypeSegment, TackType tackType) {
|
||||
super();
|
||||
this.gpsFixTrackContext = gpsFixTrackWithContext;
|
||||
this.startOfTackTypeSegment = startOfTackTypeSegment;
|
||||
this.endOfTackTypeSegment = endOfTackTypeSegment;
|
||||
this.tackType = tackType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return gpsFixTrackContext.getRaceOfCompetitorContext().getCompetitor().getName() + "@"
|
||||
+ TIMEPOINT_FORMATTER.format(startOfTackTypeSegment.asDate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public HasGPSFixTrackContext getGPSFixTrackContext() {
|
||||
return gpsFixTrackContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimePoint getStartOfTackTypeSegment() {
|
||||
return startOfTackTypeSegment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimePoint getEndOfTackTypeSegment() {
|
||||
return endOfTackTypeSegment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getDuration() {
|
||||
return getStartOfTackTypeSegment().until(getEndOfTackTypeSegment());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getDistance() {
|
||||
return getGpsFixTrack().
|
||||
getDistanceTraveled(getStartOfTackTypeSegment(), getEndOfTackTypeSegment());
|
||||
}
|
||||
|
||||
private GPSFixTrack<Competitor, GPSFixMoving> getGpsFixTrack() {
|
||||
return getTrackedRace().getTrack(getCompetitor());
|
||||
}
|
||||
|
||||
private Competitor getCompetitor() {
|
||||
return getGPSFixTrackContext().getRaceOfCompetitorContext().getCompetitor();
|
||||
}
|
||||
|
||||
private TrackedRace getTrackedRace() {
|
||||
return getGPSFixTrackContext().getRaceOfCompetitorContext().getTrackedRaceContext().getTrackedRace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TackType getTackType() {
|
||||
return tackType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LegType getLegType() throws NoWindException {
|
||||
return getTrackedLeg().getLegType(
|
||||
getStartOfTackTypeSegment().plus(getStartOfTackTypeSegment().until(getEndOfTackTypeSegment()).divide(2)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLegNumber() {
|
||||
final TrackedLeg trackedLeg = getTrackedLeg();
|
||||
return trackedLeg == null ? 0 : getTrackedRace().getRace().getCourse().getIndexOfWaypoint(trackedLeg.getLeg().getTo());
|
||||
}
|
||||
|
||||
private TrackedLeg getTrackedLeg() {
|
||||
return getTrackedRace().getTrackedLeg(getCompetitor(), getStartOfTackTypeSegment()).getTrackedLeg();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TackTypeSegmentWithContext [gpsFixTrackContext=" + gpsFixTrackContext + ", startOfTackTypeSegment="
|
||||
+ startOfTackTypeSegment + ", endOfTackTypeSegment=" + endOfTackTypeSegment + ", tackType=" + tackType
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
+58
-1
@@ -10,8 +10,11 @@ import java.util.function.Supplier;
|
||||
|
||||
import com.sap.sailing.datamining.Activator;
|
||||
import com.sap.sailing.datamining.SailingClusterGroups;
|
||||
import com.sap.sailing.datamining.data.HasTackTypeSegmentContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedLegContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.impl.components.TackTypeSegmentRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.shared.TackTypeSegmentsDataMiningSettings;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Leg;
|
||||
@@ -44,6 +47,7 @@ public class TrackedLegOfCompetitorWithContext implements HasTrackedLegOfCompeti
|
||||
private static final long serialVersionUID = 5944904146286262768L;
|
||||
|
||||
private final HasTrackedLegContext trackedLegContext;
|
||||
private final TackTypeSegmentsDataMiningSettings settings;
|
||||
|
||||
private final TrackedLegOfCompetitor trackedLegOfCompetitor;
|
||||
private final Competitor competitor;
|
||||
@@ -54,10 +58,11 @@ public class TrackedLegOfCompetitorWithContext implements HasTrackedLegOfCompeti
|
||||
private boolean isRankAtFinishInitialized;
|
||||
private Wind wind;
|
||||
|
||||
public TrackedLegOfCompetitorWithContext(HasTrackedLegContext trackedLegContext, TrackedLegOfCompetitor trackedLegOfCompetitor) {
|
||||
public TrackedLegOfCompetitorWithContext(HasTrackedLegContext trackedLegContext, TrackedLegOfCompetitor trackedLegOfCompetitor, TackTypeSegmentsDataMiningSettings settings) {
|
||||
this.trackedLegContext = trackedLegContext;
|
||||
this.trackedLegOfCompetitor = trackedLegOfCompetitor;
|
||||
this.competitor = trackedLegOfCompetitor.getCompetitor();
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -516,4 +521,56 @@ public class TrackedLegOfCompetitorWithContext implements HasTrackedLegOfCompeti
|
||||
final TimePoint finishTime = getTrackedLegOfCompetitor().getFinishTime();
|
||||
return getTrackedLegOfCompetitor().getAverageVelocityMadeGood(finishTime == null ? TimePoint.now() : finishTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getRatioDurationLongVsShortTack() {
|
||||
final TackTypeRatioCollector<Duration> resultProcessor = new TackTypeRatioCollector<Duration>(Duration.NULL) {
|
||||
@Override
|
||||
protected Duration add(Duration a, Duration b) {
|
||||
return a.plus(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double divide(Duration a, Duration b) {
|
||||
return a.divide(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Duration getAddable(HasTackTypeSegmentContext element) {
|
||||
return element.getDuration();
|
||||
}
|
||||
};
|
||||
final TackTypeSegmentRetrievalProcessor tackTypeSegmentRetriever = new TackTypeSegmentRetrievalProcessor(
|
||||
/* executor */ null,
|
||||
Collections.emptySet(), settings, 0, "TackTypeSegments");
|
||||
return Util.stream(tackTypeSegmentRetriever.retrieveData(
|
||||
new RaceOfCompetitorWithContext(getTrackedLegContext().getTrackedRaceContext(), competitor, settings)))
|
||||
.filter(tt->tt.getLegNumber() == getTrackedLegContext().getLegNumber()).collect(resultProcessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getRatioDistanceLongVsShortTack() {
|
||||
final TackTypeRatioCollector<Distance> resultProcessor = new TackTypeRatioCollector<Distance>(Distance.NULL) {
|
||||
@Override
|
||||
protected Distance add(Distance a, Distance b) {
|
||||
return a.add(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double divide(Distance a, Distance b) {
|
||||
return a.divide(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Distance getAddable(HasTackTypeSegmentContext element) {
|
||||
return element.getDistance();
|
||||
}
|
||||
};
|
||||
final TackTypeSegmentRetrievalProcessor tackTypeSegmentRetriever = new TackTypeSegmentRetrievalProcessor(
|
||||
/* executor */ null,
|
||||
Collections.emptySet(), settings, 0, "TackTypeSegments");
|
||||
return Util.stream(tackTypeSegmentRetriever.retrieveData(
|
||||
new RaceOfCompetitorWithContext(getTrackedLegContext().getTrackedRaceContext(), competitor, settings)))
|
||||
.filter(tt->tt.getLegNumber() == getTrackedLegContext().getLegNumber()).collect(resultProcessor);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -3,6 +3,7 @@ package com.sap.sailing.datamining.impl.data;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasTrackedLegContext;
|
||||
import com.sap.sailing.datamining.shared.TackTypeSegmentsDataMiningSettings;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
@@ -26,7 +27,7 @@ public class TrackedLegOfCompetitorWithSpecificTimePointWithContext extends Trac
|
||||
|
||||
public TrackedLegOfCompetitorWithSpecificTimePointWithContext(HasTrackedLegContext trackedLegContext,
|
||||
TrackedLegOfCompetitor trackedLegOfCompetitor, TimePoint timePoint) {
|
||||
super(trackedLegContext, trackedLegOfCompetitor);
|
||||
super(trackedLegContext, trackedLegOfCompetitor, TackTypeSegmentsDataMiningSettings.createDefaultSettings());
|
||||
this.timePoint = timePoint;
|
||||
}
|
||||
|
||||
|
||||
+6
-1
@@ -6,6 +6,7 @@ import com.sap.sailing.domain.common.LegType;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sse.common.Distance;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
@@ -97,5 +98,9 @@ public class TrackedLegWithContext implements HasTrackedLegContext {
|
||||
}
|
||||
return at;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Distance getLegLength() {
|
||||
return getTrackedLeg().getWindwardDistance();
|
||||
}
|
||||
}
|
||||
|
||||
+14
@@ -3,6 +3,8 @@ package com.sap.sailing.datamining.impl.data;
|
||||
import com.sap.sailing.datamining.data.HasWindFixContext;
|
||||
import com.sap.sailing.datamining.data.HasWindTrackContext;
|
||||
import com.sap.sailing.domain.common.Wind;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sse.common.impl.TimeRangeImpl;
|
||||
|
||||
/**
|
||||
* Equality is based on the {@link #getWind() wind fix} only.
|
||||
@@ -72,6 +74,18 @@ public class WindFixWithContext implements HasWindFixContext {
|
||||
return windSourceType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInTrackingInterval() {
|
||||
final TrackedRace trackedRace = getWindTrackContext().getTrackedRaceContext().getTrackedRace();
|
||||
return trackedRace != null && new TimeRangeImpl(trackedRace.getStartOfTracking(), trackedRace.getEndOfTracking()).includes(getTimePoint());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInRace() {
|
||||
final TrackedRace trackedRace = getWindTrackContext().getTrackedRaceContext().getTrackedRace();
|
||||
return trackedRace != null && new TimeRangeImpl(trackedRace.getStartOfRace(), trackedRace.getEndOfRace()).includes(getTimePoint());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WindFixWithContext [trackedRaceContext=" + windTrackContext + ", windSourceType=" + windSourceType
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
|
||||
<booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/com.sap.sailing.declination/src/com/sap/sailing/declination/impl/DeclinationStore.java"/>
|
||||
</listAttribute>
|
||||
@@ -8,6 +9,6 @@
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.sap.sailing.declination.impl.DeclinationStore"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="com.sap.sailing.declination"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="2022 2022 1"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="2024 2024 1"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.declination"/>
|
||||
</launchConfiguration>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+5
-3
@@ -89,15 +89,17 @@ public class AbstractPosition implements Position {
|
||||
|
||||
@Override
|
||||
public Bearing getBearingGreatCircle(Position p) {
|
||||
Bearing bearing = null;
|
||||
final Bearing bearing;
|
||||
if (p != null) {
|
||||
double result = Math.atan2(Math.sin(p.getLngRad() - getLngRad()) * Math.cos(p.getLatRad()),
|
||||
Math.cos(getLatRad()) * Math.sin(p.getLatRad()) - Math.sin(getLatRad()) * Math.cos(p.getLatRad())
|
||||
* Math.cos(p.getLngRad() - getLngRad()));
|
||||
Math.cos(getLatRad()) * Math.sin(p.getLatRad())
|
||||
- Math.sin(getLatRad()) * Math.cos(p.getLatRad()) * Math.cos(p.getLngRad() - getLngRad()));
|
||||
if (result < 0) {
|
||||
result = result + 2 * Math.PI;
|
||||
}
|
||||
bearing = new RadianBearingImpl(result);
|
||||
} else {
|
||||
bearing = null;
|
||||
}
|
||||
return bearing;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.sap.sse.security.shared.HasPermissions.Action;
|
||||
*
|
||||
*/
|
||||
public enum DetailType implements Serializable {
|
||||
LEG_TACKTYPE_LONGTACK_SHORTTACK(0, ASCENDING, PREMIUM_LEADERBOARD_INFORMATION, "TACKTYPE"),
|
||||
LEG_DISTANCE_TRAVELED(0, ASCENDING, PREMIUM_LEADERBOARD_INFORMATION, "DISTANCE_TRAVELED"),
|
||||
LEG_DISTANCE_TRAVELED_INCLUDING_GATE_START(0, ASCENDING, null, "DISTANCE_TRAVELED_INCLUDING_GATE_START"),
|
||||
LEG_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING, PREMIUM_LEADERBOARD_INFORMATION, "AVERAGE_SPEED_OVER_GROUND_IN_KNOTS"),
|
||||
@@ -220,6 +221,13 @@ public enum DetailType implements Serializable {
|
||||
|
||||
private final String[] oldNames;
|
||||
|
||||
/**
|
||||
* @param precision
|
||||
* the number of decimal digits in which they are usually provided and should be formatted
|
||||
* @param premiumAction
|
||||
* If not {@code null} then the user must have permission to execute this action on the leaderboard to
|
||||
* which it is applied.
|
||||
*/
|
||||
DetailType(int precision, SortingOrder defaultSortingOrder, Action premiumAction, String... oldNames) {
|
||||
this.oldNames = oldNames;
|
||||
this.precision = precision;
|
||||
@@ -227,6 +235,9 @@ public enum DetailType implements Serializable {
|
||||
this.defaultSortingOrder = defaultSortingOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of decimal digits in which they are usually provided and should be formatted
|
||||
*/
|
||||
public int getPrecision() {
|
||||
return precision;
|
||||
}
|
||||
@@ -274,6 +285,7 @@ public enum DetailType implements Serializable {
|
||||
*/
|
||||
public static Collection<DetailType> getAutoplayDetailTypesForChart() {
|
||||
final Collection<DetailType> availableDetailsTypes = new LinkedHashSet<>();
|
||||
availableDetailsTypes.add(DetailType.LEG_TACKTYPE_LONGTACK_SHORTTACK);
|
||||
availableDetailsTypes.add(DetailType.CHART_WINDWARD_DISTANCE_TO_COMPETITOR_FARTHEST_AHEAD);
|
||||
availableDetailsTypes.add(DetailType.LEG_CURRENT_SPEED_OVER_GROUND_IN_KNOTS);
|
||||
availableDetailsTypes.add(DetailType.LEG_DISTANCE_TRAVELED);
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.sap.sailing.domain.common;
|
||||
/**
|
||||
* The TackType describes how the boat is driving in relation to the next mark.
|
||||
*/
|
||||
public enum TackType {
|
||||
/**
|
||||
* The long tack takes you back towards the windline that goes though the next mark. It is the longer tack in a leg.
|
||||
*/
|
||||
LONGTACK,
|
||||
/**
|
||||
* The short tack takes you away from the windline that goes though the next mark. It is the shorter tack in a leg.
|
||||
*/
|
||||
SHORTTACK
|
||||
}
|
||||
+1
-1
@@ -55,7 +55,7 @@ public class DataImportProgressImpl implements DataImportProgress {
|
||||
@Override
|
||||
public void setCurrentSubProgress(DataImportSubProgress subProgress) {
|
||||
if (subProgress != currentSubProgress) {
|
||||
logger.info("Master data import with operation ID "+getOperationId()+" moving from stage "+currentSubProgressPct+" to "+subProgress);
|
||||
logger.info("Master data import with operation ID "+getOperationId()+" moving from stage "+currentSubProgress+" to "+subProgress);
|
||||
}
|
||||
currentSubProgress = subProgress;
|
||||
}
|
||||
|
||||
+1
@@ -35,6 +35,7 @@ public class WindImpl extends KnotSpeedWithBearingImpl implements Wind {
|
||||
public static int hashCode(double latDeg, double lngDeg, long timePointAsMillis) {
|
||||
return (31 * (int) (timePointAsMillis & Integer.MAX_VALUE)) ^ (int) (Math.round(latDeg)*Math.round(lngDeg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Wind hash is determined based on time point and position only to speed this up a little.
|
||||
*/
|
||||
|
||||
+2
-1
@@ -66,7 +66,8 @@ public class SecuredDomainType extends HasPermissionsImpl {
|
||||
EXPORT,
|
||||
SIMULATOR,
|
||||
VIEWSTREAMLETS,
|
||||
VIEWANALYSISCHARTS;
|
||||
VIEWANALYSISCHARTS,
|
||||
COLORED_TAILS;
|
||||
|
||||
private static final Action[] ALL_ACTIONS = DefaultActions.plus(TrackedRaceActions.values());
|
||||
|
||||
|
||||
+2
@@ -28,6 +28,8 @@ public class PremiumRole extends RolePrototype {
|
||||
.withActions(SecuredSecurityTypes.UserActions.BE_PREMIUM).build(),
|
||||
WildcardPermission.builder().withTypes(SecuredDomainType.TRACKED_RACE)
|
||||
.withActions(SecuredDomainType.TrackedRaceActions.VIEWANALYSISCHARTS).build(),
|
||||
WildcardPermission.builder().withTypes(SecuredDomainType.TRACKED_RACE)
|
||||
.withActions(SecuredDomainType.TrackedRaceActions.COLORED_TAILS).build(),
|
||||
WildcardPermission.builder().withTypes(SecuredDomainType.LEADERBOARD)
|
||||
.withActions(SecuredDomainType.LeaderboardActions.PREMIUM_LEADERBOARD_INFORMATION).build());
|
||||
}
|
||||
|
||||
+1
@@ -46,4 +46,5 @@ public interface BravoFix extends SensorFix {
|
||||
|
||||
@Statistic(messageKey = "heel", resultDecimals = 1)
|
||||
Bearing getHeel();
|
||||
|
||||
}
|
||||
|
||||
+2
-4
@@ -41,8 +41,6 @@ public class Activator implements BundleActivator {
|
||||
private static final Logger logger = Logger.getLogger(Activator.class.getName());
|
||||
private static Activator INSTANCE;
|
||||
|
||||
private static final String DEFAULT_CLIENT_ID = "d29eae61621af3057db0e638232a027e96b1d2291b1b89a1481dfcac075b0bf4";
|
||||
private static final String DEFAULT_CLIENT_SECRET = "537dbd14a84fcb470c91d85e8c4f8f7a356ac5ffc8727594d1bfe900ee5942ef";
|
||||
private static final String DEFAULT_REDIRECT_PROTOCOL = "https";
|
||||
private static final String DEFAULT_REDIRECT_HOST = "www.sapsailing.com";
|
||||
private static final String DEFAULT_REDIRECT_PORT = null; // port==null means default
|
||||
@@ -60,8 +58,8 @@ public class Activator implements BundleActivator {
|
||||
|
||||
public Activator() throws ClientProtocolException, IllegalStateException, IOException, ParseException {
|
||||
logger.info(getClass().getName()+" constructor");
|
||||
final String clientId = System.getProperty(CLIENT_ID_PROPERTY_NAME, DEFAULT_CLIENT_ID);
|
||||
final String clientSecret = System.getProperty(CLIENT_SECRET_PROPERTY_NAME, DEFAULT_CLIENT_SECRET);
|
||||
final String clientId = System.getProperty(CLIENT_ID_PROPERTY_NAME);
|
||||
final String clientSecret = System.getProperty(CLIENT_SECRET_PROPERTY_NAME);
|
||||
final String clientRedirectProtocol = System.getProperty(CLIENT_REDIRECT_PROTOCOL_PROPERTY_NAME, DEFAULT_REDIRECT_PROTOCOL);
|
||||
final String clientRedirectHost = System.getProperty(CLIENT_REDIRECT_HOST_PROPERTY_NAME, DEFAULT_REDIRECT_HOST);
|
||||
final String clientRedirectPort = System.getProperty(CLIENT_REDIRECT_PORT_PROPERTY_NAME, DEFAULT_REDIRECT_PORT);
|
||||
|
||||
@@ -17,7 +17,8 @@ Require-Bundle: com.sap.sailing.domain,
|
||||
com.sap.sailing.xrr.schema,
|
||||
com.sap.sailing.domain.shared.android,
|
||||
com.sun.xml.bind.jaxb-impl;bundle-version="2.3.0",
|
||||
com.sap.sse.security.common
|
||||
com.sap.sse.security.common,
|
||||
com.sap.sailing.manage2sail
|
||||
Export-Package: com.sap.sailing.domain.swisstimingadapter,
|
||||
com.sap.sailing.domain.swisstimingadapter.impl;x-friends:="com.sap.sailing.server.test,com.sap.sailing.mongodb.test,com.sap.sailing.domain.swisstimingadapter.persistence"
|
||||
Import-Package: com.sap.sailing.xrr.schema,
|
||||
|
||||
-3
@@ -3,7 +3,6 @@ package com.sap.sailing.domain.swisstimingadapter;
|
||||
import java.io.IOException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.text.ParseException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
|
||||
@@ -19,8 +18,6 @@ public interface SwissTimingAdapter {
|
||||
String NAME = "SwissTiming";
|
||||
String DEFAULT_URL = null;
|
||||
|
||||
List<com.sap.sailing.domain.swisstimingadapter.RaceRecord> getSwissTimingRaceRecords(String hostname, int port) throws InterruptedException, UnknownHostException, IOException, ParseException;
|
||||
|
||||
/**
|
||||
* @param regattaToAddTo
|
||||
* if <code>null</code>, an existing regatta by the name of the TracTrac event with the boat class name
|
||||
|
||||
+3
-2
@@ -4,6 +4,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.SocketException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.DecimalFormat;
|
||||
@@ -568,7 +569,7 @@ public abstract class AbstractSailMasterConnector extends SailMasterTransceiverI
|
||||
+ " which seems to be OK. I think we're connected in "+this+"!");
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
logger.log(Level.INFO, "Exception trying to establish connection in "+this+". Trying again in 1s.", e);
|
||||
disconnectAndWaitABit();
|
||||
}
|
||||
@@ -576,7 +577,7 @@ public abstract class AbstractSailMasterConnector extends SailMasterTransceiverI
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void connect() throws IOException;
|
||||
protected abstract void connect() throws IOException, URISyntaxException;
|
||||
|
||||
protected abstract boolean isConnected() throws IOException;
|
||||
|
||||
|
||||
+4
-2
@@ -4,6 +4,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.text.ParseException;
|
||||
@@ -12,6 +13,7 @@ import java.util.logging.Logger;
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.common.TrackedRaceStatusEnum;
|
||||
import com.sap.sailing.domain.swisstimingadapter.MessageType;
|
||||
import com.sap.sailing.manage2sail.Activator;
|
||||
import com.sap.sse.util.HttpUrlConnectionHelper;
|
||||
|
||||
/**
|
||||
@@ -67,9 +69,9 @@ public class SailMasterConnectorForUrlDownload extends AbstractSailMasterConnect
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void connect() throws IOException {
|
||||
protected void connect() throws IOException, URISyntaxException {
|
||||
logger.info("Connecting to "+raceDataUrl);
|
||||
urlConnection = HttpUrlConnectionHelper.redirectConnection(raceDataUrl);
|
||||
urlConnection = HttpUrlConnectionHelper.redirectConnection(Activator.getInstance().addAccessTokenToManage2SailUrl(raceDataUrl));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
-10
@@ -4,8 +4,6 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.UnknownHostException;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -58,14 +56,6 @@ public class SwissTimingAdapterImpl implements SwissTimingAdapter {
|
||||
return swissTimingFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<com.sap.sailing.domain.swisstimingadapter.RaceRecord> getSwissTimingRaceRecords(String hostname,
|
||||
int port) throws InterruptedException, UnknownHostException, IOException, ParseException {
|
||||
List<com.sap.sailing.domain.swisstimingadapter.RaceRecord> result = new ArrayList<com.sap.sailing.domain.swisstimingadapter.RaceRecord>();
|
||||
// TODO --> Frank: this needs to come from Manage2Sail and its JSON document somehow...
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaceHandle addSwissTimingRace(TrackerManager trackerManager, RegattaIdentifier regattaToAddTo, String raceID,
|
||||
String raceName, String raceDescription, BoatClass boatClass, String hostname, int port,
|
||||
|
||||
@@ -35,7 +35,9 @@ Require-Bundle: com.sap.sailing.domain,
|
||||
org.mongodb.driver-sync;bundle-version="4.3.1",
|
||||
org.apache.commons.math3;bundle-version="3.5.0",
|
||||
org.apache.shiro.core;bundle-version="1.2.2",
|
||||
org.hamcrest;bundle-version="2.2.0"
|
||||
org.hamcrest;bundle-version="2.2.0",
|
||||
net.bytebuddy.byte-buddy;bundle-version="1.12.18",
|
||||
net.bytebuddy.byte-buddy-agent;bundle-version="1.12.18"
|
||||
Export-Package: com.sap.sailing.domain.test,
|
||||
com.sap.sailing.domain.test.mock
|
||||
Import-Package: org.apache.commons.math;version="2.1.0",
|
||||
|
||||
+33
@@ -13,6 +13,7 @@ import org.junit.Test;
|
||||
import com.sap.sse.common.MultiTimeRange;
|
||||
import com.sap.sse.common.TimeRange;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.impl.MultiTimeRangeImpl;
|
||||
|
||||
public class MultiTimeRangeTest {
|
||||
@@ -104,4 +105,36 @@ public class MultiTimeRangeTest {
|
||||
assertEquals(createMulti(100, 120, 350, 400), createMulti(100, 200, 300, 400).subtract(createMulti(120, 350)));
|
||||
assertEquals(createMulti(100, 120, 350, 360, 370, 400), createMulti(100, 200, 300, 400).subtract(createMulti(120, 350, 360, 370)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrderingWithOf() {
|
||||
final MillisecondsTimePoint _10 = new MillisecondsTimePoint(10);
|
||||
final MillisecondsTimePoint _20 = new MillisecondsTimePoint(20);
|
||||
final MillisecondsTimePoint _100 = new MillisecondsTimePoint(100);
|
||||
final MillisecondsTimePoint _200 = new MillisecondsTimePoint(200);
|
||||
final MultiTimeRange mtr = MultiTimeRange.of(TimeRange.create(_100, _200), TimeRange.create(_10, _20));
|
||||
assertEquals(TimeRange.create(_10, _20), Util.get(mtr, 0));
|
||||
assertEquals(TimeRange.create(_100, _200), Util.get(mtr, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrderingWithUnion() {
|
||||
final MillisecondsTimePoint _10 = new MillisecondsTimePoint(10);
|
||||
final MillisecondsTimePoint _20 = new MillisecondsTimePoint(20);
|
||||
final MillisecondsTimePoint _100 = new MillisecondsTimePoint(100);
|
||||
final MillisecondsTimePoint _200 = new MillisecondsTimePoint(200);
|
||||
final MultiTimeRange mtr = MultiTimeRange.of(TimeRange.create(_100, _200)).union(TimeRange.create(_10, _20));
|
||||
assertEquals(TimeRange.create(_10, _20), Util.get(mtr, 0));
|
||||
assertEquals(TimeRange.create(_100, _200), Util.get(mtr, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyTimeRangeRemoval() {
|
||||
final MillisecondsTimePoint _10 = new MillisecondsTimePoint(10);
|
||||
final MillisecondsTimePoint _100 = new MillisecondsTimePoint(100);
|
||||
final MillisecondsTimePoint _200 = new MillisecondsTimePoint(200);
|
||||
final MultiTimeRange mtr = MultiTimeRange.of(TimeRange.create(_100, _200)).union(TimeRange.create(_10, _10));
|
||||
assertEquals(1, Util.size(mtr));
|
||||
assertEquals(TimeRange.create(_100, _200), Util.get(mtr, 0));
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ public class CalculateImageSizeFromUrlTest {
|
||||
public void calculateImageSizeFromUrl() throws IOException {
|
||||
int width = 350;
|
||||
int height = 150;
|
||||
ImageSize size = calculate("http://placekitten.com/" + width + "/" + height);
|
||||
ImageSize size = calculate("http://via.placeholder.com/" + width + "x" + height);
|
||||
assertTrue(size.getWidth() == width);
|
||||
assertTrue(size.getHeight() == height);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user