Merge branch 'master' into bug3344

This commit is contained in:
Axel Uhl committed 2015-12-03 09:47:09 +01:00
commit 80386be82b
73 files changed
+7284 -7137

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
#!/bin/sh
/usr/bin/s3cmd -c /root/.s3cfg sync s3://sapsailing-access-logs/elb-access-logs/ /var/log/old/elb-access-logs/ >/var/log/last-elb-access-logs-sync.out 2>/var/log/last-elb-access-logs-sync.err
+3 -1
View File
@@ -16,6 +16,8 @@ mkdir -p "$STATS"
# A sample line:
# 505Worlds2012.sapsailing.com 66.249.73.53 - - [12/Jan/2014:03:33:11 +0000] "GET /robots.txt HTTP/1.1" 404 238 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
echo Starting "$0" at `date` on file set "$*"
for i in $*; do
grep -q "^$i\$" $VISITED_FILES
if [ "$?" = "0" ]; then
@@ -50,4 +52,4 @@ for month in `cat $MONTHS`; do
done | tee $STATS/unique-ips-days-useragents-per-event-$month
echo "Wrote per-month results to $STATS/unique-ips-days-useragents-per-event-$month"
done
echo "Done."
echo "Done at `date`."
@@ -0,0 +1,16 @@
#!/bin/bash
CACHE=/var/log/old/cache/unique-ips-per-referrer
VISITED_FILES=$CACHE/visited
STATS=$CACHE/stats
MONTHS=$STATS/months
for month in `cat $MONTHS`; do
for i in ${STATS}/*.ips; do
echo -n "`basename $i .ips` "
cat $i | grep "^[^ ]* [0-9]*/$month .*" | sort -u | wc | awk '{ print $1; }'
# TODO consider producing an AWStats configuration file for each virtual host name and splitting all new logs into virtual host name-specific log files
done | tee $STATS/unique-ips-days-useragents-per-event-`echo $month | tr / -`
echo "Wrote per-month results to $STATS/unique-ips-days-useragents-per-event-$month"
done
echo "Done."
@@ -0,0 +1,26 @@
#!/bin/bash
CACHE=/var/log/old/cache/unique-ips-per-referrer
VISITED_FILES=$CACHE/visited
STATS=$CACHE/stats
MONTHS=$STATS/months
for i in ${STATS}/*.ips; do
echo -n "`basename $i .ips` "
cat $i | sort -u | wc | awk '{ print $1; }'
# TODO consider producing an AWStats configuration file for each virtual host name and splitting all new logs into virtual host name-specific log files
done | tee $STATS/unique-ips-days-useragents-per-event
echo "Wrote total results to $STATS/unique-ips-days-useragents-per-event"
# Now filter and group by month
cat ${STATS}/*.ips | awk '{ print $2; }' | sed -e 's/^[0-9]*\///' | sort -u >$MONTHS
for month in `cat $MONTHS`; do
for i in ${STATS}/*.ips; do
echo -n "`basename $i .ips` "
cat $i | grep "^[^ ]* [0-9]*/$month .*" | sort -u | wc | awk '{ print $1; }'
# TODO consider producing an AWStats configuration file for each virtual host name and splitting all new logs into virtual host name-specific log files
done | tee $STATS/unique-ips-days-useragents-per-event-`echo $month | tr / -`
echo "Wrote per-month results to $STATS/unique-ips-days-useragents-per-event-$month"
done
echo "Done."
@@ -11,19 +11,6 @@
<artifactId>com.sap.sailing.dashboards.gwt</artifactId>
<packaging>eclipse-plugin</packaging>
<repositories>
<repository>
<id>sonatype</id>
<url>http://oss.sonatype.org/content/repositories/snapshots</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>javax.validation</groupId>
+40 -40
View File
@@ -1,40 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sailing.domain.common</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sailing.domain.common</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -21,7 +21,7 @@ public abstract class AbstractSpeedImpl implements Speed {
@Override
public Duration getDuration(Distance distance) {
return new MillisecondsDurationImpl((long) (1000 * distance.getMeters() / getMetersPerSecond()));
return distance == null ? null : new MillisecondsDurationImpl((long) (1000 * distance.getMeters() / getMetersPerSecond()));
}
@Override
@@ -14,7 +14,8 @@ Require-Bundle: com.sap.sse.mongodb,
com.sap.sailing.server.gateway.serialization,
com.sap.sse.common,
com.sap.sse,
com.sap.sailing.server.gateway.serialization.shared.android
com.sap.sailing.server.gateway.serialization.shared.android,
com.sap.sse.shared.android
Export-Package: com.sap.sailing.domain.persistence,
com.sap.sailing.domain.persistence.impl;
x-friends:="com.sap.sailing.domain.persistence.test,
@@ -224,11 +224,11 @@ import com.sap.sse.common.impl.MillisecondsDurationImpl;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.impl.RGBColor;
import com.sap.sse.common.impl.TimeRangeImpl;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.ImageDescriptorImpl;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.common.media.VideoDescriptorImpl;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
import com.sap.sse.shared.media.impl.ImageDescriptorImpl;
import com.sap.sse.shared.media.impl.VideoDescriptorImpl;
public class DomainObjectFactoryImpl implements DomainObjectFactory {
private static final Logger logger = Logger.getLogger(DomainObjectFactoryImpl.class.getName());
@@ -1,39 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sailing.domain.shared.android</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sailing.domain.shared.android</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -1,98 +1,98 @@
package com.sap.sailing.domain.base;
import java.net.URL;
import java.util.Map;
import com.sap.sailing.domain.common.Renamable;
import com.sap.sse.common.Named;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.WithID;
import com.sap.sse.common.media.ImageSize;
import com.sap.sse.common.media.WithMedia;
/**
* Base interface for an Event consisting of all static information, which might be shared
* by the server and an Android application.
*/
public interface EventBase extends Named, WithDescription, Renamable, WithID, WithMedia {
void setDescription(String description);
/**
* @return a non-<code>null</code> venue for this event
*/
Venue getVenue();
/**
* @return the start date of the event
*/
TimePoint getStartDate();
void setStartDate(TimePoint startDate);
/**
* @return the end date of the event
*/
TimePoint getEndDate();
void setEndDate(TimePoint startDate);
boolean isPublic();
void setPublic(boolean isPublic);
/**
* @deprecated
* Returns a non-<code>null</code> live but unmodifiable collection of URLs pointing to image resources that can be
* used to represent the event, e.g., on a web page.
*
* @return a non-<code>null</code> value which may be empty
*/
Iterable<URL> getImageURLs();
/**
* @deprecated
* An event may have zero or more sponsors, each of which usually want to see their logo on the web page.
*
* @return the sponsors' logos; always non-<code>null</code> but possibly empty
*/
Iterable<URL> getSponsorImageURLs();
/**
* @deprecated
* An optional logo image; may return <code>null</code>.
*/
URL getLogoImageURL();
/**
* @deprecated
* Returns a non-<code>null</code> live but unmodifiable collection of URLs pointing to video resources that can be
* used to represent the event, e.g., on a web page.
*
* @return a non-<code>null</code> value which may be empty
*/
Iterable<URL> getVideoURLs();
/**
* @return the URL of the event's official web site, or <code>null</code> if such a site does not exist or its URL
* is not known
*/
URL getOfficialWebsiteURL();
void setOfficialWebsiteURL(URL officialWebsiteURL);
/**
* @return the URL of an external web site containing sailor related information like protests, official results, etc.
* or <code>null</code> if such a site does not exist or its URL is not known.
*/
URL getSailorsInfoWebsiteURL();
void setSailorsInfoWebsiteURL(URL sailorsInfoWebsiteURL);
Iterable<? extends LeaderboardGroupBase> getLeaderboardGroups();
/**
* Sets and converts all event images and videos from the old URL based format to the new richer format
* */
boolean setMediaURLs(Iterable<URL> imageURLs, Iterable<URL> sponsorImageURLs, Iterable<URL> videoURLs, URL logoImageURL, Map<URL, ImageSize> imageSizes);
}
package com.sap.sailing.domain.base;
import java.net.URL;
import java.util.Map;
import com.sap.sailing.domain.common.Renamable;
import com.sap.sse.common.Named;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.WithID;
import com.sap.sse.common.media.ImageSize;
import com.sap.sse.shared.media.WithMedia;
/**
* Base interface for an Event consisting of all static information, which might be shared
* by the server and an Android application.
*/
public interface EventBase extends Named, WithDescription, Renamable, WithID, WithMedia {
void setDescription(String description);
/**
* @return a non-<code>null</code> venue for this event
*/
Venue getVenue();
/**
* @return the start date of the event
*/
TimePoint getStartDate();
void setStartDate(TimePoint startDate);
/**
* @return the end date of the event
*/
TimePoint getEndDate();
void setEndDate(TimePoint startDate);
boolean isPublic();
void setPublic(boolean isPublic);
/**
* @deprecated
* Returns a non-<code>null</code> live but unmodifiable collection of URLs pointing to image resources that can be
* used to represent the event, e.g., on a web page.
*
* @return a non-<code>null</code> value which may be empty
*/
Iterable<URL> getImageURLs();
/**
* @deprecated
* An event may have zero or more sponsors, each of which usually want to see their logo on the web page.
*
* @return the sponsors' logos; always non-<code>null</code> but possibly empty
*/
Iterable<URL> getSponsorImageURLs();
/**
* @deprecated
* An optional logo image; may return <code>null</code>.
*/
URL getLogoImageURL();
/**
* @deprecated
* Returns a non-<code>null</code> live but unmodifiable collection of URLs pointing to video resources that can be
* used to represent the event, e.g., on a web page.
*
* @return a non-<code>null</code> value which may be empty
*/
Iterable<URL> getVideoURLs();
/**
* @return the URL of the event's official web site, or <code>null</code> if such a site does not exist or its URL
* is not known
*/
URL getOfficialWebsiteURL();
void setOfficialWebsiteURL(URL officialWebsiteURL);
/**
* @return the URL of an external web site containing sailor related information like protests, official results, etc.
* or <code>null</code> if such a site does not exist or its URL is not known.
*/
URL getSailorsInfoWebsiteURL();
void setSailorsInfoWebsiteURL(URL sailorsInfoWebsiteURL);
Iterable<? extends LeaderboardGroupBase> getLeaderboardGroups();
/**
* Sets and converts all event images and videos from the old URL based format to the new richer format
* */
boolean setMediaURLs(Iterable<URL> imageURLs, Iterable<URL> sponsorImageURLs, Iterable<URL> videoURLs, URL logoImageURL, Map<URL, ImageSize> imageSizes);
}
@@ -15,15 +15,15 @@ import com.sap.sailing.domain.base.Venue;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.ImageDescriptorImpl;
import com.sap.sse.common.media.ImageSize;
import com.sap.sse.common.media.MediaDescriptor;
import com.sap.sse.common.media.MediaTagConstants;
import com.sap.sse.common.media.MediaUtils;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.common.media.VideoDescriptorImpl;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.MediaDescriptor;
import com.sap.sse.shared.media.MediaUtils;
import com.sap.sse.shared.media.VideoDescriptor;
import com.sap.sse.shared.media.impl.ImageDescriptorImpl;
import com.sap.sse.shared.media.impl.VideoDescriptorImpl;
public abstract class EventBaseImpl implements EventBase {
private static final long serialVersionUID = -5749964088848611074L;
@@ -4,7 +4,6 @@ import java.util.logging.Logger;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
@@ -57,13 +56,13 @@ public class RawPositionReceiver extends AbstractReceiverWithQueue<IRaceCompetit
IRace race = event.getA().getRace();
DynamicTrackedRace trackedRace = getTrackedRace(race);
if (trackedRace != null) {
GPSFixMoving fix = getDomainFactory().createGPSFixMoving(event.getB());
if (getSimulator() != null) {
fix = new GPSFixMovingImpl(fix.getPosition(), getSimulator().delay(
fix.getTimePoint()), fix.getSpeed());
}
final GPSFixMoving fix = getDomainFactory().createGPSFixMoving(event.getB());
Competitor competitor = getDomainFactory().getOrCreateCompetitor(event.getA().getCompetitor());
trackedRace.recordFix(competitor, fix);
if (getSimulator() != null) {
getSimulator().scheduleCompetitorPosition(competitor, fix);
} else {
trackedRace.recordFix(competitor, fix);
}
} else {
logger.warning("Couldn't find tracked race for race " + race.getName()
+ ". Dropping raw position event " + event);
@@ -162,7 +162,7 @@ public class Simulator {
/**
* If {@link #advanceInMillis} is already set to a non-negative value, it is left alone, and
* {@link #delay(TimePoint)} is called. Otherwise, <code>time</code> is taken to be the original start time of the
* {@link #advance(TimePoint)} is called. Otherwise, <code>time</code> is taken to be the original start time of the
* race which is then used to compute {@link #advanceInMillis} such that
* <code>time.asMillis() + advanceInMillis == System.currentTimeMillis()</code>.
*/
@@ -238,21 +238,35 @@ public class Simulator {
// deliver an empty list now
trackedRace.updateMarkPassings(competitor, markPassings);
}
}
public void scheduleCompetitorPosition(final Competitor competitor, GPSFixMoving competitorFix) {
final RecordGPSFix<Competitor> recorder = (c, f)->trackedRace.recordFix(c, f);
scheduleFixRecording(competitor, competitorFix, recorder);
}
@FunctionalInterface
private static interface RecordGPSFix<T> {
void recordFix(T objectForFix, GPSFixMoving fix);
}
public void scheduleMarkPosition(final Mark mark, GPSFixMoving markFix) {
final TimePoint transformedTimepoint = advance(markFix.getTimePoint());
final GPSFixMoving transformedMarkFix = new GPSFixMovingImpl(markFix.getPosition(), transformedTimepoint, markFix.getSpeed());
final RecordGPSFix<Mark> recorder = (m, f)->trackedRace.recordFix(mark, f);
scheduleFixRecording(mark, markFix, recorder);
}
private <T> void scheduleFixRecording(final T object, GPSFixMoving fix, final RecordGPSFix<T> recorder) {
final TimePoint transformedTimepoint = advance(fix.getTimePoint());
final GPSFixMoving transformedMarkFix = new GPSFixMovingImpl(fix.getPosition(), transformedTimepoint, fix.getSpeed());
long waitTime = getWaitTimeInMillisUntil(transformedMarkFix.getTimePoint());
if (waitTime <= 0) {
trackedRace.recordFix(mark, transformedMarkFix);
recorder.recordFix(object, transformedMarkFix);
} else {
timer.schedule(new TimerTask() {
@Override
public void run() {
try {
trackedRace.recordFix(mark, transformedMarkFix);
recorder.recordFix(object, transformedMarkFix);
} catch (Exception e) {
logger.throwing(Simulator.class.getName(), "scheduleMarkPosition", e);
}
@@ -50,6 +50,7 @@
<plugin id="com.sap.sailing.monitoring" autoStart="true" startLevel="6" />
<plugin id="com.sap.sailing.news" autoStart="true" startLevel="3" />
<plugin id="com.sap.sailing.polars" autoStart="true" startLevel="4" />
<plugin id="com.sap.sailing.polars.datamining" autoStart="true" startLevel="4" />
<plugin id="com.sap.sailing.resultimport" autoStart="true" startLevel="3" />
<plugin id="com.sap.sailing.sailwave.resultimport" autoStart="true" startLevel="3" />
<plugin id="com.sap.sailing.server" autoStart="true" startLevel="4" />
@@ -49,9 +49,10 @@ Require-Bundle: com.sap.sailing.domain,
org.apache.shiro.core;bundle-version="1.2.2",
com.sap.sse.gwt.theme,
com.sap.sailing.news,
com.sap.sailing.polars.datamining.shared;bundle-version="1.0.0",
com.sap.sailing.polars.datamining.shared,
com.sap.sailing.polars.datamining,
com.sap.sse.datamining.annotations;bundle-version="1.0.0"
com.sap.sse.datamining.annotations,
com.sap.sse.shared.android
Bundle-Activator: com.sap.sailing.gwt.ui.server.Activator
Bundle-ActivationPolicy: lazy
Import-Package: javax.servlet;version="3.1.0",
@@ -17,7 +17,7 @@
<listEntry value="com.sap.sailing.gwt.AutoPlay"/>
<listEntry value="com.sap.sailing.gwt.ui.AdminConsole"/>
<listEntry value="com.sap.sailing.gwt.home.Home"/>
<listEntry value="com.sap.sailing.gwt.ui.VideoPopup"/>
<listEntry value="com.sap.sailing.gwt.AutoPlay"/>
</listAttribute>
<booleanAttribute key="com.google.gwt.eclipse.core.SUPERDEVMODE_ENABLED" value="true"/>
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/Home.html"/>
@@ -73,7 +73,7 @@
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-superDevMode -incremental -workDir &quot;${project_loc:com.sap.sailing.gwt.ui}/.tmp/gwt-work&quot; -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort 9876 -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/EmbeddedMapAndWindChart com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-superDevMode -incremental -workDir &quot;${project_loc:com.sap.sailing.gwt.ui}/.tmp/gwt-work&quot; -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort 9876 -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/EmbeddedMapAndWindChart com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup -startupUrl /gwt/AutoPlay.html com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms1024m -Xmx3072m"/>
</launchConfiguration>
@@ -16,7 +16,7 @@
<listEntry value="com.sap.sailing.gwt.AutoPlay"/>
<listEntry value="com.sap.sailing.gwt.ui.AdminConsole"/>
<listEntry value="com.sap.sailing.gwt.home.Home"/>
<listEntry value="com.sap.sailing.gwt.ui.VideoPopup"/>
<listEntry value="com.sap.sailing.gwt.AutoPlay"/>
</listAttribute>
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/Home.html"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
@@ -70,7 +70,7 @@
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -incremental -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -incremental -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup -startupUrl /gwt/AutoPlay.html com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/>
</launchConfiguration>
-13
View File
@@ -11,19 +11,6 @@
<artifactId>com.sap.sailing.gwt.ui</artifactId>
<packaging>eclipse-plugin</packaging>
<repositories>
<repository>
<id>sonatype</id>
<url>http://oss.sonatype.org/content/repositories/snapshots</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
<dependencies>
<!-- The following dependency needs re-declaration with the desired version
because gwt-maps-api declares it with no version specifier which may be resolved
@@ -22,8 +22,8 @@ import com.sap.sailing.gwt.home.server.EventActionUtil;
import com.sap.sailing.gwt.home.server.LeaderboardContext;
import com.sap.sailing.gwt.home.server.EventActionUtil.LeaderboardCallback;
import com.sap.sailing.gwt.server.HomeServiceUtil;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.MediaTagConstants;
import com.sap.sse.shared.media.ImageDescriptor;
public class GetEventViewAction implements SailingAction<EventViewDTO>, IsClientCacheable {
private static final Logger logger = Logger.getLogger(GetEventViewAction.class.getName());
@@ -20,7 +20,7 @@ import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsDurationImpl;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.media.MediaTagConstants;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class GetEventOverviewStageAction implements SailingAction<ResultWithTTL<EventOverviewStageDTO>>, IsClientCacheable {
@@ -2,6 +2,7 @@ package com.sap.sailing.gwt.home.communication.event.news;
import java.util.Date;
import com.google.gwt.core.shared.GwtIncompatible;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.gwt.ui.client.StringMessages;
@@ -18,6 +19,7 @@ public class RaceCompetitorNewsEntryDTO extends AbstractRaceNewsEntryDTO {
private RaceCompetitorNewsEntryDTO() {
}
@GwtIncompatible
public RaceCompetitorNewsEntryDTO(String leaderboardName, String leaderboardGroupName,
RegattaAndRaceIdentifier regattaAndRaceIdentifier, String raceTitle, String boatClass, Date timestamp,
String competitorName, Type type) {
@@ -16,8 +16,8 @@ import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
import com.sap.sailing.gwt.home.communication.event.EventMetadataDTO;
import com.sap.sailing.gwt.home.communication.fakeseries.EventSeriesViewDTO.EventSeriesState;
import com.sap.sailing.gwt.server.HomeServiceUtil;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.MediaTagConstants;
import com.sap.sse.shared.media.ImageDescriptor;
public class GetEventSeriesViewAction implements SailingAction<EventSeriesViewDTO>, IsClientCacheable {
@@ -11,9 +11,9 @@ import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
import com.sap.sailing.gwt.home.communication.event.EventReferenceDTO;
import com.sap.sailing.gwt.server.HomeServiceUtil;
import com.sap.sailing.gwt.ui.shared.media.MediaConstants;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class GetMediaForEventAction implements SailingAction<MediaDTO>, IsClientCacheable {
@@ -22,9 +22,9 @@ import com.sap.sailing.gwt.server.RecentEventsCalculator;
import com.sap.sailing.gwt.ui.shared.media.MediaConstants;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class GetStartViewAction implements SailingAction<StartViewDTO>, IsClientCacheable {
private static final int MAX_RECENT_EVENTS = 3;
@@ -44,12 +44,12 @@ import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.MediaDescriptor;
import com.sap.sse.common.media.MediaTagConstants;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.gwt.client.media.ImageDTO;
import com.sap.sse.gwt.client.media.VideoDTO;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.MediaDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public final class HomeServiceUtil {
public interface EventVisitor {
@@ -126,6 +126,7 @@ public class RaceLogCourseManagementWidget extends CourseManagementWidget {
@Override
public void onSuccess(RaceCourseDTO result) {
updateWaypointsAndControlPoints(result);
marks.refresh(result.getMarks());
}
@Override
@@ -133,18 +134,5 @@ public class RaceLogCourseManagementWidget extends CourseManagementWidget {
errorReporter.reportError("Could not load course: " + caught.getMessage());
}
});
sailingService.getMarksInRaceLog(leaderboardName, raceColumnName, fleetName,
new AsyncCallback<Iterable<MarkDTO>>() {
@Override
public void onSuccess(Iterable<MarkDTO> result) {
marks.refresh(result);
}
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Could not load marks: " + caught.getMessage());
}
});
}
}
@@ -10,7 +10,7 @@ import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.home.communication.media.SailingImageDTO;
import com.sap.sse.gwt.client.media.ImageDTO;
public class GalleryImageHolder extends Widget implements HasClickHandlers {
@@ -22,7 +22,7 @@ public class GalleryImageHolder extends Widget implements HasClickHandlers {
@UiField
DivElement imageHolderUi;
public GalleryImageHolder(SailingImageDTO video) {
public GalleryImageHolder(ImageDTO video) {
setElement(uiBinder.createAndBindUi(this));
imageHolderUi.getStyle().setBackgroundImage("url(\"" + video.getSourceRef() + "\")");
@@ -11,9 +11,9 @@ import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.home.communication.media.SailingVideoDTO;
import com.sap.sailing.gwt.ui.common.client.YoutubeApi;
import com.sap.sse.common.media.MediaSubType;
import com.sap.sse.gwt.client.media.VideoDTO;
public class VideoThumbnail extends Widget implements HasClickHandlers {
@@ -28,7 +28,7 @@ public class VideoThumbnail extends Widget implements HasClickHandlers {
@UiField
ImageElement thumbnailUi;
public VideoThumbnail(SailingVideoDTO video) {
public VideoThumbnail(VideoDTO video) {
setElement(uiBinder.createAndBindUi(this));
getElement().addClassName("videoThumbnail");
captionUi.setInnerText(video.getTitle());
@@ -445,12 +445,7 @@ import com.sap.sse.common.Util.Triple;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.impl.TimeRangeImpl;
import com.sap.sse.common.mail.MailException;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.ImageDescriptorImpl;
import com.sap.sse.common.media.MediaUtils;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.common.media.VideoDescriptorImpl;
import com.sap.sse.filestorage.FileStorageService;
import com.sap.sse.filestorage.InvalidPropertiesException;
import com.sap.sse.gwt.client.ServerInfoDTO;
@@ -466,6 +461,11 @@ import com.sap.sse.replication.ReplicationMasterDescriptor;
import com.sap.sse.replication.ReplicationService;
import com.sap.sse.replication.impl.ReplicaDescriptor;
import com.sap.sse.security.SessionUtils;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.MediaUtils;
import com.sap.sse.shared.media.VideoDescriptor;
import com.sap.sse.shared.media.impl.ImageDescriptorImpl;
import com.sap.sse.shared.media.impl.VideoDescriptorImpl;
import com.sap.sse.util.ServiceTrackerFactory;
import com.sapsailing.xrr.structureimport.eventimport.RegattaJSON;
@@ -1948,7 +1948,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
result.totalLegsCount = trackedRace.getRace().getCourse().getLegs().size();
result.currentLegNumber = trackedRace.getLastLegStarted(dateAsTimePoint);
result.marks = new HashSet<MarkDTO>();
result.course = convertToRaceCourseDTO(trackedRace.getRace().getCourse(), trackedRace, dateAsTimePoint);
result.course = convertToRaceCourseDTO(trackedRace.getRace().getCourse(), new TrackedRaceMarkPositionFinder(trackedRace), dateAsTimePoint);
// now make sure we don't duplicate the MarkDTO objects but instead use the ones from the RaceCourseDTO
// object and amend them with the Position
result.waypointPositions = new ArrayList<>();
@@ -2022,7 +2022,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
for (Waypoint waypoint : course.getWaypoints()) {
ControlPointDTO controlPointDTO = controlPointCache.get(waypoint.getControlPoint().getId());
if (controlPointDTO == null) {
controlPointDTO = convertToControlPointDTO(waypoint.getControlPoint(), trackedRace, dateAsTimePoint);
controlPointDTO = convertToControlPointDTO(waypoint.getControlPoint(), new TrackedRaceMarkPositionFinder(trackedRace), dateAsTimePoint);
controlPointCache.put(waypoint.getControlPoint().getId(), controlPointDTO);
}
WaypointDTO waypointDTO = new WaypointDTO(waypoint.getName(), controlPointDTO,
@@ -2033,20 +2033,44 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
return new RaceCourseDTO(waypointDTOs, allMarks);
}
private ControlPointDTO convertToControlPointDTO(ControlPoint controlPoint, TrackedRace trackedRace, TimePoint timePoint) {
class TrackedRaceMarkPositionFinder implements MarkPositionFinder{
private TrackedRace trackedRace;
public TrackedRaceMarkPositionFinder(TrackedRace trackedRace) {
this.trackedRace = trackedRace;
}
@Override
public Position find(Mark mark, TimePoint at) {
final TimePoint timePointToUse = trackedRace == null ? null :
at == null ? MillisecondsTimePoint.now().minus(trackedRace.getDelayToLiveInMillis()) : at;
final Position result;
if (timePointToUse == null) {
result = null;
} else {
result = trackedRace.getOrCreateTrack(mark).getEstimatedPosition(timePointToUse, /* extrapolate */ false);
}
return result;
}
}
private interface MarkPositionFinder {
Position find(Mark mark, TimePoint at);
}
private ControlPointDTO convertToControlPointDTO(ControlPoint controlPoint, MarkPositionFinder positionFinder, TimePoint timePoint) {
ControlPointDTO result;
final TimePoint timePointToUse = trackedRace == null ? null :
timePoint == null ? MillisecondsTimePoint.now().minus(trackedRace.getDelayToLiveInMillis()) : timePoint;
if (controlPoint instanceof ControlPointWithTwoMarks) {
final Mark left = ((ControlPointWithTwoMarks) controlPoint).getLeft();
final Position leftPos = timePointToUse == null ? null : trackedRace.getOrCreateTrack(left).getEstimatedPosition(timePointToUse, /* extrapolate */ false);
final Position leftPos = positionFinder.find(left, timePoint);
final Mark right = ((ControlPointWithTwoMarks) controlPoint).getRight();
final Position rightPos = timePointToUse == null ? null : trackedRace.getOrCreateTrack(right).getEstimatedPosition(timePointToUse, /* extrapolate */ false);
final Position rightPos = positionFinder.find(right, timePoint);
result = new GateDTO(controlPoint.getId().toString(), controlPoint.getName(), convertToMarkDTO(left, leftPos), convertToMarkDTO(right, rightPos));
} else {
final Position posOfFirst = timePointToUse == null ? null : trackedRace.getOrCreateTrack(controlPoint.getMarks().iterator().next()).
getEstimatedPosition(timePointToUse, /* extrapolate */ false);
result = new MarkDTO(controlPoint.getId().toString(), controlPoint.getName(), posOfFirst == null ? -1 : posOfFirst.getLatDeg(), posOfFirst == null ? -1 : posOfFirst.getLngDeg());
Mark mark = controlPoint.getMarks().iterator().next();
final Position position = positionFinder.find(mark, timePoint);
result = convertToMarkDTO(mark, position);
}
return result;
}
@@ -5158,10 +5182,10 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
* the mark positions and attach to the {@link MarkDTO}s. If <code>null<c/code>, the current time point
* will be used as default.
*/
private WaypointDTO convertToWaypointDTO(Waypoint waypoint, Map<Serializable, ControlPointDTO> controlPointCache, TrackedRace trackedRace, TimePoint timePoint) {
private WaypointDTO convertToWaypointDTO(Waypoint waypoint, Map<Serializable, ControlPointDTO> controlPointCache, MarkPositionFinder positionFinder, TimePoint timePoint) {
ControlPointDTO cp = controlPointCache.get(waypoint.getControlPoint().getId());
if (cp == null) {
cp = convertToControlPointDTO(waypoint.getControlPoint(), trackedRace, timePoint);
cp = convertToControlPointDTO(waypoint.getControlPoint(), positionFinder, timePoint);
controlPointCache.put(waypoint.getControlPoint().getId(), cp);
}
return new WaypointDTO(waypoint.getName(), cp, waypoint.getPassingInstructions());
@@ -5177,13 +5201,13 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
* the mark positions and attach to the {@link MarkDTO}s. If <code>null<c/code>, the current time point
* will be used as default.
*/
private RaceCourseDTO convertToRaceCourseDTO(CourseBase course, TrackedRace trackedRace, TimePoint timePoint) {
private RaceCourseDTO convertToRaceCourseDTO(CourseBase course, MarkPositionFinder positionFinder, TimePoint timePoint) {
final RaceCourseDTO result;
if (course != null) {
List<WaypointDTO> waypointDTOs = new ArrayList<WaypointDTO>();
Map<Serializable, ControlPointDTO> controlPointCache = new HashMap<>();
for (Waypoint waypoint : course.getWaypoints()) {
waypointDTOs.add(convertToWaypointDTO(waypoint, controlPointCache, trackedRace, timePoint));
waypointDTOs.add(convertToWaypointDTO(waypoint, controlPointCache, positionFinder, timePoint));
}
result = new RaceCourseDTO(waypointDTOs);
} else {
@@ -5193,13 +5217,18 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
}
@Override
public RaceCourseDTO getLastCourseDefinitionInRaceLog(String leaderboardName, String raceColumnName, String fleetName) {
RaceLog raceLog = getRaceLog(leaderboardName, raceColumnName, fleetName);
public RaceCourseDTO getLastCourseDefinitionInRaceLog(final String leaderboardName, String raceColumnName, String fleetName) {
final RaceLog raceLog = getRaceLog(leaderboardName, raceColumnName, fleetName);
CourseBase lastPublishedCourse = new LastPublishedCourseDesignFinder(raceLog).analyze();
if (lastPublishedCourse == null) {
lastPublishedCourse = new CourseDataImpl("");
}
return convertToRaceCourseDTO(lastPublishedCourse, /* trackedRace */ null, /* timePoint */ null);
return convertToRaceCourseDTO(lastPublishedCourse, new MarkPositionFinder() {
@Override
public Position find(Mark mark, TimePoint at) {
return getService().getMarkPosition(mark, (LeaderboardThatHasRegattaLike) getService().getLeaderboardByName(leaderboardName), at, raceLog);
}
}, /* timePoint */ MillisecondsTimePoint.now());
}
@Override
@@ -27,7 +27,8 @@ Require-Bundle: com.sap.sailing.domain,
com.sap.sse.operationaltransformation,
com.sap.sse.replication,
com.sap.sse,
com.sap.sse.filestorage
com.sap.sse.filestorage,
com.sap.sse.shared.android
Import-Package: com.sap.sailing.domain.common,
com.sap.sailing.domain.common.impl,
com.sap.sailing.domain.common.racelog,
@@ -38,7 +38,7 @@ public class GPSFixWithPolarContext implements HasGPSFixPolarContext {
@Override
public ClusterDTO getWindSpeedRange() {
return new ClusterDTO(windSpeedRangeGroup.getClusterFor(wind.getObject()).toString());
return new ClusterDTO(wind == null || wind.getObject() == null ? "null" : windSpeedRangeGroup.getClusterFor(wind.getObject()).toString());
}
@Override
@@ -8,7 +8,8 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Require-Bundle: com.sap.sailing.domain.common,
com.sap.sailing.domain.shared.android,
org.json.simple;bundle-version="1.1.0",
com.sap.sse.common
com.sap.sse.common,
com.sap.sse.shared.android
Export-Package: com.sap.sailing.server.gateway.deserialization,
com.sap.sailing.server.gateway.deserialization.coursedata.impl,
com.sap.sailing.server.gateway.deserialization.impl,
@@ -1,25 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sailing.server.gateway.serialization.shared.android</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sailing.server.gateway.serialization.shared.android</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -23,12 +23,12 @@ import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.ImageDescriptorImpl;
import com.sap.sse.common.media.ImageSize;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.common.media.VideoDescriptorImpl;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
import com.sap.sse.shared.media.impl.ImageDescriptorImpl;
import com.sap.sse.shared.media.impl.VideoDescriptorImpl;
public class EventBaseJsonDeserializer implements JsonDeserializer<EventBase> {
private final JsonDeserializer<Venue> venueDeserializer;
@@ -9,8 +9,8 @@ import com.sap.sailing.domain.base.EventBase;
import com.sap.sailing.domain.base.LeaderboardGroupBase;
import com.sap.sailing.domain.base.Venue;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class EventBaseJsonSerializer implements JsonSerializer<EventBase> {
public static final String FIELD_ID = "id";
@@ -14,4 +14,5 @@ Require-Bundle: com.sap.sailing.domain;bundle-version="1.0.0",
org.json.simple,
org.mockito.mockito-core;bundle-version="1.9.5",
org.objenesis;bundle-version="1.3.0",
com.sap.sse.common
com.sap.sse.common,
com.sap.sse.shared.android
@@ -32,8 +32,8 @@ import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJso
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class EventDataJsonSerializerTest {
protected final UUID expectedId = UUID.randomUUID();
@@ -36,11 +36,11 @@ import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.ImageDescriptorImpl;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.common.media.VideoDescriptorImpl;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
import com.sap.sse.shared.media.impl.ImageDescriptorImpl;
import com.sap.sse.shared.media.impl.VideoDescriptorImpl;
public class EventDataJsonSerializerWithImagesAndVideosTest {
private final UUID expectedId = UUID.randomUUID();
@@ -32,8 +32,8 @@ import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJso
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class EventDataJsonSerializerWithNullValuesTest {
protected final UUID expectedId = UUID.randomUUID();
@@ -31,8 +31,8 @@ import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer
import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class EventWithNullStartAndEndDataJsonSerializerTest {
@@ -129,11 +129,11 @@ import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsDurationImpl;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.mongodb.MongoDBConfiguration;
import com.sap.sse.mongodb.MongoDBService;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class MasterDataImportTest {
@@ -72,10 +72,10 @@ import com.sap.sse.common.Color;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.common.search.KeywordQuery;
import com.sap.sse.common.search.Result;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class SearchServiceTest {
private RacingEventService server;
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -1,70 +1,70 @@
package com.sap.sailing.server.operationaltransformation;
import java.net.URL;
import java.util.UUID;
import com.sap.sailing.domain.base.Event;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.VideoDescriptor;
/**
* Creates an {@link Event} in the server, with a new venue and an empty course area list.
* See the {@link AddCourseAreas} operation for adding course areas to the event's venue.
*
* @author Axel Uhl (d043530)
*
*/
public class CreateEvent extends AbstractEventOperation<Event> {
private static final long serialVersionUID = 308389324918359960L;
private final String venue;
private final TimePoint startDate;
private final TimePoint endDate;
private final boolean isPublic;
private final String eventName;
private final String eventDescription;
private final Iterable<ImageDescriptor> images;
private final Iterable<VideoDescriptor> videos;
private final URL officialWebsiteURL;
private final URL sailorsInfoWebsiteURL;
public CreateEvent(String eventName, String eventDescription, TimePoint startDate, TimePoint endDate, String venue,
boolean isPublic, UUID id, URL officialWebsiteURL, URL sailorsInfoWebsiteURL, Iterable<ImageDescriptor> images, Iterable<VideoDescriptor> videos) {
super(id);
this.eventName = eventName;
this.eventDescription = eventDescription;
this.startDate = startDate;
this.endDate = endDate;
this.venue = venue;
this.isPublic = isPublic;
this.officialWebsiteURL = officialWebsiteURL;
this.sailorsInfoWebsiteURL = sailorsInfoWebsiteURL;
this.images = images;
this.videos = videos;
}
@Override
public RacingEventServiceOperation<?> transformClientOp(RacingEventServiceOperation<?> serverOp) {
// TODO Auto-generated method stub
return null;
}
@Override
public RacingEventServiceOperation<?> transformServerOp(RacingEventServiceOperation<?> clientOp) {
// TODO Auto-generated method stub
return null;
}
protected String getEventName() {
return eventName;
}
@Override
public Event internalApplyTo(RacingEventService toState) {
return toState.createEventWithoutReplication(getEventName(), eventDescription, startDate, endDate, venue, isPublic,
getId(), officialWebsiteURL, sailorsInfoWebsiteURL, images, videos);
}
}
package com.sap.sailing.server.operationaltransformation;
import java.net.URL;
import java.util.UUID;
import com.sap.sailing.domain.base.Event;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
import com.sap.sse.common.TimePoint;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
/**
* Creates an {@link Event} in the server, with a new venue and an empty course area list.
* See the {@link AddCourseAreas} operation for adding course areas to the event's venue.
*
* @author Axel Uhl (d043530)
*
*/
public class CreateEvent extends AbstractEventOperation<Event> {
private static final long serialVersionUID = 308389324918359960L;
private final String venue;
private final TimePoint startDate;
private final TimePoint endDate;
private final boolean isPublic;
private final String eventName;
private final String eventDescription;
private final Iterable<ImageDescriptor> images;
private final Iterable<VideoDescriptor> videos;
private final URL officialWebsiteURL;
private final URL sailorsInfoWebsiteURL;
public CreateEvent(String eventName, String eventDescription, TimePoint startDate, TimePoint endDate, String venue,
boolean isPublic, UUID id, URL officialWebsiteURL, URL sailorsInfoWebsiteURL, Iterable<ImageDescriptor> images, Iterable<VideoDescriptor> videos) {
super(id);
this.eventName = eventName;
this.eventDescription = eventDescription;
this.startDate = startDate;
this.endDate = endDate;
this.venue = venue;
this.isPublic = isPublic;
this.officialWebsiteURL = officialWebsiteURL;
this.sailorsInfoWebsiteURL = sailorsInfoWebsiteURL;
this.images = images;
this.videos = videos;
}
@Override
public RacingEventServiceOperation<?> transformClientOp(RacingEventServiceOperation<?> serverOp) {
// TODO Auto-generated method stub
return null;
}
@Override
public RacingEventServiceOperation<?> transformServerOp(RacingEventServiceOperation<?> clientOp) {
// TODO Auto-generated method stub
return null;
}
protected String getEventName() {
return eventName;
}
@Override
public Event internalApplyTo(RacingEventService toState) {
return toState.createEventWithoutReplication(getEventName(), eventDescription, startDate, endDate, venue, isPublic,
getId(), officialWebsiteURL, sailorsInfoWebsiteURL, images, videos);
}
}
@@ -1,61 +1,61 @@
package com.sap.sailing.server.operationaltransformation;
import java.net.URL;
import java.util.UUID;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.VideoDescriptor;
public class UpdateEvent extends AbstractEventOperation<Void> {
private static final long serialVersionUID = -8271559266421161532L;
private final String venueName;
private final TimePoint startDate;
private final TimePoint endDate;
private final boolean isPublic;
private final Iterable<UUID> leaderboardGroupIds;
private final String eventName;
private final String eventDescription;
private final URL officialWebsiteURL;
private final URL sailorsInfoWebsiteURL;
private final Iterable<ImageDescriptor> images;
private final Iterable<VideoDescriptor> videos;
public UpdateEvent(UUID id, String eventName, String eventDescription, TimePoint startDate, TimePoint endDate,
String venueName, boolean isPublic, Iterable<UUID> leaderboardGroupIds, URL officialWebsiteURL, URL sailorsInfoWebsiteURL,
Iterable<ImageDescriptor> images, Iterable<VideoDescriptor> videos) {
super(id);
this.eventName = eventName;
this.eventDescription = eventDescription;
this.startDate = startDate;
this.endDate = endDate;
this.venueName = venueName;
this.isPublic = isPublic;
this.leaderboardGroupIds = leaderboardGroupIds;
this.officialWebsiteURL = officialWebsiteURL;
this.sailorsInfoWebsiteURL = sailorsInfoWebsiteURL;
this.images = images;
this.videos = videos;
}
@Override
public RacingEventServiceOperation<?> transformClientOp(RacingEventServiceOperation<?> serverOp) {
// TODO Auto-generated method stub
return null;
}
@Override
public RacingEventServiceOperation<?> transformServerOp(RacingEventServiceOperation<?> clientOp) {
// TODO Auto-generated method stub
return null;
}
@Override
public Void internalApplyTo(RacingEventService toState) {
toState.updateEvent(getId(), eventName, eventDescription, startDate, endDate, venueName, isPublic,
leaderboardGroupIds, officialWebsiteURL, sailorsInfoWebsiteURL, images, videos);
return null;
}
}
package com.sap.sailing.server.operationaltransformation;
import java.net.URL;
import java.util.UUID;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
import com.sap.sse.common.TimePoint;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class UpdateEvent extends AbstractEventOperation<Void> {
private static final long serialVersionUID = -8271559266421161532L;
private final String venueName;
private final TimePoint startDate;
private final TimePoint endDate;
private final boolean isPublic;
private final Iterable<UUID> leaderboardGroupIds;
private final String eventName;
private final String eventDescription;
private final URL officialWebsiteURL;
private final URL sailorsInfoWebsiteURL;
private final Iterable<ImageDescriptor> images;
private final Iterable<VideoDescriptor> videos;
public UpdateEvent(UUID id, String eventName, String eventDescription, TimePoint startDate, TimePoint endDate,
String venueName, boolean isPublic, Iterable<UUID> leaderboardGroupIds, URL officialWebsiteURL, URL sailorsInfoWebsiteURL,
Iterable<ImageDescriptor> images, Iterable<VideoDescriptor> videos) {
super(id);
this.eventName = eventName;
this.eventDescription = eventDescription;
this.startDate = startDate;
this.endDate = endDate;
this.venueName = venueName;
this.isPublic = isPublic;
this.leaderboardGroupIds = leaderboardGroupIds;
this.officialWebsiteURL = officialWebsiteURL;
this.sailorsInfoWebsiteURL = sailorsInfoWebsiteURL;
this.images = images;
this.videos = videos;
}
@Override
public RacingEventServiceOperation<?> transformClientOp(RacingEventServiceOperation<?> serverOp) {
// TODO Auto-generated method stub
return null;
}
@Override
public RacingEventServiceOperation<?> transformServerOp(RacingEventServiceOperation<?> clientOp) {
// TODO Auto-generated method stub
return null;
}
@Override
public Void internalApplyTo(RacingEventService toState) {
toState.updateEvent(getId(), eventName, eventDescription, startDate, endDate, venueName, isPublic,
leaderboardGroupIds, officialWebsiteURL, sailorsInfoWebsiteURL, images, videos);
return null;
}
}
+25 -25
View File
@@ -11,30 +11,30 @@
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
+28 -28
View File
@@ -1,31 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sse.datamining.annotations</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sse.datamining.annotations</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
+32 -32
View File
@@ -1,32 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sse.security.common</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sse.security.common</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -7,4 +7,6 @@ Bundle-Vendor: SAP
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Require-Bundle: com.sap.sse.common
Export-Package: com.sap.sse.concurrent,
com.sap.sse.shared.media,
com.sap.sse.shared.media.impl,
com.sap.sse.util.impl
@@ -1,4 +1,4 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media;
import com.sap.sse.common.Util.Pair;
@@ -1,10 +1,11 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media;
import java.io.Serializable;
import java.net.URL;
import java.util.Locale;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.media.MimeType;
/**
* A common media interface for all kinds of media like images or videos.
@@ -1,4 +1,4 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media;
import java.io.IOException;
import java.net.URL;
@@ -18,6 +18,7 @@ import javax.imageio.stream.ImageInputStream;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.media.MimeType;
public class MediaUtils {
private static final Logger logger = Logger.getLogger(MediaUtils.class.getName());
@@ -1,4 +1,4 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media;
import java.net.URL;
@@ -1,4 +1,5 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media;
public interface WithImages {
/**
@@ -1,4 +1,4 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media;
import java.util.List;
@@ -1,4 +1,5 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media;
public interface WithVideos {
@@ -1,4 +1,4 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media.impl;
import java.io.Serializable;
import java.net.URL;
@@ -8,6 +8,8 @@ import java.util.Set;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.shared.media.MediaDescriptor;
/**
* Common media data for media items
@@ -1,9 +1,11 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media.impl;
import java.net.URL;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.shared.media.ImageDescriptor;
public class ImageDescriptorImpl extends AbstractMediaDescriptor implements ImageDescriptor {
@@ -1,8 +1,10 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media.impl;
import java.net.URL;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.shared.media.VideoDescriptor;
public class VideoDescriptorImpl extends AbstractMediaDescriptor implements VideoDescriptor {
private static final long serialVersionUID = 2651747912466590862L;
@@ -3,6 +3,8 @@ package com.sap.sse;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* A class providing static information about the running server.
@@ -10,14 +12,16 @@ import java.io.FileReader;
*
*/
public class ServerInfo {
private static final Logger logger = Logger.getLogger(ServerInfo.class.getName());
public static String getBuildVersion() {
String version = "Unknown or Development (" + ServerStartupConstants.SERVER_NAME + ")";
File versionfile = new File(ServerStartupConstants.JETTY_HOME + File.separator + "version.txt");
if (versionfile.exists()) {
try {
version = new BufferedReader(new FileReader(versionfile)).readLine();
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(versionfile))) {
version = bufferedReader.readLine();
} catch (Exception ex) {
/* ignore */
logger.log(Level.WARNING, "Error trying to obtain version info", ex);
}
}
return version;
+40 -40
View File
@@ -1,40 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>org.json.simple</artifactId>
<version>1.1.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>org.json.simple</artifactId>
<version>1.1.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
+11 -11
View File
@@ -134,8 +134,8 @@
<module>com.sap.sailing.autoload</module>
<module>com.sap.sailing.feature.p2build</module>
<module>com.sap.sailing.polars</module>
<module>com.sap.sailing.polars.datamining</module>
<module>com.sap.sailing.polars.datamining.shared</module>
<module>com.sap.sailing.polars.datamining</module>
<module>com.sap.sailing.polars.datamining.shared</module>
<module>com.sap.sailing.polars.test</module>
<!--
com.sap.sailing.targetplatform.base
@@ -264,15 +264,15 @@
<version>${tycho-version}</version>
<configuration>
<resolver>p2</resolver>
<dependency-resolution>
<extraRequirements>
<requirement>
<type>eclipse-plugin</type>
<id>com.google.gwt.dev</id>
<versionRange>0.0.0</versionRange>
</requirement>
</extraRequirements>
</dependency-resolution>
<dependency-resolution>
<extraRequirements>
<requirement>
<type>eclipse-plugin</type>
<id>com.google.gwt.dev</id>
<versionRange>0.0.0</versionRange>
</requirement>
</extraRequirements>
</dependency-resolution>
<target>
<artifact>
<groupId>${project.groupId}</groupId>
+18 -18
View File
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.sap.sailing</groupId>
<artifactId>mobile</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sailing.android.shared</artifactId>
<packaging>apklib</packaging>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.sap.sailing</groupId>
<artifactId>mobile</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sailing.android.shared</artifactId>
<packaging>apklib</packaging>
<dependencies>
<dependencies>
<dependency>
<groupId>com.sap.sailing</groupId>
<artifactId>org.json.simple</artifactId>
@@ -86,12 +86,12 @@
<groupId>android</groupId>
<artifactId>android</artifactId>
</dependency>
</dependencies>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<finalName>${project.artifactId}</finalName>
<plugins>
<build>
<sourceDirectory>src</sourceDirectory>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>android-maven-plugin</artifactId>
@@ -101,6 +101,6 @@
</sdk>
</configuration>
</plugin>
</plugins>
</build>
</plugins>
</build>
</project>
@@ -120,7 +120,7 @@
</executions>
</plugin>
<!-- plugins for generating version file and copying .apk -->
<!-- plugins for generating version file and copying .apk -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
+98 -98
View File
@@ -16,13 +16,13 @@
<!--
<module>com.sap.sailing.racecommittee.app</module>
<module>com.sap.sailing.android.shared</module>
<module>com.sap.sailing.adnroid.buoy.positioning.app</module>
<module>com.sap.sailing.adnroid.buoy.positioning.app</module>
<module>com.sap.sailing.android.tracking.app</module>
-->
</modules>
<properties>
<!-- used to copy android apps to the static web dir (auto-update functionality) -->
<!-- used to copy android apps to the static web dir (auto-update functionality) -->
<!-- relative dir as seen from the child modules -->
<additional-deployment-dir>../../java/com.sap.sailing.www/apps</additional-deployment-dir>
<!-- redefine in child poms -->
@@ -32,21 +32,21 @@
<dependencyManagement>
<dependencies>
<!-- needed on remote repository -->
<dependency>
<groupId>android</groupId>
<artifactId>android</artifactId>
<version>4.4.2_r4</version>
<scope>provided</scope>
</dependency>
<!-- needed on remote repository -->
<dependency>
<groupId>android</groupId>
<artifactId>android</artifactId>
<version>4.4.2_r4</version>
<scope>provided</scope>
</dependency>
<!-- needed on remote repository -->
<dependency>
<groupId>android.support</groupId>
<artifactId>compatibility-v4</artifactId>
<version>19</version>
</dependency>
</dependencies>
<!-- needed on remote repository -->
<dependency>
<groupId>android.support</groupId>
<artifactId>compatibility-v4</artifactId>
<version>19</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
@@ -55,90 +55,90 @@
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>android-maven-plugin</artifactId>
<version>3.9.0-rc.1</version>
<configuration>
<sdk>
<platform>19</platform>
</sdk>
</configuration>
<version>3.9.0-rc.1</version>
<configuration>
<sdk>
<platform>19</platform>
</sdk>
</configuration>
<extensions>true</extensions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>copy-installed</id>
<phase>install</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<type>${project.packaging}</type>
</artifactItem>
</artifactItems>
<outputDirectory>${additional-deployment-dir}</outputDirectory>
<stripVersion>true</stripVersion>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>generate-version</id>
<phase>install</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<property name="target.dir" value="${additional-deployment-dir}" />
<property name="target.name" value="${additional-deployment-version-file}" />
<echo file="${target.dir}/${target.name}" message="${project.build.finalName}.apk=${app-version}" />
<echo message="Version file generated in ${target.dir}/${target.name}." />
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.5</version>
<configuration>
<filesets>
<fileset>
<directory>${additional-deployment-dir}</directory>
<includes>
<include>${project.build.finalName}.apk</include>
<include>${additional-deployment-version-file}</include>
</includes>
<excludes>
<exclude>*.gitignore</exclude>
</excludes>
<followSymlinks>false</followSymlinks>
</fileset>
</filesets>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>copy-installed</id>
<phase>install</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<type>${project.packaging}</type>
</artifactItem>
</artifactItems>
<outputDirectory>${additional-deployment-dir}</outputDirectory>
<stripVersion>true</stripVersion>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>generate-version</id>
<phase>install</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<property name="target.dir" value="${additional-deployment-dir}" />
<property name="target.name" value="${additional-deployment-version-file}" />
<echo file="${target.dir}/${target.name}" message="${project.build.finalName}.apk=${app-version}" />
<echo message="Version file generated in ${target.dir}/${target.name}." />
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.5</version>
<configuration>
<filesets>
<fileset>
<directory>${additional-deployment-dir}</directory>
<includes>
<include>${project.build.finalName}.apk</include>
<include>${additional-deployment-version-file}</include>
</includes>
<excludes>
<exclude>*.gitignore</exclude>
</excludes>
<followSymlinks>false</followSymlinks>
</fileset>
</filesets>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
+58 -58
View File
@@ -1,68 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sap.sailing</groupId>
<artifactId>workspace</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<groupId>com.sap.sailing</groupId>
<artifactId>workspace</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>java</module>
</modules>
<modules>
<module>java</module>
</modules>
<profiles>
<profile>
<!-- deactivate with parameter '-P !with-mobile'-->
<id>with-mobile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>mobile</module>
</modules>
</profile>
<profile>
<!-- activate with parameter '-P with-ios'-->
<id>with-ios</id>
<modules>
<module>ios</module>
</modules>
</profile>
</profiles>
<profiles>
<profile>
<!-- deactivate with parameter '-P !with-mobile'-->
<id>with-mobile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>mobile</module>
</modules>
</profile>
<profile>
<!-- activate with parameter '-P with-ios'-->
<id>with-ios</id>
<modules>
<module>ios</module>
</modules>
</profile>
</profiles>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<repositories>
<repository>
<id>equinox-sdk-3.9</id>
<layout>p2</layout>
<url>http://download.eclipse.org/releases/luna/</url>
</repository>
<!--
<repository>
<id>sap-nexus</id>
<url>http://nexus.wdf.sap.corp:8081/nexus/content/groups/build.snapshots</url>
</repository>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<repositories>
<repository>
<id>equinox-sdk-3.9</id>
<layout>p2</layout>
<url>http://download.eclipse.org/releases/luna/</url>
</repository>
<!--
<repository>
<id>sap-nexus</id>
<url>http://nexus.wdf.sap.corp:8081/nexus/content/groups/build.snapshots</url>
</repository>
-->
<repository>
<id>sailing-server-maven</id>
<url>http://maven.sapsailing.com/maven</url>
</repository>
<repository>
<id>sailing-server-maven</id>
<url>http://maven.sapsailing.com/maven</url>
</repository>
<repository>
<id>central</id>
<url>http://repo1.maven.org/maven2</url>
</repository>
<repository>
<id>central</id>
<url>http://repo1.maven.org/maven2</url>
</repository>
<repository>
<id>uni-luebeck</id>
<url>http://www.itm.uni-luebeck.de/projects/maven/releases</url>
</repository>
</repositories>
<repository>
<id>uni-luebeck</id>
<url>http://www.itm.uni-luebeck.de/projects/maven/releases</url>
</repository>
</repositories>
</project>
+78 -8
View File
@@ -64,33 +64,103 @@ This uses the SetEnvIf module, tries to match an IP address at the start of the
### Amazon EC2 Elastic Load Balancer (ELB) Logs
An Amazon ELB can be configured to write log files to the S3 storage. The general format is [explained here](http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/access-log-collection.html#access-log-entry-format). It contains in particular the client IP where the request originated and can tell timing parameters for request forwarding and processing that otherwise would not be available. It seems a good idea to always capture these logs for archiving purposes. They end up on an S3 bucket, and by default we use `sapsailing-access-logs`.
An Amazon ELB can be configured to write log files to the S3 storage. The general format is [explained here](http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/access-log-collection.html#access-log-entry-format). It contains in particular the client IP where the request originated and can tell timing parameters for request forwarding and processing that otherwise would not be available.
The format for these logs is
<pre>
timestamp elb client:port backend:port request_processing_time backend_processing_time response_processing_time elb_status_code backend_status_code received_bytes sent_bytes "request" "user_agent" ssl_cipher ssl_protocol
</pre>
It seems a good idea to always capture these logs for archiving purposes. They end up on an S3 bucket, and by default we use `sapsailing-access-logs`.
Content can be synced from there to a local directory using the following command:
``s3cmd sync s3://sapsailing-access-logs/elb-access-logs ./elb-access-logs/``
Our central web server at `www.sapsailing.com` does this periodically every day, sync'ing the logs to `/var/log/old/elb-access-logs/`. The corresponding cron job is defined in `/etc/cron.daily/syncEC2ElbLogs` which is a script also found in git in the `configuration/` folder.
### Broken or Partly Missing Logs and How We Recover
During a few events we unfortunately failed to create proper Apache log files according to the above rules for scenarios using a load-balanced setup ("ELB scenario"). In some cases, the Apache log format was missing the referrer URL. This is easy to patch into the files because we collected the logs on a per-server basis and we knew which server ran which event. For example, for Kieler Woche 2015 and Travemünder Woche 2015 we needed to insert `kielerwoche2015.sapsailing.com` and `tw2015.sapsailing.com`, respectively, to match the general log format used for analysis.
The other problem, as described already above, is that of the original client IP address. Before we encountered how to log the original client IP from the `X-Forwarded-For` header field, only the ELB's IP addresses were logged in the Apache logs. While counting the correct number of hits is possible with such logs, they don't reveal the true number of unique visitors. They do, however, contain a valid referrer URL, telling us which leaderboards and races were the most popular.
In case we had an ELB log active, storing the Amazon ELB logs to an S3 bucket, we were able to convert those with a script stored in our git at `configuration/convertELBLogToApacheFormat` into our general Apache log format. This allows us to count the unique visitors for those events, but the ELB logs don't contain the referrer URL, so we patch that to always be the plain event URL, such as `http://kielerwoche2015.sapsailing.com`. Therefore, while these converted logs tell the correct number of unique visitors and the correct number of hits, they don't allow for an analysis of the most popular leaderboards and races.
We hope that these partially-logged events remain the exception and that future events are logged homogeneously according to the rules above. The following naming conventions have been established under `/var/log/old` that shall allow the automatic log analyzers to identify the log file contents by file name patterns:
- `access_log*`: A proper Apache log file with virtual host name as the first field, followed by the original client's IP address and a valid referrer URL as the second-to-last field
- `elb-origin-access_log*`: An Apache log file whose origin IP addresses are usually only the ELB IP addresses, therefore not allowing for unique visitor analysis
- `bundesliga2015_elb_access_log.gz` and `tw2015_elb_access_log.gz`: ELB log files converted to Apache format, appended in order of ascending time stamps, prefixed with the virtual host name as the first field, using the original client IP address which allows for unique visitor analysis, and the virtual host name used again as generic referrer URL
- `original-access_log*`: Apache log file without leading virtual host name field, also usually only with ELB IP addresses instead of an original client IP; not good for any log file analysis without further conversion, but kept for reference purposes
## Automatic Log File Rotation to /var/log/old
- describe how logrotate is used and automatically configured during instance start-up and where the logs go
When an EC2 server is launched from its Amazon Machine Image (AMI), the /etc/init.d/sailing script is executed with the "start" parameter. This script is really just a link to `/home/sailing/code/configuration/sailing` which comes from the git version checked out to the workspace at `/home/sailing/code`. This script patches the file `/etc/logrotate.d/httpd` such that when log rotation happens, the existence of the directory `/var/log/old/$SERVER_NAME/$SERVER_IP` is ensured and the log files are copied there.
This way, logs end up in a per server-name and per server-ip directory.
The general log rotation rules (size, time, compression, etc.) is governed by `/etc/logrotate.conf`.
## Analysis Tools
### goaccess
- mention specific parameters and .goaccess config file required to parse our format
The file `/root/.goaccessrc` on `www.sapsailing.com` looks as follows:
```
color_scheme 1
date_format %d/%b/%Y
time_format %H:%M:%S
log_format %^ %h %^[%d:%^] "%r" %s %b "%R" "%u"
log_file STDIN
```
Still, specific parameters are required for `goaccess` in order to parse our regular Apache logs that have the virtual host name as their first field:
`goaccess --no-global-config -a -f /var/log/httpd/access_log`
The unique visitors that goaccess lists are based on the common definition that counts requests as originating from the same visitor if they happened on the same day with equal user agent and IP address.
### apachetop
The simple command `apachetop` shows the traffic on the Apache httpd server running on the host where the command is invoked, based on the access log file in the usual location `/var/log/httpd/access_log`.
### AWStats
- specific log collection approach configured in /etc/awstats/*.conf script
We use AWStats to analyze our Apache access log files and produce per-month reports at [http://awstats.sapsailing.com](http://awstats.sapsailing.com/awstats/awstats.pl?output=main&config=www.sapsailing.com&framename=index). The username is `awstats`. Ask axel.uhl@sap.com or stefan.lacher@sap.com for the password.
- extension for per-virtual-host hit count
AWStats report production is controlled by three things: a cron job hooked up by `/etc/cron.weekly/awstats` which is basically a one-liner launching the `awstats` command like this:
- configuration of central apache to present results (awstats.sapsailing.com)
`exec /usr/share/awstats/tools/awstats_updateall.pl now -configdir="/etc/awstats" -awstatsprog="/usr/share/awstats/wwwroot/cgi-bin/awstats.pl"`
and a configuration file located at `/etc/awstats/awstats.www.sapsailing.com.conf` which describes in its `LogFile` directive the filename pattern to use for collecting the log files that shall be analyzed. Currently, the file name pattern is this:
`/var/log/httpd/access_log /var/log/old/access_log-???????? /var/log/old/access_log-????????.gz /var/log/old/*/elb-origin-access_log* /var/log/old/*/*/elb-origin-access_log* /var/log/old/*/access_log* /var/log/old/*/*/access_log*`
and all log entries that contain `HealthChecker` are eliminated as they are only a "ping" request sent by the load balancer to check the instance's health status which is not to be counted as a "hit." Note that according to the above explanations of our log file formats and variants this focuses on hit analysis for those events with broken or partial / incomplete log files such as Kieler Woche 2015 and Travemünder Woche 2015. It uses the `elb-origin-*` flavors, tolerating the fact that these don't have the original client's IP address.
The third element of AWStats configuration is how it is published through Apache. This is described in `/etc/httpd/conf.d/awstats.conf` and uses the password definition file `/etc/httpd/conf/passwd.awstats` which can be updated using the `htpasswd` command.
### Custom Scripts
- unique_ips_per_referrer
- convertELBLogToApacheFormat
#### `unique_ips_per_referrer`
The script is located in git at `configuration/unique_ips_per_referrer`. It has two variants next to it: `unique_ips_per_referrer_generate_results_only` and `unique_ips_per_referrer_generate_month_results_only`. The basic idea of this family of scripts is to count the unique visitors for each virtual host name (usually corresponding to an event), in total and by month. Neither the `goaccess` nor the AWStats tool provide us with these numbers. AWStats can only compute the _hits_ per virtual host name, and `goaccess` only lists unique visitors per day, not per virtual host.
The script can be fed with a list of log files in our common Apache format, with virtual host name in first, original client IP in second, time stamp in third and user agent in last column. For all new files (files already analyzed are recorded in `/var/log/old/cache/unique-ips-per-referrer/visited) the script then reduces each line to its timestamp, original client IP and user agent fields, constituting the key for identifying a unique visitor. Each log entry that has been analyzed and reduced this way is then appended to a file under `/var/log/old/cache/unique-ips-per-referrer/stats/<virtual-host-name>.ips`. When done with all inputs, the `*.ips` files produced are filtered for unique entries (using `sort -u`) and number of lines are counted, resulting in the total number of unique visitors per virtual host name since the beginning of our log file records.
Additionally, a per-month analysis is carried out by splitting the `*.ips` files by the months found in the time stamps and again applying a unique count. The resulting files can be found at `/var/log/old/cache/unique-ips-per-referrer/stats/unique-ips-days-useragents-per-event` and `/var/log/old/cache/unique-ips-per-referrer/stats/unique-ips-days-useragents-per-event-MMM-YYYY` where `MMM` represents the three-letter month name such as `Apr` and `YYYY` stands for the year.
The `unique_ips_per_referrer` script is registered as a weekly cron job in `/etc/cron.weekly` and is fed the special converted log files of Travemünder Woche 2015 and the Bundesliga logs from 2015, as well as all files matching the file name pattern `access_log-*` anywhere under `/var/log/old`. This only matches proper Apache log files with original client IP addresses, not those with ELB IP addresses only (which are named `elb-origin-access_log*` by convention, see above).
The variant `unique_ips_per_referrer_generate_results_only` assumes that the `*.ips` files have already been updated and produces the total and per-month output files.
The variant `unique_ips_per_referrer_generate_month_results_only` produces only the per-month output files, also assuming that the `*.ips` files have already been updated.
The results are published under the link [http://awstats.sapsailing.com/unique-visitors/](http://awstats.sapsailing.com/unique-visitors/) which uses the same credentials as the main AWStats publishing page.
#### `convertELBLogToApacheFormat`
This script was already briefly mentioned above. It is found at `configuration/convertELBLogToApacheFormat` and converts and Amazon Elastic Load Balancer (ELB) log file to our common Apache log file format with leading virtual host name. The virtual host name is expected as the first parameter; all subsequent parameters are treated as file names of ELB log files, either in GZIP format with `.gz` extension or uncompressed. The conversion result is streamed to the standard output and may therefore be redirected into a file.
+2 -1
View File
@@ -19,7 +19,8 @@ I then did a `yum update` and added the following packages:
- goaccess
- postfix (for sending e-mail, e.g., to invite competitors and buoy pingers)
- tigervnc-server
- xdm (to have a rudimentary window manager available for the VNC server)
- WindowMaker
- xterm
Then I created a mount point /home/sailing and copied the following lines from the /etc/fstab file from an existing SL instance:
+6 -4
View File
@@ -67,11 +67,13 @@ First of all, make sure you've looked at http://www.amazon.de/Patterns-Elements-
* Rebuild all projects
4. Run the Race Analysis Suite
* Start the MongoDB
* Start the appropriate Eclipse launch configuration (e.g. 'Sailing Server (Proxy)') You´ll find this in the run dropdown
* Run "Security UI sdm" in the run dropdown
* Run "SailingGWT" in the run dropdown
5. Within the Race Analysis Suite
* Start the appropriate Eclipse launch configuration (e.g. 'Sailing Server (Proxy)') You´ll find this in the debug dropdown
* Run "Security UI sdm" in the debug dropdown
* Run "SailingGWT" in the debug dropdown
5. Import races within the Race Analysis Suite
* Choose "Security UI sdm" in the upper left corner of the "Development Mode" Tab in Eclipse and open "...Login.html" in your browser
* Default Login: user "admin", password "admin"
* Choose "Sailing GWT" in the "Development Mode" Tab and open "...AdminConsole.html..." (It is normal that the first try fails. Reload the page after the first try)
* For TracTrac Events: (Date 27.11.2012) Use Live URI tcp://10.18.22.156:4412, Stored URI tcp://10.18.22.156:4413, JSON URL http://germanmaster.traclive.dk/events/event_20120905_erEuropean/jsonservice.php
* Press List Races